Fixed conflicts after merge with master
|  | @ -18,6 +18,8 @@ config_update_url = http://files.prusa3d.com/wp-content/uploads/repository/Prusa | |||
| name = Creality Ender-3 | ||||
| variants = 0.4 | ||||
| technology = FFF | ||||
| bed_model = ender3_bed.stl | ||||
| bed_texture = ender3.svg | ||||
| default_materials = Creality PLA @ENDER3; Prusament PLA @ENDER3 | ||||
| 
 | ||||
| # All presets starting with asterisk, for example *common*, are intermediate and they will | ||||
|  |  | |||
| Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB | 
|  | @ -22,6 +22,8 @@ name = Original Prusa MINI | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MINI | ||||
| bed_model = mini_bed.stl | ||||
| bed_texture = mini.svg | ||||
| default_materials = Prusament PLA; Prusament PETG @MINI | ||||
| 
 | ||||
| [printer_model:MK3S] | ||||
|  | @ -29,6 +31,8 @@ name = Original Prusa i3 MK3S | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK3 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA; Prusament PETG | ||||
| 
 | ||||
| [printer_model:MK3] | ||||
|  | @ -36,6 +40,8 @@ name = Original Prusa i3 MK3 | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK3 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA; Prusament PETG | ||||
| 
 | ||||
| [printer_model:MK3SMMU2S] | ||||
|  | @ -43,6 +49,8 @@ name = Original Prusa i3 MK3S MMU2S | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK3 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA @MMU2; Prusament PETG @MMU2 | ||||
| 
 | ||||
| [printer_model:MK3MMU2] | ||||
|  | @ -50,6 +58,8 @@ name = Original Prusa i3 MK3 MMU2 | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK3 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA @MMU2; Prusament PETG @MMU2 | ||||
| 
 | ||||
| [printer_model:MK2.5S] | ||||
|  | @ -57,6 +67,8 @@ name = Original Prusa i3 MK2.5S | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK2.5 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA; Prusament PETG | ||||
| 
 | ||||
| [printer_model:MK2.5] | ||||
|  | @ -64,6 +76,8 @@ name = Original Prusa i3 MK2.5 | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK2.5 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA; Prusament PETG | ||||
| 
 | ||||
| [printer_model:MK2.5SMMU2S] | ||||
|  | @ -71,6 +85,8 @@ name = Original Prusa i3 MK2.5S MMU2S | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK2.5 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA @MMU2; Prusament PETG @MMU2 | ||||
| 
 | ||||
| [printer_model:MK2.5MMU2] | ||||
|  | @ -78,6 +94,8 @@ name = Original Prusa i3 MK2.5 MMU2 | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK2.5 | ||||
| bed_model = mk3_bed.stl | ||||
| bed_texture = mk3.svg | ||||
| default_materials = Prusament PLA @MMU2; Prusament PETG @MMU2 | ||||
| 
 | ||||
| [printer_model:MK2S] | ||||
|  | @ -85,6 +103,8 @@ name = Original Prusa i3 MK2S | |||
| variants = 0.4; 0.25; 0.6 | ||||
| technology = FFF | ||||
| family = MK2 | ||||
| bed_model = mk2_bed.stl | ||||
| bed_texture = mk2.svg | ||||
| default_materials = Prusament PLA; Prusament PETG | ||||
| 
 | ||||
| [printer_model:MK2SMM] | ||||
|  | @ -92,6 +112,8 @@ name = Original Prusa i3 MK2S MMU1 | |||
| variants = 0.4; 0.6 | ||||
| technology = FFF | ||||
| family = MK2 | ||||
| bed_model = mk2_bed.stl | ||||
| bed_texture = mk2.svg | ||||
| default_materials = Prusament PLA; Prusament PETG @MMU1 | ||||
| 
 | ||||
| [printer_model:SL1] | ||||
|  | @ -99,6 +121,8 @@ name = Original Prusa SL1 | |||
| variants = default | ||||
| technology = SLA | ||||
| family = SL1 | ||||
| bed_model = sl1_bed.stl | ||||
| bed_texture = sl1.svg | ||||
| default_materials = Prusa Transparent Tough @0.05 | ||||
| 
 | ||||
| # All presets starting with asterisk, for example *common*, are intermediate and they will | ||||
|  |  | |||
| Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB | 
| Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB | 
| Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB | 
| Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB | 
|  | @ -1717,9 +1717,6 @@ namespace Slic3r { | |||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| #if !ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|             Transform3d inv_matrix = volume_matrix_to_object.inverse(); | ||||
| #endif // !ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
| 
 | ||||
|             // splits volume out of imported geometry
 | ||||
| 			TriangleMesh triangle_mesh; | ||||
|  | @ -1739,15 +1736,7 @@ namespace Slic3r { | |||
|                 for (unsigned int v = 0; v < 3; ++v) | ||||
|                 { | ||||
|                     unsigned int tri_id = geometry.triangles[src_start_id + ii + v] * 3; | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|                     facet.vertex[v] = Vec3f(geometry.vertices[tri_id + 0], geometry.vertices[tri_id + 1], geometry.vertices[tri_id + 2]); | ||||
| #else | ||||
|                     Vec3f vertex(geometry.vertices[tri_id + 0], geometry.vertices[tri_id + 1], geometry.vertices[tri_id + 2]); | ||||
|                     facet.vertex[v] = has_transform ? | ||||
|                         // revert the vertices to the original mesh reference system
 | ||||
|                         (inv_matrix * vertex.cast<double>()).cast<float>() : | ||||
|                         vertex; | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -1755,15 +1744,9 @@ namespace Slic3r { | |||
| 			triangle_mesh.repair(); | ||||
| 
 | ||||
| 			ModelVolume* volume = object.add_volume(std::move(triangle_mesh)); | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|             // stores the volume matrix taken from the metadata, if present
 | ||||
|             if (has_transform) | ||||
|                 volume->source.transform = Slic3r::Geometry::Transformation(volume_matrix_to_object); | ||||
| #else | ||||
|             // apply the volume matrix taken from the metadata, if present
 | ||||
|             if (has_transform) | ||||
|                 volume->set_transformation(Slic3r::Geometry::Transformation(volume_matrix_to_object)); | ||||
| #endif //ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|             volume->calculate_convex_hull(); | ||||
| 
 | ||||
|             // apply the remaining volume's metadata
 | ||||
|  | @ -2567,11 +2550,7 @@ namespace Slic3r { | |||
| 
 | ||||
|                             // stores volume's local matrix
 | ||||
|                             stream << "   <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MATRIX_KEY << "\" " << VALUE_ATTR << "=\""; | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|                             Transform3d matrix = volume->get_matrix() * volume->source.transform.get_matrix(); | ||||
| #else | ||||
|                             const Transform3d& matrix = volume->get_matrix(); | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|                             for (int r = 0; r < 4; ++r) | ||||
|                             { | ||||
|                                 for (int c = 0; c < 4; ++c) | ||||
|  |  | |||
|  | @ -585,36 +585,20 @@ void AMFParserContext::endElement(const char * /* name */) | |||
|         stl_allocate(&stl); | ||||
| 
 | ||||
|         bool has_transform = ! m_volume_transform.isApprox(Transform3d::Identity(), 1e-10); | ||||
| #if !ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|         Transform3d inv_matrix = m_volume_transform.inverse(); | ||||
| #endif // !ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|         for (size_t i = 0; i < m_volume_facets.size();) { | ||||
|             stl_facet &facet = stl.facet_start[i/3]; | ||||
|             for (unsigned int v = 0; v < 3; ++v) | ||||
|             { | ||||
|                 unsigned int tri_id = m_volume_facets[i++] * 3; | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|                 facet.vertex[v] = Vec3f(m_object_vertices[tri_id + 0], m_object_vertices[tri_id + 1], m_object_vertices[tri_id + 2]); | ||||
| #else | ||||
|                 Vec3f vertex(m_object_vertices[tri_id + 0], m_object_vertices[tri_id + 1], m_object_vertices[tri_id + 2]); | ||||
|                 facet.vertex[v] = has_transform ? | ||||
|                     // revert the vertices to the original mesh reference system
 | ||||
|                     (inv_matrix * vertex.cast<double>()).cast<float>() : | ||||
|                     vertex; | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|             } | ||||
|         }         | ||||
|         stl_get_size(&stl); | ||||
|         mesh.repair(); | ||||
| 		m_volume->set_mesh(std::move(mesh)); | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|         // stores the volume matrix taken from the metadata, if present
 | ||||
|         if (has_transform) | ||||
|             m_volume->source.transform = Slic3r::Geometry::Transformation(m_volume_transform); | ||||
| #else | ||||
|         if (has_transform) | ||||
|             m_volume->set_transformation(m_volume_transform); | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|         if (m_volume->source.input_file.empty() && (m_volume->type() == ModelVolumeType::MODEL_PART)) | ||||
|         { | ||||
|             m_volume->source.object_idx = (int)m_model.objects.size() - 1; | ||||
|  | @ -1163,11 +1147,7 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) | |||
|                 stream << "        <metadata type=\"slic3r.modifier\">1</metadata>\n"; | ||||
|             stream << "        <metadata type=\"slic3r.volume_type\">" << ModelVolume::type_to_string(volume->type()) << "</metadata>\n"; | ||||
|             stream << "        <metadata type=\"slic3r.matrix\">"; | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|             const Transform3d& matrix = volume->get_matrix() * volume->source.transform.get_matrix(); | ||||
| #else | ||||
|             const Transform3d& matrix = volume->get_matrix(); | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|             stream << std::setprecision(std::numeric_limits<double>::max_digits10); | ||||
|             for (int r = 0; r < 4; ++r) | ||||
|             { | ||||
|  |  | |||
|  | @ -1738,7 +1738,7 @@ namespace ProcessLayer | |||
|          | ||||
|         if (custom_gcode != nullptr) { | ||||
| 			// Extruder switches are processed by LayerTools, they should be filtered out.
 | ||||
| 			assert(custom_gcode->gcode != ExtruderChangeCode); | ||||
| 			assert(custom_gcode->gcode != ToolChangeCode); | ||||
| 
 | ||||
|             const std::string &custom_code = custom_gcode->gcode; | ||||
| 		    std::string pause_print_msg; | ||||
|  |  | |||
|  | @ -478,7 +478,7 @@ void ToolOrdering::assign_custom_gcodes(const Print &print) | |||
| 		for (unsigned int i : lt.extruders) | ||||
| 			extruder_printing_above[i] = true; | ||||
| 		// Skip all custom G-codes above this layer and skip all extruder switches.
 | ||||
| 		for (; custom_gcode_it != custom_gcode_per_print_z.gcodes.rend() && (custom_gcode_it->print_z > lt.print_z + EPSILON || custom_gcode_it->gcode == ExtruderChangeCode); ++ custom_gcode_it); | ||||
| 		for (; custom_gcode_it != custom_gcode_per_print_z.gcodes.rend() && (custom_gcode_it->print_z > lt.print_z + EPSILON || custom_gcode_it->gcode == ToolChangeCode); ++ custom_gcode_it); | ||||
| 		if (custom_gcode_it == custom_gcode_per_print_z.gcodes.rend()) | ||||
| 			// Custom G-codes were processed.
 | ||||
| 			break; | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ namespace Slic3r { | |||
| // Additional Codes which can be set by user using DoubleSlider
 | ||||
| static constexpr char ColorChangeCode[]     = "M600"; | ||||
| static constexpr char PausePrintCode[]      = "M601"; | ||||
| static constexpr char ExtruderChangeCode[]  = "tool_change"; | ||||
| static constexpr char ToolChangeCode[]  = "tool_change"; | ||||
| 
 | ||||
| class GCodeWriter { | ||||
| public: | ||||
|  |  | |||
|  | @ -1847,7 +1847,7 @@ std::vector<std::pair<double, unsigned int>> custom_tool_changes(const Model &mo | |||
| { | ||||
|     std::vector<std::pair<double, unsigned int>> custom_tool_changes; | ||||
|     for (const Model::CustomGCode &custom_gcode : model.custom_gcode_per_print_z.gcodes) | ||||
|         if (custom_gcode.gcode == ExtruderChangeCode) { | ||||
|         if (custom_gcode.gcode == ToolChangeCode) { | ||||
|             // If extruder count in PrinterSettings was changed, use default (0) extruder for extruders, more than num_extruders
 | ||||
|             custom_tool_changes.emplace_back(custom_gcode.print_z, static_cast<unsigned int>(custom_gcode.extruder > num_extruders ? 1 : custom_gcode.extruder)); | ||||
|         } | ||||
|  |  | |||
|  | @ -399,13 +399,9 @@ public: | |||
|         int object_idx{ -1 }; | ||||
|         int volume_idx{ -1 }; | ||||
|         Vec3d mesh_offset{ Vec3d::Zero() }; | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|         Geometry::Transformation transform; | ||||
| 
 | ||||
|         template<class Archive> void serialize(Archive& ar) { ar(input_file, object_idx, volume_idx, mesh_offset, transform); } | ||||
| #else | ||||
|         template<class Archive> void serialize(Archive& ar) { ar(input_file, object_idx, volume_idx, mesh_offset); } | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|     }; | ||||
|     Source              source; | ||||
| 
 | ||||
|  | @ -767,8 +763,9 @@ public: | |||
|          | ||||
|         double      print_z; | ||||
|         std::string gcode; | ||||
|         int         extruder;   // 0    - "gcode" will be applied for whole print
 | ||||
|                                 // else - "gcode" will be applied only for "extruder" print
 | ||||
|         int         extruder;   // Informative value for ColorChangeCode and ToolChangeCode
 | ||||
|                                 // "gcode" == ColorChangeCode   => M600 will be applied for "extruder" extruder
 | ||||
|                                 // "gcode" == ToolChangeCode    => for whole print tool will be switched to "extruder" extruder
 | ||||
|         std::string color;      // if gcode is equal to PausePrintCode, 
 | ||||
|                                 // this field is used for save a short message shown on Printer display 
 | ||||
|     }; | ||||
|  |  | |||
|  | @ -493,18 +493,18 @@ static bool layer_height_ranges_equal(const t_layer_config_ranges &lr1, const t_ | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| // Returns true if va == vb when all CustomGCode items that are not ExtruderChangeCode are ignored.
 | ||||
| // Returns true if va == vb when all CustomGCode items that are not ToolChangeCode are ignored.
 | ||||
| static bool custom_per_printz_gcodes_tool_changes_differ(const std::vector<Model::CustomGCode> &va, const std::vector<Model::CustomGCode> &vb) | ||||
| { | ||||
| 	auto it_a = va.begin(); | ||||
| 	auto it_b = vb.begin(); | ||||
| 	while (it_a != va.end() && it_b != vb.end()) { | ||||
| 		if (it_a != va.end() && it_a->gcode != ExtruderChangeCode) { | ||||
| 		if (it_a != va.end() && it_a->gcode != ToolChangeCode) { | ||||
| 			// Skip any CustomGCode items, which are not tool changes.
 | ||||
| 			++ it_a; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (it_b != vb.end() && it_b->gcode != ExtruderChangeCode) { | ||||
| 		if (it_b != vb.end() && it_b->gcode != ToolChangeCode) { | ||||
| 			// Skip any CustomGCode items, which are not tool changes.
 | ||||
| 			++ it_b; | ||||
| 			continue; | ||||
|  | @ -512,8 +512,8 @@ static bool custom_per_printz_gcodes_tool_changes_differ(const std::vector<Model | |||
| 		if (it_a == va.end() || it_b == vb.end()) | ||||
| 			// va or vb contains more Tool Changes than the other.
 | ||||
| 			return true; | ||||
| 		assert(it_a->gcode == ExtruderChangeCode); | ||||
| 		assert(it_b->gcode == ExtruderChangeCode); | ||||
| 		assert(it_a->gcode == ToolChangeCode); | ||||
| 		assert(it_b->gcode == ToolChangeCode); | ||||
| 		if (*it_a != *it_b) | ||||
| 			// The two Tool Changes differ.
 | ||||
| 			return true; | ||||
|  |  | |||
|  | @ -300,26 +300,14 @@ std::vector<double> layer_height_profile_adaptive(const SlicingParameters& slici | |||
|         layer_height_profile.push_back(print_z); | ||||
|         layer_height_profile.push_back(height); | ||||
|         print_z += height; | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         layer_height_profile.push_back(print_z); | ||||
|         layer_height_profile.push_back(height); | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     double z_gap = slicing_params.object_print_z_height() - layer_height_profile[layer_height_profile.size() - 2]; | ||||
|     if (z_gap > 0.0) | ||||
|     { | ||||
|         layer_height_profile.push_back(slicing_params.object_print_z_height()); | ||||
|         layer_height_profile.push_back(clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, z_gap)); | ||||
|     } | ||||
| #else | ||||
|     double last = std::max(slicing_params.first_object_layer_height, layer_height_profile[layer_height_profile.size() - 2]); | ||||
|     layer_height_profile.push_back(last); | ||||
|     layer_height_profile.push_back(slicing_params.first_object_layer_height); | ||||
|     layer_height_profile.push_back(slicing_params.object_print_z_height()); | ||||
|     layer_height_profile.push_back(slicing_params.first_object_layer_height); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|     return layer_height_profile; | ||||
| } | ||||
|  |  | |||
|  | @ -41,24 +41,6 @@ | |||
| #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) | ||||
| #define ENABLE_THUMBNAIL_GENERATOR_DEBUG (0 && ENABLE_THUMBNAIL_GENERATOR) | ||||
| 
 | ||||
| // Enable adaptive layer height profile
 | ||||
| #define ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE (1 && ENABLE_2_2_0_ALPHA1) | ||||
| 
 | ||||
| // Enable grayed variant for gizmos icons in non activable state
 | ||||
| #define ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE (1 && ENABLE_2_2_0_ALPHA1) | ||||
| 
 | ||||
| // Enable fix for view toolbar background not showing up on Mac with dark mode
 | ||||
| #define ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX (1 && ENABLE_2_2_0_ALPHA1) | ||||
| 
 | ||||
| // Enable selection for missing files in reload from disk command
 | ||||
| #define ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION (1 && ENABLE_2_2_0_ALPHA1) | ||||
| 
 | ||||
| // Enable closing 3Dconnextion imgui settings dialog by clicking on [X] and [Close] buttons
 | ||||
| #define ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG (1 && ENABLE_2_2_0_ALPHA1) | ||||
| 
 | ||||
| // Enable not applying volume transformation during 3mf and amf loading, but keeping it as a ModelVolume member
 | ||||
| #define ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE (1 && ENABLE_2_2_0_ALPHA1) | ||||
| 
 | ||||
| 
 | ||||
| //==================
 | ||||
| // 2.2.0.beta1 techs
 | ||||
|  |  | |||
|  | @ -189,8 +189,6 @@ void Bed3D::Axes::render_axis(double length) const | |||
| 
 | ||||
| Bed3D::Bed3D() | ||||
|     : m_type(Custom) | ||||
|     , m_custom_texture("") | ||||
|     , m_custom_model("") | ||||
|     , m_vbo_id(0) | ||||
|     , m_scale_factor(1.0f) | ||||
| { | ||||
|  | @ -198,31 +196,31 @@ Bed3D::Bed3D() | |||
| 
 | ||||
| bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) | ||||
| { | ||||
|     EType new_type = detect_type(shape); | ||||
|     auto check_texture = [](const std::string& texture) { | ||||
|         return !texture.empty() && (boost::algorithm::iends_with(texture, ".png") || boost::algorithm::iends_with(texture, ".svg")) && boost::filesystem::exists(texture); | ||||
|     }; | ||||
| 
 | ||||
|     // check that the passed custom texture filename is valid
 | ||||
|     std::string cst_texture(custom_texture); | ||||
|     if (!cst_texture.empty()) | ||||
|     { | ||||
|         if ((!boost::algorithm::iends_with(custom_texture, ".png") && !boost::algorithm::iends_with(custom_texture, ".svg")) || !boost::filesystem::exists(custom_texture)) | ||||
|             cst_texture = ""; | ||||
|     } | ||||
|     auto check_model = [](const std::string& model) { | ||||
|         return !model.empty() && boost::algorithm::iends_with(model, ".stl") && boost::filesystem::exists(model); | ||||
|     }; | ||||
| 
 | ||||
|     // check that the passed custom texture filename is valid
 | ||||
|     std::string cst_model(custom_model); | ||||
|     if (!cst_model.empty()) | ||||
|     { | ||||
|         if (!boost::algorithm::iends_with(custom_model, ".stl") || !boost::filesystem::exists(custom_model)) | ||||
|             cst_model = ""; | ||||
|     } | ||||
|     auto [new_type, system_model, system_texture] = detect_type(shape); | ||||
| 
 | ||||
|     if ((m_shape == shape) && (m_type == new_type) && (m_custom_texture == cst_texture) && (m_custom_model == cst_model)) | ||||
|     std::string texture_filename = custom_texture.empty() ? system_texture : custom_texture; | ||||
|     if (!check_texture(texture_filename)) | ||||
|         texture_filename.clear(); | ||||
| 
 | ||||
|     std::string model_filename = custom_model.empty() ? system_model : custom_model; | ||||
|     if (!check_model(model_filename)) | ||||
|         model_filename.clear(); | ||||
| 
 | ||||
|     if ((m_shape == shape) && (m_type == new_type) && (m_texture_filename == texture_filename) && (m_model_filename == model_filename)) | ||||
|         // No change, no need to update the UI.
 | ||||
|         return false; | ||||
| 
 | ||||
|     m_shape = shape; | ||||
|     m_custom_texture = cst_texture; | ||||
|     m_custom_model = cst_model; | ||||
|     m_texture_filename = texture_filename; | ||||
|     m_model_filename = model_filename; | ||||
|     m_type = new_type; | ||||
| 
 | ||||
|     calc_bounding_boxes(); | ||||
|  | @ -244,7 +242,7 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c | |||
|     m_texture.reset(); | ||||
|     m_model.reset(); | ||||
| 
 | ||||
|     // Set the origin and size for painting of the coordinate system axes.
 | ||||
|     // Set the origin and size for rendering the coordinate system axes.
 | ||||
|     m_axes.origin = Vec3d(0.0, 0.0, (double)GROUND_Z); | ||||
|     m_axes.length = 0.1 * m_bounding_box.max_size() * Vec3d::Ones(); | ||||
| 
 | ||||
|  | @ -278,19 +276,11 @@ void Bed3D::render(GLCanvas3D& canvas, float theta, float scale_factor, bool sho | |||
|     switch (m_type) | ||||
|     { | ||||
| #if ENABLE_6DOF_CAMERA | ||||
|     case MK2: { render_prusa(canvas, "mk2", bottom); break; } | ||||
|     case MK3: { render_prusa(canvas, "mk3", bottom); break; } | ||||
|     case SL1: { render_prusa(canvas, "sl1", bottom); break; } | ||||
|     case MINI: { render_prusa(canvas, "mini", bottom); break; } | ||||
|     case ENDER3: { render_prusa(canvas, "ender3", bottom); break; } | ||||
|     case System: { render_system(canvas, bottom); break; } | ||||
|     default: | ||||
|     case Custom: { render_custom(canvas, bottom); break; } | ||||
| #else | ||||
|     case MK2: { render_prusa(canvas, "mk2", theta > 90.0f); break; } | ||||
|     case MK3: { render_prusa(canvas, "mk3", theta > 90.0f); break; } | ||||
|     case SL1: { render_prusa(canvas, "sl1", theta > 90.0f); break; } | ||||
|     case MINI: { render_prusa(canvas, "mini", theta > 90.0f); break; } | ||||
|     case ENDER3: { render_prusa(canvas, "ender3", theta > 90.0f); break; } | ||||
|     case System: { render_system(canvas, theta > 90.0f); break; } | ||||
|     default: | ||||
|     case Custom: { render_custom(canvas, theta > 90.0f); break; } | ||||
| #endif // ENABLE_6DOF_CAMERA
 | ||||
|  | @ -373,10 +363,8 @@ static std::string system_print_bed_texture(const Preset &preset) | |||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| Bed3D::EType Bed3D::detect_type(const Pointfs& shape) const | ||||
| std::tuple<Bed3D::EType, std::string, std::string> Bed3D::detect_type(const Pointfs& shape) const | ||||
| { | ||||
|     EType type = Custom; | ||||
| 
 | ||||
|     auto bundle = wxGetApp().preset_bundle; | ||||
|     if (bundle != nullptr) | ||||
|     { | ||||
|  | @ -385,39 +373,12 @@ Bed3D::EType Bed3D::detect_type(const Pointfs& shape) const | |||
|         { | ||||
|             if (curr->config.has("bed_shape")) | ||||
|             { | ||||
|                 if (curr->vendor != nullptr) | ||||
|                 if (shape == dynamic_cast<const ConfigOptionPoints*>(curr->config.option("bed_shape"))->values) | ||||
|                 { | ||||
|                     if ((curr->vendor->name == "Prusa Research") && (shape == dynamic_cast<const ConfigOptionPoints*>(curr->config.option("bed_shape"))->values)) | ||||
|                     { | ||||
|                         if (boost::contains(curr->name, "SL1")) | ||||
|                         { | ||||
|                             type = SL1; | ||||
|                             break; | ||||
|                         } | ||||
|                         else if (boost::contains(curr->name, "MK3") || boost::contains(curr->name, "MK2.5")) | ||||
|                         { | ||||
|                             type = MK3; | ||||
|                             break; | ||||
|                         } | ||||
|                         else if (boost::contains(curr->name, "MK2")) | ||||
|                         { | ||||
|                             type = MK2; | ||||
|                             break; | ||||
|                         } | ||||
|                         else if (boost::contains(curr->name, "MINI")) | ||||
|                         { | ||||
|                             type = MINI; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     else if ((curr->vendor->name == "Creality") && (shape == dynamic_cast<const ConfigOptionPoints*>(curr->config.option("bed_shape"))->values)) | ||||
|                     { | ||||
|                         if (boost::contains(curr->name, "ENDER-3")) | ||||
|                         { | ||||
|                             type = ENDER3; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     std::string model_filename = system_print_bed_model(*curr); | ||||
|                     std::string texture_filename = system_print_bed_texture(*curr); | ||||
|                     if (!model_filename.empty() && !texture_filename.empty()) | ||||
|                         return std::make_tuple(System, model_filename, texture_filename); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -425,7 +386,7 @@ Bed3D::EType Bed3D::detect_type(const Pointfs& shape) const | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return type; | ||||
|     return std::make_tuple(Custom, "", ""); | ||||
| } | ||||
| 
 | ||||
| void Bed3D::render_axes() const | ||||
|  | @ -434,35 +395,35 @@ void Bed3D::render_axes() const | |||
|         m_axes.render(); | ||||
| } | ||||
| 
 | ||||
| void Bed3D::render_prusa(GLCanvas3D& canvas, const std::string& key, bool bottom) const | ||||
| void Bed3D::render_system(GLCanvas3D& canvas, bool bottom) const | ||||
| { | ||||
|     if (!bottom) | ||||
|         render_model(m_custom_model.empty() ? resources_dir() + "/models/" + key + "_bed.stl" : m_custom_model); | ||||
|         render_model(); | ||||
| 
 | ||||
|     render_texture(m_custom_texture.empty() ? resources_dir() + "/icons/bed/" + key + ".svg" : m_custom_texture, bottom, canvas); | ||||
|     render_texture(bottom, canvas); | ||||
| } | ||||
| 
 | ||||
| void Bed3D::render_texture(const std::string& filename, bool bottom, GLCanvas3D& canvas) const | ||||
| void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const | ||||
| { | ||||
|     if (filename.empty()) | ||||
|     if (m_texture_filename.empty()) | ||||
|     { | ||||
|         m_texture.reset(); | ||||
|         render_default(bottom); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if ((m_texture.get_id() == 0) || (m_texture.get_source() != filename)) | ||||
|     if ((m_texture.get_id() == 0) || (m_texture.get_source() != m_texture_filename)) | ||||
|     { | ||||
|         m_texture.reset(); | ||||
| 
 | ||||
|         if (boost::algorithm::iends_with(filename, ".svg")) | ||||
|         if (boost::algorithm::iends_with(m_texture_filename, ".svg")) | ||||
|         { | ||||
|             // use higher resolution images if graphic card and opengl version allow
 | ||||
|             GLint max_tex_size = GLCanvas3DManager::get_gl_info().get_max_tex_size(); | ||||
|             if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != filename)) | ||||
|             if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) | ||||
|             { | ||||
|                 // generate a temporary lower resolution texture to show while no main texture levels have been compressed
 | ||||
|                 if (!m_temp_texture.load_from_svg_file(filename, false, false, false, max_tex_size / 8)) | ||||
|                 if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) | ||||
|                 { | ||||
|                     render_default(bottom); | ||||
|                     return; | ||||
|  | @ -471,18 +432,18 @@ void Bed3D::render_texture(const std::string& filename, bool bottom, GLCanvas3D& | |||
|             } | ||||
| 
 | ||||
|             // starts generating the main texture, compression will run asynchronously
 | ||||
|             if (!m_texture.load_from_svg_file(filename, true, true, true, max_tex_size)) | ||||
|             if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) | ||||
|             { | ||||
|                 render_default(bottom); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         else if (boost::algorithm::iends_with(filename, ".png")) | ||||
|         else if (boost::algorithm::iends_with(m_texture_filename, ".png")) | ||||
|         { | ||||
|             // generate a temporary lower resolution texture to show while no main texture levels have been compressed
 | ||||
|             if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != filename)) | ||||
|             if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) | ||||
|             { | ||||
|                 if (!m_temp_texture.load_from_file(filename, false, GLTexture::None, false)) | ||||
|                 if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) | ||||
|                 { | ||||
|                     render_default(bottom); | ||||
|                     return; | ||||
|  | @ -491,7 +452,7 @@ void Bed3D::render_texture(const std::string& filename, bool bottom, GLCanvas3D& | |||
|             } | ||||
| 
 | ||||
|             // starts generating the main texture, compression will run asynchronously
 | ||||
|             if (!m_texture.load_from_file(filename, true, GLTexture::MultiThreaded, true)) | ||||
|             if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) | ||||
|             { | ||||
|                 render_default(bottom); | ||||
|                 return; | ||||
|  | @ -590,12 +551,12 @@ void Bed3D::render_texture(const std::string& filename, bool bottom, GLCanvas3D& | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void Bed3D::render_model(const std::string& filename) const | ||||
| void Bed3D::render_model() const | ||||
| { | ||||
|     if (filename.empty()) | ||||
|     if (m_model_filename.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     if ((m_model.get_filename() != filename) && m_model.init_from_file(filename)) | ||||
|     if ((m_model.get_filename() != m_model_filename) && m_model.init_from_file(m_model_filename)) | ||||
|     { | ||||
|         // move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
 | ||||
|         Vec3d shift = m_bounding_box.center(); | ||||
|  | @ -616,16 +577,16 @@ void Bed3D::render_model(const std::string& filename) const | |||
| 
 | ||||
| void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom) const | ||||
| { | ||||
|     if (m_custom_texture.empty() && m_custom_model.empty()) | ||||
|     if (m_texture_filename.empty() && m_model_filename.empty()) | ||||
|     { | ||||
|         render_default(bottom); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (!bottom) | ||||
|         render_model(m_custom_model); | ||||
|         render_model(); | ||||
| 
 | ||||
|     render_texture(m_custom_texture, bottom, canvas); | ||||
|     render_texture(bottom, canvas); | ||||
| } | ||||
| 
 | ||||
| void Bed3D::render_default(bool bottom) const | ||||
|  |  | |||
|  | @ -5,6 +5,8 @@ | |||
| #include "3DScene.hpp" | ||||
| #include "GLShader.hpp" | ||||
| 
 | ||||
| #include <tuple> | ||||
| 
 | ||||
| class GLUquadric; | ||||
| typedef class GLUquadric GLUquadricObj; | ||||
| 
 | ||||
|  | @ -64,11 +66,7 @@ class Bed3D | |||
| public: | ||||
|     enum EType : unsigned char | ||||
|     { | ||||
|         MK2, | ||||
|         MK3, | ||||
|         SL1, | ||||
|         MINI, | ||||
|         ENDER3, | ||||
|         System, | ||||
|         Custom, | ||||
|         Num_Types | ||||
|     }; | ||||
|  | @ -76,19 +74,19 @@ public: | |||
| private: | ||||
|     EType m_type; | ||||
|     Pointfs m_shape; | ||||
|     std::string m_custom_texture; | ||||
|     std::string m_custom_model; | ||||
|     std::string m_texture_filename; | ||||
|     std::string m_model_filename; | ||||
|     mutable BoundingBoxf3 m_bounding_box; | ||||
|     mutable BoundingBoxf3 m_extended_bounding_box; | ||||
|     Polygon m_polygon; | ||||
|     GeometryBuffer m_triangles; | ||||
|     GeometryBuffer m_gridlines; | ||||
|     mutable GLTexture m_texture; | ||||
|     mutable GLBed m_model; | ||||
|     // temporary texture shown until the main texture has still no levels compressed
 | ||||
|     mutable GLTexture m_temp_texture; | ||||
|     mutable Shader m_shader; | ||||
|     mutable unsigned int m_vbo_id; | ||||
|     mutable GLBed m_model; | ||||
|     Axes m_axes; | ||||
| 
 | ||||
|     mutable float m_scale_factor; | ||||
|  | @ -99,7 +97,6 @@ public: | |||
| 
 | ||||
|     EType get_type() const { return m_type; } | ||||
| 
 | ||||
|     bool is_prusa() const { return (m_type == MK2) || (m_type == MK3) || (m_type == SL1); } | ||||
|     bool is_custom() const { return m_type == Custom; } | ||||
| 
 | ||||
|     const Pointfs& get_shape() const { return m_shape; } | ||||
|  | @ -120,11 +117,11 @@ private: | |||
|     void calc_bounding_boxes() const; | ||||
|     void calc_triangles(const ExPolygon& poly); | ||||
|     void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); | ||||
|     EType detect_type(const Pointfs& shape) const; | ||||
|     std::tuple<EType, std::string, std::string> detect_type(const Pointfs& shape) const; | ||||
|     void render_axes() const; | ||||
|     void render_prusa(GLCanvas3D& canvas, const std::string& key, bool bottom) const; | ||||
|     void render_texture(const std::string& filename, bool bottom, GLCanvas3D& canvas) const; | ||||
|     void render_model(const std::string& filename) const; | ||||
|     void render_system(GLCanvas3D& canvas, bool bottom) const; | ||||
|     void render_texture(bool bottom, GLCanvas3D& canvas) const; | ||||
|     void render_model() const; | ||||
|     void render_custom(GLCanvas3D& canvas, bool bottom) const; | ||||
|     void render_default(bool bottom) const; | ||||
|     void reset(); | ||||
|  |  | |||
|  | @ -132,9 +132,7 @@ GLCanvas3D::LayersEditing::LayersEditing() | |||
|     , m_object_max_z(0.f) | ||||
|     , m_slicing_parameters(nullptr) | ||||
|     , m_layer_height_profile_modified(false) | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     , m_adaptive_quality(0.5f) | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     , state(Unknown) | ||||
|     , band_width(2.0f) | ||||
|     , strength(0.005f) | ||||
|  | @ -155,9 +153,6 @@ GLCanvas3D::LayersEditing::~LayersEditing() | |||
| } | ||||
| 
 | ||||
| const float GLCanvas3D::LayersEditing::THICKNESS_BAR_WIDTH = 70.0f; | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| const float GLCanvas3D::LayersEditing::THICKNESS_RESET_BUTTON_HEIGHT = 22.0f; | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename) | ||||
| { | ||||
|  | @ -224,7 +219,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const | |||
|     if (!m_enabled) | ||||
|         return; | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f); | ||||
| 
 | ||||
|     const Size& cnv_size = canvas.get_canvas_size(); | ||||
|  | @ -319,13 +313,6 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const | |||
|     imgui.end(); | ||||
| 
 | ||||
|     const Rect& bar_rect = get_bar_rect_viewport(canvas); | ||||
| #else | ||||
|     const Rect& bar_rect = get_bar_rect_viewport(canvas); | ||||
|     const Rect& reset_rect = get_reset_rect_viewport(canvas); | ||||
| 
 | ||||
|     _render_tooltip_texture(canvas, bar_rect, reset_rect); | ||||
|     _render_reset_texture(reset_rect); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     render_active_object_annotations(canvas, bar_rect); | ||||
|     render_profile(bar_rect); | ||||
| } | ||||
|  | @ -352,38 +339,15 @@ bool GLCanvas3D::LayersEditing::bar_rect_contains(const GLCanvas3D& canvas, floa | |||
|     return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom()); | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| bool GLCanvas3D::LayersEditing::reset_rect_contains(const GLCanvas3D& canvas, float x, float y) | ||||
| { | ||||
|     const Rect& rect = get_reset_rect_screen(canvas); | ||||
|     return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom()); | ||||
| } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas) | ||||
| { | ||||
|     const Size& cnv_size = canvas.get_canvas_size(); | ||||
|     float w = (float)cnv_size.get_width(); | ||||
|     float h = (float)cnv_size.get_height(); | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     return Rect(w - thickness_bar_width(canvas), 0.0f, w, h); | ||||
| #else | ||||
|     return Rect(w - thickness_bar_width(canvas), 0.0f, w, h - reset_button_height(canvas)); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas) | ||||
| { | ||||
|     const Size& cnv_size = canvas.get_canvas_size(); | ||||
|     float w = (float)cnv_size.get_width(); | ||||
|     float h = (float)cnv_size.get_height(); | ||||
| 
 | ||||
|     return Rect(w - thickness_bar_width(canvas), h - reset_button_height(canvas), w, h); | ||||
| } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) | ||||
| { | ||||
|     const Size& cnv_size = canvas.get_canvas_size(); | ||||
|  | @ -392,26 +356,9 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas) | |||
| 
 | ||||
|     float inv_zoom = (float)canvas.get_camera().get_inv_zoom(); | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); | ||||
| #else | ||||
|     return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas) | ||||
| { | ||||
|     const Size& cnv_size = canvas.get_canvas_size(); | ||||
|     float half_w = 0.5f * (float)cnv_size.get_width(); | ||||
|     float half_h = 0.5f * (float)cnv_size.get_height(); | ||||
| 
 | ||||
|     float inv_zoom = (float)canvas.get_camera().get_inv_zoom(); | ||||
| 
 | ||||
|     return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); | ||||
| } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| bool GLCanvas3D::LayersEditing::is_initialized() const | ||||
| { | ||||
|     return m_shader.is_initialized(); | ||||
|  | @ -446,53 +393,6 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con | |||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const | ||||
| { | ||||
|     // TODO: do this with ImGui
 | ||||
| 
 | ||||
|     if (m_tooltip_texture.get_id() == 0) | ||||
|     { | ||||
|         std::string filename = resources_dir() + "/icons/variable_layer_height_tooltip.png"; | ||||
|         if (!m_tooltip_texture.load_from_file(filename, false, GLTexture::SingleThreaded, false)) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_RETINA_GL | ||||
|     const float scale = canvas.get_canvas_size().get_scale_factor(); | ||||
| #else | ||||
|     const float scale = canvas.get_wxglcanvas()->GetContentScaleFactor(); | ||||
| #endif | ||||
|     const float width = (float)m_tooltip_texture.get_width() * scale; | ||||
|     const float height = (float)m_tooltip_texture.get_height() * scale; | ||||
| 
 | ||||
|     float inv_zoom = (float)canvas.get_camera().get_inv_zoom(); | ||||
|     float gap = 10.0f * inv_zoom; | ||||
| 
 | ||||
|     float bar_left = bar_rect.get_left(); | ||||
|     float reset_bottom = reset_rect.get_bottom(); | ||||
| 
 | ||||
|     float l = bar_left - width * inv_zoom - gap; | ||||
|     float r = bar_left - gap; | ||||
|     float t = reset_bottom + height * inv_zoom + gap; | ||||
|     float b = reset_bottom + gap; | ||||
| 
 | ||||
|     GLTexture::render_texture(m_tooltip_texture.get_id(), l, r, b, t); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::LayersEditing::_render_reset_texture(const Rect& reset_rect) const | ||||
| { | ||||
|     if (m_reset_texture.get_id() == 0) | ||||
|     { | ||||
|         std::string filename = resources_dir() + "/icons/variable_layer_height_reset.png"; | ||||
|         if (!m_reset_texture.load_from_file(filename, false, GLTexture::SingleThreaded, false)) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     GLTexture::render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); | ||||
| } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const | ||||
| { | ||||
|     m_shader.start_using(); | ||||
|  | @ -641,7 +541,6 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) | |||
|     canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor) | ||||
| { | ||||
|     this->update_slicing_parameters(); | ||||
|  | @ -659,7 +558,6 @@ void GLCanvas3D::LayersEditing::smooth_layer_height_profile(GLCanvas3D& canvas, | |||
|     m_layers_texture.valid = false; | ||||
|     canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); | ||||
| } | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| void GLCanvas3D::LayersEditing::generate_layer_height_texture() | ||||
| { | ||||
|  | @ -722,19 +620,6 @@ float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D &canvas) | |||
|          * THICKNESS_BAR_WIDTH; | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| float GLCanvas3D::LayersEditing::reset_button_height(const GLCanvas3D &canvas) | ||||
| { | ||||
|     return | ||||
| #if ENABLE_RETINA_GL | ||||
|         canvas.get_canvas_size().get_scale_factor() | ||||
| #else | ||||
|         canvas.get_wxglcanvas()->GetContentScaleFactor() | ||||
| #endif | ||||
|          * THICKNESS_RESET_BUTTON_HEIGHT; | ||||
| } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| 
 | ||||
| const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX); | ||||
| const Vec3d GLCanvas3D::Mouse::Drag::Invalid_3D_Point(DBL_MAX, DBL_MAX, DBL_MAX); | ||||
|  | @ -1344,9 +1229,6 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent); | ||||
| #endif // !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent); | ||||
|  | @ -1370,11 +1252,9 @@ wxDEFINE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); | |||
| wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| #if ENABLE_THUMBNAIL_GENERATOR | ||||
| const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25; | ||||
|  | @ -1516,10 +1396,6 @@ bool GLCanvas3D::init() | |||
|     if (m_selection.is_enabled() && !m_selection.init()) | ||||
|         return false; | ||||
| 
 | ||||
| #if !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     post_event(SimpleEvent(EVT_GLCANVAS_INIT)); | ||||
| #endif // !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     m_initialized = true; | ||||
| 
 | ||||
|     return true; | ||||
|  | @ -1676,7 +1552,6 @@ bool GLCanvas3D::is_layers_editing_allowed() const | |||
|     return m_layers_editing.is_allowed(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| void GLCanvas3D::reset_layer_height_profile() | ||||
| { | ||||
|     wxGetApp().plater()->take_snapshot(_(L("Variable layer height - Reset"))); | ||||
|  | @ -1700,7 +1575,6 @@ void GLCanvas3D::smooth_layer_height_profile(const HeightProfileSmoothingParams& | |||
|     m_layers_editing.state = LayersEditing::Completed; | ||||
|     m_dirty = true; | ||||
| } | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| bool GLCanvas3D::is_reload_delayed() const | ||||
| { | ||||
|  | @ -1934,11 +1808,7 @@ void GLCanvas3D::render() | |||
|     m_camera.debug_render(); | ||||
| #endif // ENABLE_CAMERA_STATISTICS
 | ||||
| 
 | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog(*this); | ||||
| #else | ||||
|     wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
|     wxGetApp().imgui()->render(); | ||||
| 
 | ||||
|  | @ -3124,20 +2994,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             m_layers_editing.state = LayersEditing::Editing; | ||||
|             _perform_layer_editing_action(&evt); | ||||
|         } | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         else if ((layer_editing_object_idx != -1) && m_layers_editing.reset_rect_contains(*this, pos(0), pos(1))) | ||||
|         { | ||||
|             if (evt.LeftDown()) | ||||
|             { | ||||
|                 // A volume is selected and the mouse is inside the reset button. Reset the ModelObject's layer height profile.
 | ||||
| 				m_layers_editing.reset_layer_height_profile(*this); | ||||
|                 // Index 2 means no editing, just wait for mouse up event.
 | ||||
|                 m_layers_editing.state = LayersEditing::Completed; | ||||
| 
 | ||||
|                 m_dirty = true; | ||||
|             } | ||||
|         } | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|         else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) | ||||
|         { | ||||
|             if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports) | ||||
|  | @ -4262,10 +4118,8 @@ bool GLCanvas3D::_init_toolbars() | |||
|     if (!_init_undoredo_toolbar()) | ||||
|         return false; | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     if (!_init_view_toolbar()) | ||||
|         return false; | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
|  | @ -4524,12 +4378,10 @@ bool GLCanvas3D::_init_undoredo_toolbar() | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
| bool GLCanvas3D::_init_view_toolbar() | ||||
| { | ||||
|     return wxGetApp().plater()->init_view_toolbar(); | ||||
| } | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
| bool GLCanvas3D::_set_current() | ||||
| { | ||||
|  | @ -5439,11 +5291,11 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|                 const std::string& code = it->gcode; | ||||
|                 // pause print or custom Gcode
 | ||||
|                 if (code == PausePrintCode ||  | ||||
|                     (code != ColorChangeCode && code != ExtruderChangeCode)) | ||||
|                     (code != ColorChangeCode && code != ToolChangeCode)) | ||||
|                     return number_tools()-1; // last color item is a gray color for pause print or custom G-code 
 | ||||
| 
 | ||||
|                 // change tool (extruder) 
 | ||||
|                 if (code == ExtruderChangeCode) | ||||
|                 if (code == ToolChangeCode) | ||||
|                     return get_color_idx_for_tool_change(it, extruder); | ||||
|                 // change color for current extruder
 | ||||
|                 if (code == ColorChangeCode) { | ||||
|  | @ -5465,7 +5317,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|                         return color_idx; | ||||
|                 } | ||||
|                 // change tool (extruder) 
 | ||||
|                 if (it->gcode == ExtruderChangeCode) | ||||
|                 if (it->gcode == ToolChangeCode) | ||||
|                     return get_color_idx_for_tool_change(it, extruder); | ||||
|             } | ||||
| 
 | ||||
|  | @ -5509,7 +5361,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c | |||
|             bool is_tool_change = false; | ||||
|             while (it_n != color_print_values->begin()) { | ||||
|                 --it_n; | ||||
|                 if (it_n->gcode == ExtruderChangeCode) { | ||||
|                 if (it_n->gcode == ToolChangeCode) { | ||||
|                     is_tool_change = true; | ||||
|                     if (it_n->extruder == it->extruder || (it_n->extruder == 0 && it->extruder == extruder)) | ||||
|                         return get_m600_color_idx(it); | ||||
|  |  | |||
|  | @ -83,9 +83,6 @@ template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>; | |||
| 
 | ||||
| using HeightProfileSmoothEvent = Event<HeightProfileSmoothingParams>; | ||||
| 
 | ||||
| #if !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent); | ||||
| #endif // !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); | ||||
|  | @ -108,11 +105,9 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent); | |||
| wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
| class GLCanvas3D | ||||
| { | ||||
|  | @ -162,17 +157,10 @@ private: | |||
| 
 | ||||
|     private: | ||||
|         static const float THICKNESS_BAR_WIDTH; | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         static const float THICKNESS_RESET_BUTTON_HEIGHT; | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|         bool                        m_enabled; | ||||
|         Shader                      m_shader; | ||||
|         unsigned int                m_z_texture_id; | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         mutable GLTexture           m_tooltip_texture; | ||||
|         mutable GLTexture           m_reset_texture; | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|         // Not owned by LayersEditing.
 | ||||
|         const DynamicPrintConfig   *m_config; | ||||
|         // ModelObject for the currently selected object (Model::objects[last_object_id]).
 | ||||
|  | @ -184,10 +172,8 @@ private: | |||
|         std::vector<double>         m_layer_height_profile; | ||||
|         bool                        m_layer_height_profile_modified; | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         mutable float               m_adaptive_quality; | ||||
|         mutable HeightProfileSmoothingParams m_smooth_params; | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|         class LayersTexture | ||||
|         { | ||||
|  | @ -235,24 +221,13 @@ private: | |||
| 		void adjust_layer_height_profile(); | ||||
| 		void accept_changes(GLCanvas3D& canvas); | ||||
|         void reset_layer_height_profile(GLCanvas3D& canvas); | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         void adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor); | ||||
|         void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|         static float get_cursor_z_relative(const GLCanvas3D& canvas); | ||||
|         static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y); | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         static bool reset_rect_contains(const GLCanvas3D& canvas, float x, float y); | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|         static Rect get_bar_rect_screen(const GLCanvas3D& canvas); | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         static Rect get_reset_rect_screen(const GLCanvas3D& canvas); | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|         static Rect get_bar_rect_viewport(const GLCanvas3D& canvas); | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         static Rect get_reset_rect_viewport(const GLCanvas3D& canvas); | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|         float object_max_z() const { return m_object_max_z; } | ||||
| 
 | ||||
|  | @ -261,18 +236,11 @@ private: | |||
|     private: | ||||
|         bool is_initialized() const; | ||||
|         void generate_layer_height_texture(); | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const; | ||||
|         void _render_reset_texture(const Rect& reset_rect) const; | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|         void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const; | ||||
|         void render_profile(const Rect& bar_rect) const; | ||||
|         void update_slicing_parameters(); | ||||
| 
 | ||||
|         static float thickness_bar_width(const GLCanvas3D &canvas); | ||||
| #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|         static float reset_button_height(const GLCanvas3D &canvas); | ||||
| #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
|     }; | ||||
| 
 | ||||
|     struct Mouse | ||||
|  | @ -539,11 +507,9 @@ public: | |||
|     bool is_layers_editing_enabled() const; | ||||
|     bool is_layers_editing_allowed() const; | ||||
| 
 | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     void reset_layer_height_profile(); | ||||
|     void adaptive_layer_height_profile(float quality_factor); | ||||
|     void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|     bool is_reload_delayed() const; | ||||
| 
 | ||||
|  | @ -683,9 +649,7 @@ private: | |||
|     bool _init_toolbars(); | ||||
|     bool _init_main_toolbar(); | ||||
|     bool _init_undoredo_toolbar(); | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     bool _init_view_toolbar(); | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     bool _set_current(); | ||||
|     void _resize(unsigned int w, unsigned int h); | ||||
|  |  | |||
|  | @ -276,12 +276,12 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri | |||
| #if ENABLE_MODIFIED_TOOLBAR_TEXTURES | ||||
|                 float inv_255 = 1.0f / 255.0f; | ||||
|                 // offset by 1 to leave the first pixel empty (both in x and y)
 | ||||
|                 for (int r = 1; r <= sprite_size_px; ++r) | ||||
|                 for (unsigned int r = 1; r <= sprite_size_px; ++r) | ||||
|                 { | ||||
|                     int offset_r = r * sprite_size_px_ex; | ||||
|                     for (int c = 1; c <= sprite_size_px; ++c) | ||||
|                     unsigned int offset_r = r * sprite_size_px_ex; | ||||
|                     for (unsigned int c = 1; c <= sprite_size_px; ++c) | ||||
|                     { | ||||
|                         int offset = (offset_r + c) * 4; | ||||
|                         unsigned int offset = (offset_r + c) * 4; | ||||
|                         float alpha = (float)output_data.data()[offset + 3] * inv_255; | ||||
|                         output_data.data()[offset + 0] = (unsigned char)(output_data.data()[offset + 0] * alpha); | ||||
|                         output_data.data()[offset + 1] = (unsigned char)(output_data.data()[offset + 1] * alpha); | ||||
|  |  | |||
|  | @ -295,9 +295,7 @@ public: | |||
| 
 | ||||
|     bool is_any_item_pressed() const; | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     unsigned int get_items_count() const { return (unsigned int)m_items.size(); } | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
|     int get_item_id(const std::string& name) const; | ||||
| 
 | ||||
|     void force_left_action(int item_id, GLCanvas3D& parent) { do_action(GLToolbarItem::Left, item_id, parent, false); } | ||||
|  |  | |||
|  | @ -597,7 +597,7 @@ void Preview::create_double_slider() | |||
| 
 | ||||
|     Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { | ||||
|         Model& model = wxGetApp().plater()->model(); | ||||
|         model.custom_gcode_per_print_z.gcodes = m_slider->GetTicksValues(); | ||||
|         model.custom_gcode_per_print_z = m_slider->GetTicksValues(); | ||||
|         m_schedule_background_process(); | ||||
| 
 | ||||
|         update_view_type(false); | ||||
|  | @ -666,8 +666,11 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee | |||
|     bool   snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min(); | ||||
| 	bool   snap_to_max  = force_sliders_full_range || m_slider->is_higher_at_max(); | ||||
| 
 | ||||
|     std::vector<Model::CustomGCode> &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes; | ||||
|     check_slider_values(ticks_from_model, layers_z); | ||||
|     // Detect and set manipulation mode for double slider
 | ||||
|     update_double_slider_mode(); | ||||
| 
 | ||||
|     Model::CustomGCodeInfo &ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z; | ||||
|     check_slider_values(ticks_info_from_model.gcodes, layers_z); | ||||
| 
 | ||||
|     m_slider->SetSliderValues(layers_z); | ||||
|     assert(m_slider->GetMinValue() == 0); | ||||
|  | @ -689,13 +692,9 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee | |||
|     } | ||||
|     m_slider->SetSelectionSpan(idx_low, idx_high); | ||||
| 
 | ||||
|     m_slider->SetTicksValues(ticks_from_model); | ||||
|     m_slider->SetTicksValues(ticks_info_from_model); | ||||
| 
 | ||||
|     bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF); | ||||
| 
 | ||||
|     m_slider->EnableTickManipulation(color_print_enable); | ||||
|     // Detect and set manipulation mode for double slider
 | ||||
|     update_double_slider_mode(); | ||||
|     m_slider->EnableTickManipulation(wxGetApp().plater()->printer_technology() == ptFFF); | ||||
| } | ||||
| 
 | ||||
| void Preview::update_double_slider_mode() | ||||
|  |  | |||
|  | @ -48,12 +48,10 @@ std::string GLGizmoMove3D::on_get_name() const | |||
|     return (_(L("Move")) + " [M]").ToUTF8().data(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
| bool GLGizmoMove3D::on_is_activable() const | ||||
| { | ||||
|     return !m_parent.get_selection().is_empty(); | ||||
| } | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
| 
 | ||||
| void GLGizmoMove3D::on_start_dragging() | ||||
| { | ||||
|  |  | |||
|  | @ -33,9 +33,7 @@ public: | |||
| protected: | ||||
|     virtual bool on_init(); | ||||
|     virtual std::string on_get_name() const; | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
|     virtual bool on_is_activable() const; | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
|     virtual void on_start_dragging(); | ||||
|     virtual void on_stop_dragging(); | ||||
|     virtual void on_update(const UpdateData& data); | ||||
|  |  | |||
|  | @ -449,12 +449,10 @@ std::string GLGizmoRotate3D::on_get_name() const | |||
|     return (_(L("Rotate")) + " [R]").ToUTF8().data(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
| bool GLGizmoRotate3D::on_is_activable() const | ||||
| { | ||||
|     return !m_parent.get_selection().is_empty(); | ||||
| } | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
| 
 | ||||
| void GLGizmoRotate3D::on_start_dragging() | ||||
| { | ||||
|  |  | |||
|  | @ -104,9 +104,7 @@ protected: | |||
|         if (id < 3) | ||||
|             m_gizmos[id].disable_grabber(0); | ||||
|     } | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
|     virtual bool on_is_activable() const; | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
|     virtual void on_start_dragging(); | ||||
|     virtual void on_stop_dragging(); | ||||
|     virtual void on_update(const UpdateData& data) | ||||
|  |  | |||
|  | @ -49,12 +49,8 @@ std::string GLGizmoScale3D::on_get_name() const | |||
| 
 | ||||
| bool GLGizmoScale3D::on_is_activable() const | ||||
| { | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
|     const Selection& selection = m_parent.get_selection(); | ||||
|     return !selection.is_empty() && !selection.is_wipe_tower(); | ||||
| #else | ||||
|     return !m_parent.get_selection().is_wipe_tower(); | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
| } | ||||
| 
 | ||||
| void GLGizmoScale3D::on_start_dragging() | ||||
|  |  | |||
|  | @ -881,11 +881,7 @@ void GLGizmosManager::do_render_overlay() const | |||
|     if ((icons_texture_id == 0) || (tex_width <= 1) || (tex_height <= 1)) | ||||
|         return; | ||||
| 
 | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
|     float du = (float)(tex_width - 1) / (4.0f * (float)tex_width); // 4 is the number of possible states if the icons
 | ||||
| #else | ||||
|     float du = (float)(tex_width - 1) / (3.0f * (float)tex_width); // 3 is the number of possible states if the icons
 | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
|     float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height); | ||||
| 
 | ||||
|     // tiles in the texture are spaced by 1 pixel
 | ||||
|  | @ -908,11 +904,7 @@ void GLGizmosManager::do_render_overlay() const | |||
|         GLGizmoBase* gizmo = m_gizmos[idx].get(); | ||||
| 
 | ||||
|         unsigned int sprite_id = gizmo->get_sprite_id(); | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
|         int icon_idx = (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3)); | ||||
| #else | ||||
|         int icon_idx = m_current == idx ? 2 : (m_hover == idx ? 1 : 0); | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
| 
 | ||||
| #if ENABLE_MODIFIED_TOOLBAR_TEXTURES | ||||
|         float v_top = v_offset + sprite_id * dv; | ||||
|  | @ -971,9 +963,7 @@ bool GLGizmosManager::generate_icons_texture() const | |||
|     states.push_back(std::make_pair(1, false)); // Activable
 | ||||
|     states.push_back(std::make_pair(0, false)); // Hovered
 | ||||
|     states.push_back(std::make_pair(0, true));  // Selected
 | ||||
| #if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE | ||||
|     states.push_back(std::make_pair(2, false)); // Disabled
 | ||||
| #endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
 | ||||
| 
 | ||||
|     unsigned int sprite_size_px = (unsigned int)m_layout.scaled_icons_size(); | ||||
| //    // force even size
 | ||||
|  |  | |||
|  | @ -5,9 +5,7 @@ | |||
| #include "GUI_App.hpp" | ||||
| #include "PresetBundle.hpp" | ||||
| #include "AppConfig.hpp" | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
| #include "GLCanvas3D.hpp" | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
| #include <wx/glcanvas.h> | ||||
| 
 | ||||
|  | @ -206,9 +204,7 @@ Mouse3DController::Mouse3DController() | |||
|     , m_device_str("") | ||||
|     , m_running(false) | ||||
|     , m_show_settings_dialog(false) | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     , m_settings_dialog_closed_by_user(false) | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| { | ||||
|     m_last_time = std::chrono::high_resolution_clock::now(); | ||||
| } | ||||
|  | @ -253,9 +249,7 @@ bool Mouse3DController::apply(Camera& camera) | |||
|         disconnect_device(); | ||||
|         // hides the settings dialog if the user un-plug the device
 | ||||
|         m_show_settings_dialog = false; | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|         m_settings_dialog_closed_by_user = false; | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
|     } | ||||
| 
 | ||||
|     // check if the user plugged the device
 | ||||
|  | @ -265,16 +259,11 @@ bool Mouse3DController::apply(Camera& camera) | |||
|     return is_device_connected() ? m_state.apply(camera) : false; | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
| void Mouse3DController::render_settings_dialog(GLCanvas3D& canvas) const | ||||
| #else | ||||
| void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsigned int canvas_height) const | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| { | ||||
|     if (!m_running || !m_show_settings_dialog) | ||||
|         return; | ||||
| 
 | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     // when the user clicks on [X] or [Close] button we need to trigger
 | ||||
|     // an extra frame to let the dialog disappear
 | ||||
|     if (m_settings_dialog_closed_by_user) | ||||
|  | @ -286,16 +275,10 @@ void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsign | |||
|     } | ||||
| 
 | ||||
|     Size cnv_size = canvas.get_canvas_size(); | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
|     ImGuiWrapper& imgui = *wxGetApp().imgui(); | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     imgui.set_next_window_pos(0.5f * (float)cnv_size.get_width(), 0.5f * (float)cnv_size.get_height(), ImGuiCond_Always, 0.5f, 0.5f); | ||||
| #else | ||||
|     imgui.set_next_window_pos(0.5f * (float)canvas_width, 0.5f * (float)canvas_height, ImGuiCond_Always, 0.5f, 0.5f); | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     static ImVec2 last_win_size(0.0f, 0.0f); | ||||
|     bool shown = true; | ||||
|     if (imgui.begin(_(L("3Dconnexion settings")), &shown, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse)) | ||||
|  | @ -310,9 +293,6 @@ void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsign | |||
|                 last_win_size = win_size; | ||||
|                 canvas.request_extra_frame(); | ||||
|             } | ||||
| #else | ||||
|     imgui.begin(_(L("3Dconnexion settings")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
|             const ImVec4& color = ImGui::GetStyleColorVec4(ImGuiCol_Separator); | ||||
|             ImGui::PushStyleColor(ImGuiCol_Text, color); | ||||
|  | @ -395,7 +375,6 @@ void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsign | |||
|             Vec3f target = wxGetApp().plater()->get_camera().get_target().cast<float>(); | ||||
|             ImGui::InputFloat3("Target", target.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT
 | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
| 
 | ||||
|             ImGui::Separator(); | ||||
|             if (imgui.button(_(L("Close")))) | ||||
|  | @ -412,7 +391,6 @@ void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsign | |||
|             canvas.set_as_dirty(); | ||||
|         } | ||||
|     } | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
|     imgui.end(); | ||||
| } | ||||
|  |  | |||
|  | @ -18,9 +18,7 @@ namespace Slic3r { | |||
| namespace GUI { | ||||
| 
 | ||||
| struct Camera; | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
| class GLCanvas3D; | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
| class Mouse3DController | ||||
| { | ||||
|  | @ -143,13 +141,9 @@ class Mouse3DController | |||
|     hid_device* m_device; | ||||
|     std::string m_device_str; | ||||
|     bool m_running; | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     mutable bool m_show_settings_dialog; | ||||
|     // set to true when ther user closes the dialog by clicking on [X] or [Close] buttons
 | ||||
|     mutable bool m_settings_dialog_closed_by_user; | ||||
| #else | ||||
|     bool m_show_settings_dialog; | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
|     std::chrono::time_point<std::chrono::high_resolution_clock> m_last_time; | ||||
| 
 | ||||
| public: | ||||
|  | @ -167,11 +161,7 @@ public: | |||
| 
 | ||||
|     bool is_settings_dialog_shown() const { return m_show_settings_dialog; } | ||||
|     void show_settings_dialog(bool show) { m_show_settings_dialog = show && is_running(); } | ||||
| #if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG | ||||
|     void render_settings_dialog(GLCanvas3D& canvas) const; | ||||
| #else | ||||
|     void render_settings_dialog(unsigned int canvas_width, unsigned int canvas_height) const; | ||||
| #endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG
 | ||||
| 
 | ||||
| private: | ||||
|     bool connect_device(); | ||||
|  |  | |||
|  | @ -1857,9 +1857,7 @@ struct Plater::priv | |||
| 
 | ||||
|     void set_current_canvas_as_dirty(); | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     bool init_view_toolbar(); | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     void reset_all_gizmos(); | ||||
|     void update_ui_from_settings(); | ||||
|  | @ -2006,9 +2004,6 @@ private: | |||
|     bool complit_init_object_menu(); | ||||
|     bool complit_init_sla_object_menu(); | ||||
|     bool complit_init_part_menu(); | ||||
| #if !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     void init_view_toolbar(); | ||||
| #endif // !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     bool can_split() const; | ||||
|     bool layers_height_allowed() const; | ||||
|  | @ -2142,11 +2137,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     view3D_canvas->Bind(EVT_GLCANVAS_RESETGIZMOS, [this](SimpleEvent&) { reset_all_gizmos(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); }); | ||||
| #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, [this](SimpleEvent&) { this->view3D->get_canvas3d()->reset_layer_height_profile(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, [this](Event<float>& evt) { this->view3D->get_canvas3d()->adaptive_layer_height_profile(evt.data); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, [this](HeightProfileSmoothEvent& evt) { this->view3D->get_canvas3d()->smooth_layer_height_profile(evt.data); }); | ||||
| #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
 | ||||
| 
 | ||||
|     // 3DScene/Toolbar:
 | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); | ||||
|  | @ -2160,9 +2153,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); | ||||
|     view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); | ||||
| #if !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_INIT, [this](SimpleEvent&) { init_view_toolbar(); }); | ||||
| #endif // !ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) | ||||
|         { | ||||
|             set_bed_shape(config->option<ConfigOptionPoints>("bed_shape")->values, | ||||
|  | @ -3241,12 +3231,9 @@ void Plater::priv::reload_from_disk() | |||
| 
 | ||||
|     // collects paths of files to load
 | ||||
|     std::vector<fs::path> input_paths; | ||||
| #if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION | ||||
|     std::vector<fs::path> missing_input_paths; | ||||
| #endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION
 | ||||
|     for (const SelectedVolume& v : selected_volumes) | ||||
|     { | ||||
| #if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION | ||||
|         const ModelObject* object = model.objects[v.object_idx]; | ||||
|         const ModelVolume* volume = object->volumes[v.volume_idx]; | ||||
| 
 | ||||
|  | @ -3257,14 +3244,8 @@ void Plater::priv::reload_from_disk() | |||
|             else | ||||
|                 missing_input_paths.push_back(volume->source.input_file); | ||||
|         } | ||||
| #else | ||||
|         const ModelVolume* volume = model.objects[v.object_idx]->volumes[v.volume_idx]; | ||||
|         if (!volume->source.input_file.empty() && boost::filesystem::exists(volume->source.input_file)) | ||||
|             input_paths.push_back(volume->source.input_file); | ||||
| #endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION
 | ||||
|     } | ||||
| 
 | ||||
| #if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION | ||||
|     std::sort(missing_input_paths.begin(), missing_input_paths.end()); | ||||
|     missing_input_paths.erase(std::unique(missing_input_paths.begin(), missing_input_paths.end()), missing_input_paths.end()); | ||||
| 
 | ||||
|  | @ -3314,7 +3295,6 @@ void Plater::priv::reload_from_disk() | |||
|                 return; | ||||
|         } | ||||
|     } | ||||
| #endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION
 | ||||
| 
 | ||||
|     std::sort(input_paths.begin(), input_paths.end()); | ||||
|     input_paths.erase(std::unique(input_paths.begin(), input_paths.end()), input_paths.end()); | ||||
|  | @ -3360,27 +3340,17 @@ void Plater::priv::reload_from_disk() | |||
|                     new_volume->config.apply(old_volume->config); | ||||
|                     new_volume->set_type(old_volume->type()); | ||||
|                     new_volume->set_material_id(old_volume->material_id()); | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|                     new_volume->set_transformation(old_volume->get_transformation() * old_volume->source.transform); | ||||
| #else | ||||
|                     new_volume->set_transformation(old_volume->get_transformation()); | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|                     new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); | ||||
|                     new_volume->source.input_file = path; | ||||
|                     std::swap(old_model_object->volumes[old_v.volume_idx], old_model_object->volumes.back()); | ||||
|                     old_model_object->delete_volume(old_model_object->volumes.size() - 1); | ||||
| #if ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|                     old_model_object->ensure_on_bed(); | ||||
| #endif // ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| #if !ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE | ||||
|     model.adjust_min_z(); | ||||
| #endif // !ENABLE_KEEP_LOADED_VOLUME_TRANSFORM_AS_STAND_ALONE
 | ||||
| 
 | ||||
|     // update 3D scene
 | ||||
|     update(); | ||||
| 
 | ||||
|  | @ -3994,17 +3964,11 @@ void Plater::priv::set_current_canvas_as_dirty() | |||
|         preview->set_as_dirty(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
| bool Plater::priv::init_view_toolbar() | ||||
| #else | ||||
| void Plater::priv::init_view_toolbar() | ||||
| #endif //!ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| { | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     if (view_toolbar.get_items_count() > 0) | ||||
|         // already initialized
 | ||||
|         return true; | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     BackgroundTexture::Metadata background_data; | ||||
|     background_data.filename = "toolbar_background.png"; | ||||
|  | @ -4014,11 +3978,7 @@ void Plater::priv::init_view_toolbar() | |||
|     background_data.bottom = 16; | ||||
| 
 | ||||
|     if (!view_toolbar.init(background_data)) | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|         return false; | ||||
| #else | ||||
|         return; | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     view_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Left); | ||||
|     view_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Bottom); | ||||
|  | @ -4033,11 +3993,7 @@ void Plater::priv::init_view_toolbar() | |||
|     item.sprite_id = 0; | ||||
|     item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; | ||||
|     if (!view_toolbar.add_item(item)) | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|         return false; | ||||
| #else | ||||
|         return; | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     item.name = "Preview"; | ||||
|     item.icon_filename = "preview.svg"; | ||||
|  | @ -4045,18 +4001,12 @@ void Plater::priv::init_view_toolbar() | |||
|     item.sprite_id = 1; | ||||
|     item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; | ||||
|     if (!view_toolbar.add_item(item)) | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|         return false; | ||||
| #else | ||||
|         return; | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     view_toolbar.select_item("3D"); | ||||
|     view_toolbar.set_enabled(true); | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     return true; | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| } | ||||
| 
 | ||||
| bool Plater::priv::can_set_instance_to_object() const | ||||
|  | @ -4121,11 +4071,7 @@ bool Plater::priv::can_reload_from_disk() const | |||
|     for (const SelectedVolume& v : selected_volumes) | ||||
|     { | ||||
|         const ModelVolume* volume = model.objects[v.object_idx]->volumes[v.volume_idx]; | ||||
| #if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION | ||||
|         if (!volume->source.input_file.empty()) | ||||
| #else | ||||
|         if (!volume->source.input_file.empty() && boost::filesystem::exists(volume->source.input_file)) | ||||
| #endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION
 | ||||
|             paths.push_back(volume->source.input_file); | ||||
|     } | ||||
|     std::sort(paths.begin(), paths.end()); | ||||
|  | @ -5515,12 +5461,10 @@ void Plater::msw_rescale() | |||
|     GetParent()->Layout(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
| bool Plater::init_view_toolbar() | ||||
| { | ||||
|     return p->init_view_toolbar(); | ||||
| } | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
| const Camera& Plater::get_camera() const | ||||
| { | ||||
|  |  | |||
|  | @ -266,9 +266,7 @@ public: | |||
| 
 | ||||
|     void msw_rescale(); | ||||
| 
 | ||||
| #if ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX | ||||
|     bool init_view_toolbar(); | ||||
| #endif // ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX
 | ||||
| 
 | ||||
|     const Camera& get_camera() const; | ||||
|     const Mouse3DController& get_mouse3d_controller() const; | ||||
|  |  | |||
|  | @ -2532,9 +2532,10 @@ double DoubleSlider::get_double_value(const SelectedSlider& selection) | |||
| } | ||||
| 
 | ||||
| using t_custom_code = Slic3r::Model::CustomGCode; | ||||
| std::vector<t_custom_code> DoubleSlider::GetTicksValues() const | ||||
| Slic3r::Model::CustomGCodeInfo DoubleSlider::GetTicksValues() const | ||||
| { | ||||
|     std::vector<t_custom_code> values; | ||||
|     Slic3r::Model::CustomGCodeInfo custom_gcode_per_print_z; | ||||
|     std::vector<t_custom_code>& values = custom_gcode_per_print_z.gcodes; | ||||
| 
 | ||||
|     const int val_size = m_values.size(); | ||||
|     if (!m_values.empty()) | ||||
|  | @ -2544,17 +2545,23 @@ std::vector<t_custom_code> DoubleSlider::GetTicksValues() const | |||
|             values.emplace_back(t_custom_code{m_values[tick.tick], tick.gcode, tick.extruder, tick.color}); | ||||
|         } | ||||
| 
 | ||||
|     return values; | ||||
|     custom_gcode_per_print_z.mode = m_mode; | ||||
| 
 | ||||
|     return custom_gcode_per_print_z; | ||||
| } | ||||
| 
 | ||||
| void DoubleSlider::SetTicksValues(const std::vector<t_custom_code>& heights) | ||||
| void DoubleSlider::SetTicksValues(const Slic3r::Model::CustomGCodeInfo& custom_gcode_per_print_z) | ||||
| { | ||||
|     if (m_values.empty()) | ||||
|     { | ||||
|         m_ticks_mode = m_mode; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const bool was_empty = m_ticks.empty(); | ||||
| 
 | ||||
|     m_ticks.clear(); | ||||
|     const std::vector<t_custom_code>& heights = custom_gcode_per_print_z.gcodes; | ||||
|     for (auto h : heights) { | ||||
|         auto it = std::lower_bound(m_values.begin(), m_values.end(), h.print_z - epsilon()); | ||||
| 
 | ||||
|  | @ -2566,7 +2573,9 @@ void DoubleSlider::SetTicksValues(const std::vector<t_custom_code>& heights) | |||
|      | ||||
|     if (!was_empty && m_ticks.empty()) | ||||
|         // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one
 | ||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|         post_ticks_changed_event(); | ||||
| 
 | ||||
|     m_ticks_mode = custom_gcode_per_print_z.mode; | ||||
| 
 | ||||
|     Refresh(); | ||||
|     Update(); | ||||
|  | @ -2793,7 +2802,7 @@ void DoubleSlider::draw_ticks(wxDC& dc) | |||
|                             dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/); | ||||
| 
 | ||||
|         // Draw icon for "Pause print" or "Custom Gcode"
 | ||||
|         if (tick.gcode != Slic3r::ColorChangeCode && tick.gcode != Slic3r::ExtruderChangeCode) | ||||
|         if (tick.gcode != Slic3r::ColorChangeCode && tick.gcode != Slic3r::ToolChangeCode) | ||||
|         { | ||||
|             wxBitmap icon = create_scaled_bitmap(this, tick.gcode == Slic3r::PausePrintCode ? "pause_print" : "edit_gcode"); | ||||
| 
 | ||||
|  | @ -2827,7 +2836,7 @@ std::string DoubleSlider::get_color_for_color_change_tick(std::set<TICK_CODE>::c | |||
|     bool is_tool_change = false; | ||||
|     while (it_n != m_ticks.begin()) { | ||||
|         --it_n; | ||||
|         if (it_n->gcode == Slic3r::ExtruderChangeCode) { | ||||
|         if (it_n->gcode == Slic3r::ToolChangeCode) { | ||||
|             is_tool_change = true; | ||||
|             if (it_n->extruder == it->extruder) | ||||
|                 return it->color; | ||||
|  | @ -2863,28 +2872,28 @@ void DoubleSlider::draw_colored_band(wxDC& dc) | |||
|     }; | ||||
| 
 | ||||
|     // don't color a band for MultiExtruder mode
 | ||||
|     if (m_ticks.empty() || m_mode == mmMultiExtruder) | ||||
|     if (m_ticks.empty() || m_mode == t_mode::MultiExtruder) | ||||
|     { | ||||
|         draw_band(dc, GetParent()->GetBackgroundColour(), main_band); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const int default_color_idx = m_mode==mmMultiAsSingle ? std::max<int>(m_only_extruder - 1, 0) : 0; | ||||
|     const int default_color_idx = m_mode==t_mode::MultiAsSingle ? std::max<int>(m_only_extruder - 1, 0) : 0; | ||||
|     draw_band(dc, wxColour(Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config()[default_color_idx]), main_band); | ||||
| 
 | ||||
|     std::set<TICK_CODE>::const_iterator tick_it = m_ticks.begin(); | ||||
| 
 | ||||
|     while (tick_it != m_ticks.end()) | ||||
|     { | ||||
|         if ( (m_mode == mmSingleExtruder &&  tick_it->gcode == Slic3r::ColorChangeCode  ) || | ||||
|              (m_mode == mmMultiAsSingle  && (tick_it->gcode == Slic3r::ExtruderChangeCode || tick_it->gcode == Slic3r::ColorChangeCode)) )  | ||||
|         if ( (m_mode == t_mode::SingleExtruder &&  tick_it->gcode == Slic3r::ColorChangeCode  ) || | ||||
|              (m_mode == t_mode::MultiAsSingle  && (tick_it->gcode == Slic3r::ToolChangeCode || tick_it->gcode == Slic3r::ColorChangeCode)) )  | ||||
|         {         | ||||
|             const wxCoord pos = get_position_from_value(tick_it->tick); | ||||
|             is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : | ||||
|                               main_band.SetBottom(pos - 1); | ||||
| 
 | ||||
|             const std::string clr_str = m_mode == mmSingleExtruder ? tick_it->color : | ||||
|                                         tick_it->gcode == Slic3r::ExtruderChangeCode ? | ||||
|             const std::string clr_str = m_mode == t_mode::SingleExtruder ? tick_it->color : | ||||
|                                         tick_it->gcode == Slic3r::ToolChangeCode ? | ||||
|                                         get_color_for_tool_change_tick(tick_it) : | ||||
|                                         get_color_for_color_change_tick(tick_it); | ||||
| 
 | ||||
|  | @ -2934,7 +2943,7 @@ void DoubleSlider::draw_revert_icon(wxDC& dc) | |||
| 
 | ||||
| void DoubleSlider::draw_cog_icon(wxDC& dc) | ||||
| { | ||||
|     if (m_mode != mmMultiExtruder) | ||||
|     if (m_mode != t_mode::MultiExtruder) | ||||
|         return; | ||||
| 
 | ||||
|     int width, height; | ||||
|  | @ -3046,9 +3055,9 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) | |||
|         if (!m_selection) m_selection = ssHigher; | ||||
| 
 | ||||
|         m_ticks.clear(); | ||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|         post_ticks_changed_event(); | ||||
|     } | ||||
|     else if (is_point_in_rect(pos, m_rect_cog_icon) && m_mode == mmMultiExtruder) { | ||||
|     else if (is_point_in_rect(pos, m_rect_cog_icon) && m_mode == t_mode::MultiExtruder) { | ||||
|         // show dialog for set extruder sequence
 | ||||
|         m_edit_extruder_sequence = true; | ||||
|     } | ||||
|  | @ -3119,17 +3128,17 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus) | |||
|     { | ||||
|         const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; | ||||
|         const auto tick_code_it = m_ticks.find(TICK_CODE{tick}); | ||||
|         tooltip = tick_code_it == m_ticks.end()                    ? (m_mode == mmMultiAsSingle ? | ||||
|         tooltip = tick_code_it == m_ticks.end()                    ? (m_mode == t_mode::MultiAsSingle ? | ||||
|                       _(L("For add change extruder use left mouse button click")) : | ||||
|                       _(L("For add color change use left mouse button click"))  ) + "\n" + | ||||
|                       _(L("For add another code use right mouse button click"))   : | ||||
|                   tick_code_it->gcode == Slic3r::ColorChangeCode    ? ( m_mode == mmSingleExtruder ? | ||||
|                   tick_code_it->gcode == Slic3r::ColorChangeCode    ? ( m_mode == t_mode::SingleExtruder ? | ||||
|                       _(L("For Delete color change use left mouse button click\n" | ||||
|                           "For Edit color use right mouse button click")) : | ||||
|                       from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): | ||||
|                   tick_code_it->gcode == Slic3r::PausePrintCode     ?  | ||||
|                       _(L("Delete pause")) : | ||||
|                   tick_code_it->gcode == Slic3r::ExtruderChangeCode ? | ||||
|                   tick_code_it->gcode == Slic3r::ToolChangeCode ? | ||||
|                       from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) : | ||||
|                       from_u8((boost::format(_utf8(L("For Delete \"%1%\" code use left mouse button click\n" | ||||
|                                                        "For Edit \"%1%\" code use right mouse button click"))) % tick_code_it->gcode ).str()); | ||||
|  | @ -3200,7 +3209,7 @@ void DoubleSlider::append_change_extruder_menu_item(wxMenu* menu) | |||
|             const wxString item_name = wxString::Format(_(L("Extruder %d")), i) + | ||||
|                                        (is_active_extruder ? " (" + _(L("active")) + ")" : ""); | ||||
| 
 | ||||
|             if (m_mode == mmMultiAsSingle) | ||||
|             if (m_mode == t_mode::MultiAsSingle) | ||||
|                 append_menu_item(change_extruder_menu, wxID_ANY, item_name, "", | ||||
|                     [this, i](wxCommandEvent&) { change_extruder(i); }, "", menu, | ||||
|                     [is_active_extruder]() { return !is_active_extruder; }, Slic3r::GUI::wxGetApp().plater()); | ||||
|  | @ -3208,13 +3217,13 @@ void DoubleSlider::append_change_extruder_menu_item(wxMenu* menu) | |||
| //                    [this, i](wxCommandEvent&) { change_extruder(i); }, menu)->Check(i == initial_extruder);
 | ||||
|         } | ||||
| 
 | ||||
|         const wxString change_extruder_menu_name = m_mode == mmMultiAsSingle ? _(L("Change extruder")) : _(L("Change extruder (N/A)")); | ||||
|         const wxString change_extruder_menu_name = m_mode == t_mode::MultiAsSingle ? _(L("Change extruder")) : _(L("Change extruder (N/A)")); | ||||
| 
 | ||||
|         wxMenuItem* change_extruder_menu_item = menu->AppendSubMenu(change_extruder_menu, change_extruder_menu_name, _(L("Use another extruder"))); | ||||
|         change_extruder_menu_item->SetBitmap(create_scaled_bitmap(this, "change_extruder")); | ||||
| 
 | ||||
|         Slic3r::GUI::wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this, change_extruder_menu_item](wxUpdateUIEvent& evt) { | ||||
|             enable_menu_item(evt, [this]() {return m_mode == mmMultiAsSingle; }, change_extruder_menu_item, this); }, | ||||
|             enable_menu_item(evt, [this]() {return m_mode == t_mode::MultiAsSingle; }, change_extruder_menu_item, this); }, | ||||
|             change_extruder_menu_item->GetId()); | ||||
|     } | ||||
| } | ||||
|  | @ -3255,13 +3264,13 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event) | |||
| 
 | ||||
|     if (m_show_context_menu) | ||||
|     { | ||||
|         if (m_mode == mmSingleExtruder) | ||||
|         if (m_mode == t_mode::SingleExtruder) | ||||
|             add_code(Slic3r::ColorChangeCode); | ||||
|         else | ||||
|         { | ||||
|             wxMenu menu; | ||||
| 
 | ||||
|             if (m_mode == mmMultiAsSingle) | ||||
|             if (m_mode == t_mode::MultiAsSingle) | ||||
|                 append_change_extruder_menu_item(&menu); | ||||
|             else | ||||
|                 append_add_color_change_menu_item(&menu); | ||||
|  | @ -3335,7 +3344,7 @@ void DoubleSlider::action_tick(const TicksAction action) | |||
|             return; | ||||
|         m_ticks.erase(TICK_CODE{tick}); | ||||
| 
 | ||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|         post_ticks_changed_event(it->gcode); | ||||
|         Refresh(); | ||||
|         Update(); | ||||
|         return; | ||||
|  | @ -3350,7 +3359,7 @@ void DoubleSlider::action_tick(const TicksAction action) | |||
|         if (m_suppress_add_code) | ||||
|             return; | ||||
|         m_suppress_add_code = true; | ||||
|         if (m_mode == mmSingleExtruder) // if (m_mode != mmMultiExtruder)
 | ||||
|         if (m_mode == t_mode::SingleExtruder) // if (m_mode != t_mode::MultiExtruder)
 | ||||
|             add_code(Slic3r::ColorChangeCode); | ||||
|         m_suppress_add_code = false; | ||||
|         return; | ||||
|  | @ -3444,7 +3453,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) | |||
|             m_show_context_menu = true; | ||||
|             return; | ||||
|         } | ||||
|         if (it->gcode != Slic3r::ExtruderChangeCode) | ||||
|         if (it->gcode != Slic3r::ToolChangeCode) | ||||
|         { | ||||
|             // show "Edit" and "Delete" menu on OnRightUp()
 | ||||
|             m_show_edit_menu = true; | ||||
|  | @ -3471,14 +3480,14 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event) | |||
| 
 | ||||
| int DoubleSlider::get_extruder_for_tick(int tick) | ||||
| { | ||||
|     int default_initial_extruder = m_mode == mmMultiAsSingle ? m_only_extruder : 0; | ||||
|     int default_initial_extruder = m_mode == t_mode::MultiAsSingle ? m_only_extruder : 0; | ||||
|     if (m_ticks.empty()) | ||||
|         return default_initial_extruder; | ||||
|      | ||||
|     auto it = m_ticks.lower_bound(TICK_CODE{tick}); | ||||
|     while (it != m_ticks.begin()) { | ||||
|         --it; | ||||
|         if(it->gcode == Slic3r::ExtruderChangeCode) | ||||
|         if(it->gcode == Slic3r::ToolChangeCode) | ||||
|             return it->extruder; | ||||
|     } | ||||
| 
 | ||||
|  | @ -3487,7 +3496,7 @@ int DoubleSlider::get_extruder_for_tick(int tick) | |||
| 
 | ||||
| std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick) | ||||
| { | ||||
|     if (m_mode == mmMultiExtruder) | ||||
|     if (m_mode == t_mode::MultiExtruder) | ||||
|     { | ||||
|         // #ys_FIXME: get tool ordering from _correct_ place
 | ||||
|         const Slic3r::ToolOrdering& tool_ordering = Slic3r::GUI::wxGetApp().plater()->fff_print().get_tool_ordering(); | ||||
|  | @ -3508,7 +3517,7 @@ std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick) | |||
|         return used_extruders; | ||||
|     } | ||||
| 
 | ||||
|     const int default_initial_extruder = m_mode == mmMultiAsSingle ? std::max(m_only_extruder, 1) : 1; | ||||
|     const int default_initial_extruder = m_mode == t_mode::MultiAsSingle ? std::max(m_only_extruder, 1) : 1; | ||||
|     if (m_ticks.empty()) | ||||
|         return {default_initial_extruder}; | ||||
| 
 | ||||
|  | @ -3516,7 +3525,7 @@ std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick) | |||
|     auto it_start = m_ticks.lower_bound(TICK_CODE{tick}); | ||||
| 
 | ||||
|     auto it = it_start; | ||||
|     if (it == m_ticks.begin() && it->gcode == Slic3r::ExtruderChangeCode) { | ||||
|     if (it == m_ticks.begin() && it->gcode == Slic3r::ToolChangeCode) { | ||||
|         used_extruders.emplace(it->extruder); | ||||
|         if (tick < it->tick) | ||||
|             used_extruders.emplace(default_initial_extruder); | ||||
|  | @ -3524,7 +3533,7 @@ std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick) | |||
| 
 | ||||
|     while (it != m_ticks.begin()) { | ||||
|         --it; | ||||
|         if(it->gcode == Slic3r::ExtruderChangeCode) | ||||
|         if(it->gcode == Slic3r::ToolChangeCode) | ||||
|         { | ||||
|             used_extruders.emplace(it->extruder); | ||||
|             break; | ||||
|  | @ -3536,7 +3545,7 @@ std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick) | |||
| 
 | ||||
|     it = it_start; | ||||
|     while (it != m_ticks.end()) { | ||||
|         if(it->gcode == Slic3r::ExtruderChangeCode) | ||||
|         if(it->gcode == Slic3r::ToolChangeCode) | ||||
|             used_extruders.emplace(it->extruder); | ||||
|         ++it; | ||||
|     } | ||||
|  | @ -3554,7 +3563,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event) | |||
|     if (m_show_context_menu) { | ||||
|         wxMenu menu; | ||||
| 
 | ||||
|         if (m_mode == mmSingleExtruder) | ||||
|         if (m_mode == t_mode::SingleExtruder) | ||||
|             append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", | ||||
|                 [this](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode); }, "colorchange_add_m", &menu, | ||||
|                 [](){return true;}, this); | ||||
|  | @ -3703,7 +3712,7 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) | |||
| 
 | ||||
|     m_ticks.emplace(TICK_CODE{tick, code, extruder, color}); | ||||
| 
 | ||||
|     wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|     post_ticks_changed_event(code); | ||||
|     Refresh(); | ||||
|     Update(); | ||||
| } | ||||
|  | @ -3741,7 +3750,7 @@ void DoubleSlider::edit_tick() | |||
|         m_ticks.erase(it); | ||||
|         m_ticks.emplace(changed_tick); | ||||
| 
 | ||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|         post_ticks_changed_event(changed_tick.gcode); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -3754,9 +3763,9 @@ void DoubleSlider::change_extruder(int extruder) | |||
|     // if on this Y doesn't exist tick
 | ||||
|     if (m_ticks.find(TICK_CODE{tick}) == m_ticks.end()) | ||||
|     {         | ||||
|         m_ticks.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]}); | ||||
|         m_ticks.emplace(TICK_CODE{tick, Slic3r::ToolChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]}); | ||||
| 
 | ||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|         post_ticks_changed_event(Slic3r::ToolChangeCode); | ||||
|         Refresh(); | ||||
|         Update(); | ||||
|     } | ||||
|  | @ -3776,7 +3785,7 @@ void DoubleSlider::edit_extruder_sequence() | |||
| 
 | ||||
|     auto it = m_ticks.begin(); | ||||
|     while (it != m_ticks.end()) { | ||||
|         if (it->gcode == Slic3r::ExtruderChangeCode) | ||||
|         if (it->gcode == Slic3r::ToolChangeCode) | ||||
|             it = m_ticks.erase(it); | ||||
|         else | ||||
|             ++it; | ||||
|  | @ -3792,7 +3801,7 @@ void DoubleSlider::edit_extruder_sequence() | |||
|     while (tick <= m_max_value) | ||||
|     { | ||||
|         int cur_extruder = m_extruders_sequence.extruders[extruder]; | ||||
|         m_ticks.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder]}); | ||||
|         m_ticks.emplace(TICK_CODE{tick, Slic3r::ToolChangeCode, cur_extruder + 1, colors[cur_extruder]}); | ||||
| 
 | ||||
|         extruder++; | ||||
|         if (extruder == extr_cnt) | ||||
|  | @ -3811,6 +3820,42 @@ void DoubleSlider::edit_extruder_sequence() | |||
|             tick += m_extruders_sequence.interval_by_layers; | ||||
|     } | ||||
| 
 | ||||
|     post_ticks_changed_event(Slic3r::ToolChangeCode); | ||||
| } | ||||
| 
 | ||||
| void DoubleSlider::post_ticks_changed_event(const std::string& gcode /*= ""*/) | ||||
| { | ||||
|     if ( m_ticks_mode == m_mode || | ||||
|         (gcode != Slic3r::ColorChangeCode && gcode != Slic3r::ToolChangeCode) ) | ||||
|     { | ||||
|         wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (m_ticks_mode == t_mode::SingleExtruder && m_mode == t_mode::MultiAsSingle) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     if (m_ticks_mode == t_mode::SingleExtruder && m_mode == t_mode::MultiExtruder) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     if (m_ticks_mode == t_mode::MultiAsSingle && m_mode == t_mode::SingleExtruder) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     if (m_ticks_mode == t_mode::MultiAsSingle && m_mode == t_mode::MultiExtruder) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     if (m_ticks_mode == t_mode::MultiExtruder && m_mode == t_mode::SingleExtruder) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     if (m_ticks_mode == t_mode::MultiExtruder && m_mode == t_mode::MultiAsSingle) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -782,6 +782,8 @@ public: | |||
|         const wxString& name = wxEmptyString); | ||||
|     ~DoubleSlider() {} | ||||
| 
 | ||||
|     using t_mode = Slic3r::Model::CustomGCodeInfo::MODE; | ||||
| 
 | ||||
|     /* For exporting GCode in GCodeWriter is used XYZF_NUM(val) = PRECISION(val, 3) for XYZ values. 
 | ||||
|      * So, let use same value as a permissible error for layer height. | ||||
|      */ | ||||
|  | @ -805,37 +807,22 @@ public: | |||
|     // Set low and high slider position. If the span is non-empty, disable the "one layer" mode.
 | ||||
|     void SetSelectionSpan(const int lower_val, const int higher_val); | ||||
|     void SetMaxValue(const int max_value); | ||||
|     void SetKoefForLabels(const double koef) { | ||||
|         m_label_koef = koef; | ||||
|     } | ||||
|     void SetSliderValues(const std::vector<double>& values) { | ||||
|         m_values = values; | ||||
|     } | ||||
|     void SetKoefForLabels(const double koef)                { m_label_koef = koef; } | ||||
|     void SetSliderValues(const std::vector<double>& values) { m_values = values; } | ||||
|     void ChangeOneLayerLock(); | ||||
|     std::vector<Slic3r::Model::CustomGCode> GetTicksValues() const; | ||||
|     void SetTicksValues(const std::vector<Slic3r::Model::CustomGCode> &heights); | ||||
|     void EnableTickManipulation(bool enable = true) { | ||||
|         m_is_enabled_tick_manipulation = enable; | ||||
|     } | ||||
|     void DisableTickManipulation() { | ||||
|         EnableTickManipulation(false); | ||||
|     } | ||||
|     Slic3r::Model::CustomGCodeInfo  GetTicksValues() const; | ||||
|     void                            SetTicksValues(const Slic3r::Model::CustomGCodeInfo &custom_gcode_per_print_z); | ||||
|     void EnableTickManipulation(bool enable = true) { m_is_enabled_tick_manipulation = enable; } | ||||
|     void DisableTickManipulation()                  { EnableTickManipulation(false); } | ||||
| 
 | ||||
|     enum ManipulationMode { | ||||
|         mmSingleExtruder,   // single extruder printer preset is selected
 | ||||
|         mmMultiAsSingle,    // multiple extruder printer preset is selected, but 
 | ||||
|                             // this mode works just for Single extruder print 
 | ||||
|                             // (For all print from objects settings is used just one extruder) 
 | ||||
|         mmMultiExtruder     // multiple extruder printer preset is selected
 | ||||
|     }; | ||||
|     void SetManipulationMode(ManipulationMode mode) { m_mode = mode; } | ||||
|     ManipulationMode GetManipulationMode() const    { return m_mode; } | ||||
|     void    SetManipulationMode(t_mode mode)    { m_mode = mode; } | ||||
|     t_mode  GetManipulationMode() const         { return m_mode; } | ||||
| 
 | ||||
|     void SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, const int only_extruder) | ||||
|     { | ||||
|         m_mode = !is_one_extruder_printed_model ? mmMultiExtruder : | ||||
|                  only_extruder < 0              ? mmSingleExtruder : | ||||
|                                                   mmMultiAsSingle; | ||||
|         m_mode = !is_one_extruder_printed_model ? t_mode::MultiExtruder : | ||||
|                  only_extruder < 0              ? t_mode::SingleExtruder : | ||||
|                                                   t_mode::MultiAsSingle; | ||||
|         m_only_extruder = only_extruder; | ||||
|     } | ||||
| 
 | ||||
|  | @ -918,7 +905,7 @@ private: | |||
|     int         get_extruder_for_tick(int tick); | ||||
|     std::set<int>   get_used_extruders_for_tick(int tick); | ||||
| 
 | ||||
| 
 | ||||
|     void        post_ticks_changed_event(const std::string& gcode = ""); | ||||
|     void        append_change_extruder_menu_item(wxMenu*); | ||||
|     void        append_add_color_change_menu_item(wxMenu*); | ||||
| 
 | ||||
|  | @ -952,7 +939,7 @@ private: | |||
|     bool        m_show_edit_menu = false; | ||||
|     bool        m_edit_extruder_sequence = false; | ||||
|     bool        m_suppress_add_code = false; | ||||
|     ManipulationMode m_mode = mmSingleExtruder; | ||||
|     t_mode      m_mode = t_mode::SingleExtruder; | ||||
|     std::string m_custom_gcode = ""; | ||||
|     std::string m_pause_print_msg; | ||||
|     int         m_only_extruder = -1; | ||||
|  | @ -986,6 +973,7 @@ private: | |||
|     std::vector<wxPen*> m_segm_pens; | ||||
|     std::vector<double> m_values; | ||||
|     std::set<TICK_CODE> m_ticks; | ||||
|     t_mode              m_ticks_mode; | ||||
| 
 | ||||
| public: | ||||
|     struct ExtrudersSequence | ||||
|  |  | |||
 Enrico Turri
						Enrico Turri