From 1b8553c747ad5c0eb9bdba46d2b7c8003ef9ad5f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 20 Mar 2023 14:34:04 +0100 Subject: [PATCH 01/32] Reintroduced visualization of SLA supports and pad into 3D scene and gizmos Hollow and SLA support as it was in 2.5.0 --- src/slic3r/GUI/3DScene.cpp | 61 +++++++ src/slic3r/GUI/3DScene.hpp | 10 ++ src/slic3r/GUI/GLCanvas3D.cpp | 160 ++++++++++++++++++- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 9 ++ src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp | 67 ++++++-- src/slic3r/GUI/Gizmos/GLGizmoSlaBase.hpp | 4 + src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 7 +- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 97 +++++------ src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp | 4 +- 9 files changed, 337 insertions(+), 82 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index c25bff45de..843aa6a337 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -564,6 +564,67 @@ int GLVolumeCollection::load_wipe_tower_preview( return int(volumes.size() - 1); } +// Load SLA auxiliary GLVolumes (for support trees or pad). +// This function produces volumes for multiple instances in a single shot, +// as some object specific mesh conversions may be expensive. +void GLVolumeCollection::load_object_auxiliary( + const SLAPrintObject* print_object, + int obj_idx, + // pairs of + const std::vector>& instances, + SLAPrintObjectStep milestone, + // Timestamp of the last change of the milestone + size_t timestamp) +{ + if (print_object->get_mesh_to_print() == nullptr) + return; + const Transform3d mesh_trafo_inv = print_object->trafo().inverse(); + + auto add_volume = [this, &instances, timestamp](int obj_idx, int inst_idx, const ModelInstance& model_instance, SLAPrintObjectStep step, + const TriangleMesh& mesh, const ColorRGBA& color, std::optional convex_hull = std::nullopt) { + if (mesh.empty()) + return; + + GLVolume& v = *this->volumes.emplace_back(new GLVolume(color)); +#if ENABLE_SMOOTH_NORMALS + v.model.init_from(mesh, true); +#else + v.model.init_from(mesh); + v.model.set_color(color); + v.mesh_raycaster = std::make_unique(std::make_shared(mesh)); +#endif // ENABLE_SMOOTH_NORMALS + v.composite_id = GLVolume::CompositeID(obj_idx, -int(step), inst_idx); + v.geometry_id = std::pair(timestamp, model_instance.id().id); + if (convex_hull.has_value()) + v.set_convex_hull(*convex_hull); + v.is_modifier = false; + v.shader_outside_printer_detection_enabled = (step == slaposSupportTree); + v.set_instance_transformation(model_instance.get_transformation()); + }; + + // Get the support mesh. + TriangleMesh supports_mesh = print_object->support_mesh(); + if (!supports_mesh.empty()) { + supports_mesh.transform(mesh_trafo_inv); + TriangleMesh convex_hull = supports_mesh.convex_hull_3d(); + for (const std::pair& instance_idx : instances) { + const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; + add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposSupportTree, supports_mesh, GLVolume::SLA_SUPPORT_COLOR, convex_hull); + } + } + + // Get the pad mesh. + TriangleMesh pad_mesh = print_object->pad_mesh(); + if (!pad_mesh.empty()) { + pad_mesh.transform(mesh_trafo_inv); + TriangleMesh convex_hull = pad_mesh.convex_hull_3d(); + for (const std::pair& instance_idx : instances) { + const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; + add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposPad, pad_mesh, GLVolume::SLA_PAD_COLOR, convex_hull); + } + } +} + GLVolume* GLVolumeCollection::new_toolpath_volume(const ColorRGBA& rgba) { GLVolume* out = new_nontoolpath_volume(rgba); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 9791a0fafb..9095885fc8 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -430,6 +430,16 @@ public: float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width); #endif // ENABLE_OPENGL_ES + // Load SLA auxiliary GLVolumes (for support trees or pad). + void load_object_auxiliary( + const SLAPrintObject* print_object, + int obj_idx, + // pairs of + const std::vector>& instances, + SLAPrintObjectStep milestone, + // Timestamp of the last change of the milestone + size_t timestamp); + GLVolume* new_toolpath_volume(const ColorRGBA& rgba); GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba); // Render the volumes by OpenGL. diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1f2f668c32..ea79739c40 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1881,6 +1881,15 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re size_t volume_idx; }; + // SLA steps to pull the preview meshes for. + typedef std::array SLASteps; + SLASteps sla_steps = { slaposDrillHoles, slaposSupportTree, slaposPad }; + struct SLASupportState { + std::array::value> step; + }; + // State of the sla_steps for all SLAPrintObjects. + std::vector sla_support_state; + std::vector instance_ids_selected; std::vector map_glvolume_old_to_new(m_volumes.volumes.size(), size_t(-1)); std::vector deleted_volumes; @@ -1906,6 +1915,37 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } } + if (printer_technology == ptSLA) { + const SLAPrint* sla_print = this->sla_print(); +#ifndef NDEBUG + // Verify that the SLAPrint object is synchronized with m_model. + check_model_ids_equal(*m_model, sla_print->model()); +#endif // NDEBUG + sla_support_state.reserve(sla_print->objects().size()); + for (const SLAPrintObject* print_object : sla_print->objects()) { + SLASupportState state; + for (size_t istep = 0; istep < sla_steps.size(); ++istep) { + state.step[istep] = print_object->step_state_with_timestamp(sla_steps[istep]); + if (state.step[istep].state == PrintStateBase::State::Done) { + std::shared_ptr m = print_object->get_mesh_to_print(); + if (m == nullptr || m->empty()) + // Consider the DONE step without a valid mesh as invalid for the purpose + // of mesh visualization. + state.step[istep].state = PrintStateBase::State::Invalidated; + else { + for (const ModelInstance* model_instance : print_object->model_object()->instances) { + // Only the instances, which are currently printable, will have the SLA support structures kept. + // The instances outside the print bed will have the GLVolumes of their support structures released. + if (model_instance->is_printable()) + aux_volume_state.emplace_back(state.step[istep].timestamp, model_instance->id()); + } + } + } + } + sla_support_state.emplace_back(state); + } + } + std::sort(model_volume_state.begin(), model_volume_state.end(), model_volume_state_lower); std::sort(aux_volume_state.begin(), aux_volume_state.end(), model_volume_state_lower); // Release all ModelVolume based GLVolumes not found in the current Model. Find the GLVolume of a hollowed mesh. @@ -2020,6 +2060,118 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } } + if (printer_technology == ptSLA) { + size_t idx = 0; + const SLAPrint *sla_print = this->sla_print(); + std::vector shift_zs(m_model->objects.size(), 0); + double relative_correction_z = sla_print->relative_correction().z(); + if (relative_correction_z <= EPSILON) + relative_correction_z = 1.; + for (const SLAPrintObject *print_object : sla_print->objects()) { + SLASupportState &state = sla_support_state[idx ++]; + const ModelObject *model_object = print_object->model_object(); + // Find an index of the ModelObject + int object_idx; + // There may be new SLA volumes added to the scene for this print_object. + // Find the object index of this print_object in the Model::objects list. + auto it = std::find(sla_print->model().objects.begin(), sla_print->model().objects.end(), model_object); + assert(it != sla_print->model().objects.end()); + object_idx = it - sla_print->model().objects.begin(); + // Cache the Z offset to be applied to all volumes with this object_idx. + shift_zs[object_idx] = print_object->get_current_elevation() / relative_correction_z; + // Collect indices of this print_object's instances, for which the SLA support meshes are to be added to the scene. + // pairs of + std::vector> instances[std::tuple_size::value]; + for (size_t print_instance_idx = 0; print_instance_idx < print_object->instances().size(); ++ print_instance_idx) { + const SLAPrintObject::Instance &instance = print_object->instances()[print_instance_idx]; + // Find index of ModelInstance corresponding to this SLAPrintObject::Instance. + auto it = std::find_if(model_object->instances.begin(), model_object->instances.end(), + [&instance](const ModelInstance *mi) { return mi->id() == instance.instance_id; }); + assert(it != model_object->instances.end()); + int instance_idx = it - model_object->instances.begin(); + for (size_t istep = 0; istep < sla_steps.size(); ++istep) { + if (sla_steps[istep] == slaposDrillHoles) { + // Hollowing is a special case, where the mesh from the backend is being loaded into the 1st volume of an instance, + // not into its own GLVolume. + // There shall always be such a GLVolume allocated. + ModelVolumeState key(model_object->volumes.front()->id(), instance.instance_id); + auto it = std::lower_bound(model_volume_state.begin(), model_volume_state.end(), key, model_volume_state_lower); + assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id); + assert(!it->new_geometry()); + GLVolume& volume = *m_volumes.volumes[it->volume_idx]; + if (!volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) { + // The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen. + volume.model.reset(); + if (state.step[istep].state == PrintStateBase::State::Done) { + std::shared_ptr m = print_object->get_mesh_to_print(); + assert(m != nullptr && !m->empty()); + TriangleMesh mesh(*m); + // sla_trafo does not contain volume trafo. To get a mesh to create + // a new volume from, we have to apply vol trafo inverse separately. + const ModelObject& mo = *m_model->objects[volume.object_idx()]; + Transform3d trafo = sla_print->sla_trafo(mo) * mo.volumes.front()->get_transformation().get_matrix(); + mesh.transform(trafo.inverse()); +#if ENABLE_SMOOTH_NORMALS + volume.model.init_from(mesh, true); +#else + volume.model.init_from(mesh); + volume.mesh_raycaster = std::make_unique(std::make_shared(mesh)); +#endif // ENABLE_SMOOTH_NORMALS + } + else { + // Reload the original volume. +#if ENABLE_SMOOTH_NORMALS + volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true); +#else + const TriangleMesh& new_mesh = m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(); + volume.model.init_from(new_mesh); + volume.mesh_raycaster = std::make_unique(std::make_shared(new_mesh)); +#endif // ENABLE_SMOOTH_NORMALS + } + } + //FIXME it is an ugly hack to write the timestamp into the "offsets" field to not have to add another member variable + // to the GLVolume. We should refactor GLVolume significantly, so that the GLVolume will not contain member variables + // of various concenrs (model vs. 3D print path). + volume.offsets = { state.step[istep].timestamp }; + } + else if (state.step[istep].state == PrintStateBase::State::Done) { + // Check whether there is an existing auxiliary volume to be updated, or a new auxiliary volume to be created. + ModelVolumeState key(state.step[istep].timestamp, instance.instance_id.id); + auto it = std::lower_bound(aux_volume_state.begin(), aux_volume_state.end(), key, model_volume_state_lower); + assert(it != aux_volume_state.end() && it->geometry_id == key.geometry_id); + if (it->new_geometry()) { + // This can be an SLA support structure that should not be rendered (in case someone used undo + // to revert to before it was generated). If that's the case, we should not generate anything. + if (model_object->sla_points_status != sla::PointsStatus::NoPoints) + instances[istep].emplace_back(std::pair(instance_idx, print_instance_idx)); + else + shift_zs[object_idx] = 0.; + } + else { + // Recycling an old GLVolume. Update the Object/Instance indices into the current Model. + m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx); + m_volumes.volumes[it->volume_idx]->set_instance_transformation(model_object->instances[instance_idx]->get_transformation()); + } + } + } + } + + for (size_t istep = 0; istep < sla_steps.size(); ++istep) { + if (!instances[istep].empty()) + m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp); + } + } + + // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed + for (GLVolume* volume : m_volumes.volumes) { + if (volume->object_idx() < (int)m_model->objects.size() && m_model->objects[volume->object_idx()]->instances[volume->instance_idx()]->is_printable()) { + const SLAPrintObject* po = sla_print->objects()[volume->object_idx()]; + float zoffs = po->get_current_elevation() / sla_print->relative_correction().z(); + volume->set_sla_shift_z(zoffs); + } + } + } + if (printer_technology == ptFFF && m_config->has("nozzle_diameter")) { // Should the wipe tower be visualized ? unsigned int extruders_count = (unsigned int)dynamic_cast(m_config->option("nozzle_diameter"))->values.size(); @@ -6805,9 +6957,9 @@ void GLCanvas3D::_load_sla_shells() // adds objects' volumes for (const SLAPrintObject* obj : print->objects()) { unsigned int initial_volumes_count = (unsigned int)m_volumes.volumes.size(); - for (const SLAPrintObject::Instance& instance : obj->instances()) { - std::shared_ptr m = obj->get_mesh_to_print(); - if (m && !m->empty()) { + std::shared_ptr m = obj->get_mesh_to_print(); + if (m && !m->empty()) { + for (const SLAPrintObject::Instance& instance : obj->instances()) { add_volume(*obj, 0, instance, *m, GLVolume::MODEL_COLOR[0], true); // Set the extruder_id and volume_id to achieve the same color as in the 3D scene when // through the update_volumes_colors_by_extruder() call. @@ -6818,7 +6970,7 @@ void GLCanvas3D::_load_sla_shells() add_volume(*obj, -int(slaposPad), instance, pad_mesh, GLVolume::SLA_PAD_COLOR, false); } } - double shift_z = obj->get_current_elevation(); + const double shift_z = obj->get_current_elevation(); for (unsigned int i = initial_volumes_count; i < m_volumes.volumes.size(); ++ i) { // apply shift z m_volumes.volumes[i]->set_sla_shift_z(shift_z); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index d04a9cf2fd..85e9d16cee 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -101,6 +101,7 @@ void GLGizmoHollow::on_render() m_selection_rectangle.render(m_parent); m_c->object_clipper()->render_cut(); + m_c->supports_clipper()->render_cut(); glsafe(::glDisable(GL_BLEND)); } @@ -772,6 +773,14 @@ RENDER_AGAIN: if (m_imgui->slider_float("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f")) m_c->object_clipper()->set_position_by_ratio(clp_dist, true); + // make sure supports are shown/hidden as appropriate + ImGui::Separator(); + bool show_sups = are_sla_supports_shown(); + if (m_imgui->checkbox(m_desc["show_supports"], show_sups)) { + show_sla_supports(show_sups); + force_refresh = true; + } + m_imgui->disabled_end(); m_imgui->end(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp index 3ac438902d..dac76b3916 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp @@ -30,7 +30,8 @@ CommonGizmosDataID GLGizmoSlaBase::on_get_requirements() const int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::InstancesHider) | int(CommonGizmosDataID::Raycaster) - | int(CommonGizmosDataID::ObjectClipper)); + | int(CommonGizmosDataID::ObjectClipper) + | int(CommonGizmosDataID::SupportsClipper)); } void GLGizmoSlaBase::update_volumes() @@ -50,27 +51,54 @@ void GLGizmoSlaBase::update_volumes() TriangleMesh backend_mesh; std::shared_ptr preview_mesh_ptr = po->get_mesh_to_print(); - if (preview_mesh_ptr) - backend_mesh = TriangleMesh{*preview_mesh_ptr}; + if (preview_mesh_ptr != nullptr) + backend_mesh = TriangleMesh(*preview_mesh_ptr); if (!backend_mesh.empty()) { - // The backend has generated a valid mesh. Use it - backend_mesh.transform(po->trafo().inverse()); - m_volumes.volumes.emplace_back(new GLVolume()); - GLVolume* new_volume = m_volumes.volumes.back(); - new_volume->model.init_from(backend_mesh); - new_volume->set_instance_transformation(po->model_object()->instances[m_parent.get_selection().get_instance_idx()]->get_transformation()); - new_volume->set_sla_shift_z(po->get_current_elevation()); - new_volume->mesh_raycaster = std::make_unique(backend_mesh); auto last_comp_step = static_cast(po->last_completed_step()); if (last_comp_step == slaposCount) last_comp_step = -1; m_input_enabled = last_comp_step >= m_min_sla_print_object_step; - if (m_input_enabled) - new_volume->selected = true; // to set the proper color - else - new_volume->set_color(DISABLED_COLOR); + + const int object_idx = m_parent.get_selection().get_object_idx(); + const int instance_idx = m_parent.get_selection().get_instance_idx(); + const Geometry::Transformation& inst_trafo = po->model_object()->instances[instance_idx]->get_transformation(); + const double current_elevation = po->get_current_elevation(); + + auto add_volume = [this, object_idx, instance_idx, &inst_trafo, current_elevation](const TriangleMesh& mesh, int volume_id, bool add_mesh_raycaster = false) { + GLVolume* volume = m_volumes.volumes.emplace_back(new GLVolume()); + volume->model.init_from(mesh); + volume->set_instance_transformation(inst_trafo); + volume->set_sla_shift_z(current_elevation); + if (add_mesh_raycaster) + volume->mesh_raycaster = std::make_unique(mesh); + if (m_input_enabled) + volume->selected = true; // to set the proper color + else + volume->set_color(DISABLED_COLOR); + volume->composite_id = GLVolume::CompositeID(object_idx, volume_id, instance_idx); + }; + + const Transform3d po_trafo_inverse = po->trafo().inverse(); + + // main mesh + backend_mesh.transform(po_trafo_inverse); + add_volume(backend_mesh, 0, true); + + // supports mesh + TriangleMesh supports_mesh = po->support_mesh(); + if (!supports_mesh.empty()) { + supports_mesh.transform(po_trafo_inverse); + add_volume(supports_mesh, -int(slaposSupportTree)); + } + + // pad mesh + TriangleMesh pad_mesh = po->pad_mesh(); + if (!pad_mesh.empty()) { + pad_mesh.transform(po_trafo_inverse); + add_volume(pad_mesh, -int(slaposPad)); + } } if (m_volumes.volumes.empty()) { @@ -110,7 +138,11 @@ void GLGizmoSlaBase::render_volumes() clipping_plane.set_normal(-clipping_plane.get_normal()); m_volumes.set_clipping_plane(clipping_plane.get_data()); - m_volumes.render(GLVolumeCollection::ERenderType::Opaque, false, camera.get_view_matrix(), camera.get_projection_matrix()); + for (GLVolume* v : m_volumes.volumes) { + v->is_active = m_show_sla_supports || (!v->is_sla_pad() && !v->is_sla_support()); + } + + m_volumes.render(GLVolumeCollection::ERenderType::Opaque, true, camera.get_view_matrix(), camera.get_projection_matrix()); shader->stop_using(); } @@ -119,7 +151,8 @@ void GLGizmoSlaBase::register_volume_raycasters_for_picking() { for (size_t i = 0; i < m_volumes.volumes.size(); ++i) { const GLVolume* v = m_volumes.volumes[i]; - m_volume_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, VOLUME_RAYCASTERS_BASE_ID + (int)i, *v->mesh_raycaster, v->world_matrix())); + if (!v->is_sla_pad() && !v->is_sla_support()) + m_volume_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, VOLUME_RAYCASTERS_BASE_ID + (int)i, *v->mesh_raycaster, v->world_matrix())); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.hpp index 4384775988..acda5a8a16 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.hpp @@ -40,11 +40,15 @@ protected: bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair& pos_and_normal); + bool are_sla_supports_shown() const { return m_show_sla_supports; } + void show_sla_supports(bool show) { m_show_sla_supports = show; } + const GLVolumeCollection &volumes() const { return m_volumes; } private: GLVolumeCollection m_volumes; bool m_input_enabled{ false }; + bool m_show_sla_supports{ false }; int m_min_sla_print_object_step{ -1 }; std::vector> m_volume_raycasters; }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 4d76dfb04b..073d3fa293 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -25,8 +25,10 @@ namespace Slic3r { namespace GUI { GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) - : GLGizmoSlaBase(parent, icon_filename, sprite_id, slaposDrillHoles) -{} +: GLGizmoSlaBase(parent, icon_filename, sprite_id, slaposDrillHoles) +{ + show_sla_supports(true); +} bool GLGizmoSlaSupports::on_init() { @@ -127,6 +129,7 @@ void GLGizmoSlaSupports::on_render() m_selection_rectangle.render(m_parent); m_c->object_clipper()->render_cut(); + m_c->supports_clipper()->render_cut(); glsafe(::glDisable(GL_BLEND)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index a8dc16c558..1e5bd7955b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -453,83 +453,66 @@ void SupportsClipper::on_update() if (! mo || ! is_sla) return; - const GLCanvas3D* canvas = get_pool()->get_canvas(); - const PrintObjects& print_objects = canvas->sla_print()->objects(); - const SLAPrintObject* print_object = (m_print_object_idx >= 0 && m_print_object_idx < int(print_objects.size())) - ? print_objects[m_print_object_idx] - : nullptr; + const SLAPrintObject* print_object = get_pool()->selection_info()->print_object(); + if (print_object == nullptr) + return; - // Find the respective SLAPrintObject. - if (m_print_object_idx < 0 || m_print_objects_count != int(print_objects.size())) { - m_print_objects_count = print_objects.size(); - m_print_object_idx = -1; - for (const SLAPrintObject* po : print_objects) { - ++m_print_object_idx; - if (po->model_object()->id() == mo->id()) { - print_object = po; - break; - } - } + if (print_object->get_mesh_to_print() == nullptr) { + // The object has been not sliced yet. We better dump the cached data. + m_supports_clipper.reset(); + m_pad_clipper.reset(); + return; } - if (print_object - && print_object->is_step_done(slaposSupportTree) - && ! print_object->support_mesh().empty()) - { - // If the supports are already calculated, save the timestamp of the respective step - // so we can later tell they were recalculated. - size_t timestamp = print_object->step_state_with_timestamp(slaposSupportTree).timestamp; - if (! m_clipper || timestamp != m_old_timestamp) { - // The timestamp has changed. - m_clipper.reset(new MeshClipper); - // The mesh should already have the shared vertices calculated. - m_clipper->set_mesh(print_object->support_mesh().its); - m_old_timestamp = timestamp; - } + const TriangleMesh& support_mesh = print_object->support_mesh(); + if (support_mesh.empty()) { + // The supports are not available yet. We better dump the cached data. + m_supports_clipper.reset(); + } + else { + m_supports_clipper.reset(new MeshClipper); + m_supports_clipper->set_mesh(support_mesh.its); + } + + const TriangleMesh& pad_mesh = print_object->pad_mesh(); + if (pad_mesh.empty()) { + // The supports are not available yet. We better dump the cached data. + m_pad_clipper.reset(); + } + else { + m_pad_clipper.reset(new MeshClipper); + m_pad_clipper->set_mesh(pad_mesh.its); } - else - // The supports are not valid. We better dump the cached data. - m_clipper.reset(); } void SupportsClipper::on_release() { - m_clipper.reset(); - m_old_timestamp = 0; + m_supports_clipper.reset(); + m_pad_clipper.reset(); m_print_object_idx = -1; } void SupportsClipper::render_cut() const { const CommonGizmosDataObjects::ObjectClipper* ocl = get_pool()->object_clipper(); - if (ocl->get_position() == 0. - || ! m_clipper) + if (ocl->get_position() == 0.) return; const SelectionInfo* sel_info = get_pool()->selection_info(); - const ModelObject* mo = sel_info->model_object(); - const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation(); - //Geometry::Transformation vol_trafo = mo->volumes.front()->get_transformation(); - Geometry::Transformation trafo = inst_trafo;// * vol_trafo; - trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift())); + const Geometry::Transformation inst_trafo = sel_info->model_object()->instances[sel_info->get_active_instance()]->get_transformation(); + if (m_supports_clipper != nullptr) { + m_supports_clipper->set_plane(*ocl->get_clipping_plane()); + m_supports_clipper->set_transformation(inst_trafo); + m_supports_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f }); + } - // Get transformation of supports - Geometry::Transformation supports_trafo = trafo; - supports_trafo.set_scaling_factor(Vec3d::Ones()); - supports_trafo.set_offset(Vec3d(trafo.get_offset()(0), trafo.get_offset()(1), sel_info->get_sla_shift())); - supports_trafo.set_rotation(Vec3d(0., 0., trafo.get_rotation()(2))); - // I don't know why, but following seems to be correct. - supports_trafo.set_mirror(Vec3d(trafo.get_mirror()(0) * trafo.get_mirror()(1) * trafo.get_mirror()(2), - 1, - 1.)); - - m_clipper->set_plane(*ocl->get_clipping_plane()); - m_clipper->set_transformation(supports_trafo); - - m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f }); - m_clipper->render_contour({ 1.f, 1.f, 1.f, 1.f }); + if (m_pad_clipper != nullptr) { + m_pad_clipper->set_plane(*ocl->get_clipping_plane()); + m_pad_clipper->set_transformation(inst_trafo); + m_pad_clipper->render_cut({ 0.6f, 0.f, 0.222f, 1.0f }); + } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp index 01b888be0a..785c660766 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.hpp @@ -293,10 +293,10 @@ protected: void on_release() override; private: - size_t m_old_timestamp = 0; int m_print_object_idx = -1; int m_print_objects_count = 0; - std::unique_ptr m_clipper; + std::unique_ptr m_supports_clipper; + std::unique_ptr m_pad_clipper; }; } // namespace CommonGizmosDataObjects From 9d156463b174b0b18b3aa2fe029bd9668fa306c6 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Mar 2023 14:43:14 +0100 Subject: [PATCH 02/32] Fixed crash when rotating a part after slicing with sla printer --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ea79739c40..743b4504fe 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3766,7 +3766,7 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); #endif // ENABLE_WORLD_COORDINATE } - else if (selection_mode == Selection::Volume) { + else if (selection_mode == Selection::Volume && volume_idx >= 0) { #if ENABLE_WORLD_COORDINATE model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); #else From 37edec974cb85fe7f694d523f000adda86d8d61b Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Mar 2023 15:33:27 +0100 Subject: [PATCH 03/32] Gizmo Hollow - Show clipped supports only when the supports are visible --- src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp | 3 ++- src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 85e9d16cee..89e0809fdf 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -101,7 +101,8 @@ void GLGizmoHollow::on_render() m_selection_rectangle.render(m_parent); m_c->object_clipper()->render_cut(); - m_c->supports_clipper()->render_cut(); + if (are_sla_supports_shown()) + m_c->supports_clipper()->render_cut(); glsafe(::glDisable(GL_BLEND)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp index dac76b3916..348fa5ca75 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaBase.cpp @@ -144,7 +144,6 @@ void GLGizmoSlaBase::render_volumes() m_volumes.render(GLVolumeCollection::ERenderType::Opaque, true, camera.get_view_matrix(), camera.get_projection_matrix()); shader->stop_using(); - } void GLGizmoSlaBase::register_volume_raycasters_for_picking() From c251122e8993ed5aebc51ad1106cc790bc6dc8fd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 22 Mar 2023 09:41:30 +0100 Subject: [PATCH 04/32] Fixed SupportsClipper::render_cut() method --- src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 1e5bd7955b..debb225358 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -453,18 +453,18 @@ void SupportsClipper::on_update() if (! mo || ! is_sla) return; - const SLAPrintObject* print_object = get_pool()->selection_info()->print_object(); - if (print_object == nullptr) + const SLAPrintObject* po = get_pool()->selection_info()->print_object(); + if (po == nullptr) return; - if (print_object->get_mesh_to_print() == nullptr) { + if (po->get_mesh_to_print() == nullptr) { // The object has been not sliced yet. We better dump the cached data. m_supports_clipper.reset(); m_pad_clipper.reset(); return; } - const TriangleMesh& support_mesh = print_object->support_mesh(); + const TriangleMesh& support_mesh = po->support_mesh(); if (support_mesh.empty()) { // The supports are not available yet. We better dump the cached data. m_supports_clipper.reset(); @@ -474,7 +474,7 @@ void SupportsClipper::on_update() m_supports_clipper->set_mesh(support_mesh.its); } - const TriangleMesh& pad_mesh = print_object->pad_mesh(); + const TriangleMesh& pad_mesh = po->pad_mesh(); if (pad_mesh.empty()) { // The supports are not available yet. We better dump the cached data. m_pad_clipper.reset(); @@ -499,8 +499,16 @@ void SupportsClipper::render_cut() const if (ocl->get_position() == 0.) return; + const SLAPrintObject* po = get_pool()->selection_info()->print_object(); + if (po == nullptr) + return; + + Geometry::Transformation po_trafo(po->trafo()); + const SelectionInfo* sel_info = get_pool()->selection_info(); - const Geometry::Transformation inst_trafo = sel_info->model_object()->instances[sel_info->get_active_instance()]->get_transformation(); + Geometry::Transformation inst_trafo = sel_info->model_object()->instances[sel_info->get_active_instance()]->get_transformation(); + inst_trafo = Geometry::Transformation(inst_trafo.get_matrix() * po_trafo.get_matrix().inverse()); + inst_trafo.set_offset(inst_trafo.get_offset() + Vec3d(0.0, 0.0, sel_info->get_sla_shift())); if (m_supports_clipper != nullptr) { m_supports_clipper->set_plane(*ocl->get_clipping_plane()); From e1c289f51ae51e4fcdeae8c4a68090959497e17f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 22 Mar 2023 11:00:04 +0100 Subject: [PATCH 05/32] Fixed GLCanvas3D::reload_scene() method to avoid adding volumes coming from the sla backend --- src/slic3r/GUI/GLCanvas3D.cpp | 46 +---------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 743b4504fe..a898d08fcf 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2090,51 +2090,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re assert(it != model_object->instances.end()); int instance_idx = it - model_object->instances.begin(); for (size_t istep = 0; istep < sla_steps.size(); ++istep) { - if (sla_steps[istep] == slaposDrillHoles) { - // Hollowing is a special case, where the mesh from the backend is being loaded into the 1st volume of an instance, - // not into its own GLVolume. - // There shall always be such a GLVolume allocated. - ModelVolumeState key(model_object->volumes.front()->id(), instance.instance_id); - auto it = std::lower_bound(model_volume_state.begin(), model_volume_state.end(), key, model_volume_state_lower); - assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id); - assert(!it->new_geometry()); - GLVolume& volume = *m_volumes.volumes[it->volume_idx]; - if (!volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) { - // The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen. - volume.model.reset(); - if (state.step[istep].state == PrintStateBase::State::Done) { - std::shared_ptr m = print_object->get_mesh_to_print(); - assert(m != nullptr && !m->empty()); - TriangleMesh mesh(*m); - // sla_trafo does not contain volume trafo. To get a mesh to create - // a new volume from, we have to apply vol trafo inverse separately. - const ModelObject& mo = *m_model->objects[volume.object_idx()]; - Transform3d trafo = sla_print->sla_trafo(mo) * mo.volumes.front()->get_transformation().get_matrix(); - mesh.transform(trafo.inverse()); -#if ENABLE_SMOOTH_NORMALS - volume.model.init_from(mesh, true); -#else - volume.model.init_from(mesh); - volume.mesh_raycaster = std::make_unique(std::make_shared(mesh)); -#endif // ENABLE_SMOOTH_NORMALS - } - else { - // Reload the original volume. -#if ENABLE_SMOOTH_NORMALS - volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true); -#else - const TriangleMesh& new_mesh = m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(); - volume.model.init_from(new_mesh); - volume.mesh_raycaster = std::make_unique(std::make_shared(new_mesh)); -#endif // ENABLE_SMOOTH_NORMALS - } - } - //FIXME it is an ugly hack to write the timestamp into the "offsets" field to not have to add another member variable - // to the GLVolume. We should refactor GLVolume significantly, so that the GLVolume will not contain member variables - // of various concenrs (model vs. 3D print path). - volume.offsets = { state.step[istep].timestamp }; - } - else if (state.step[istep].state == PrintStateBase::State::Done) { + if (state.step[istep].state == PrintStateBase::State::Done) { // Check whether there is an existing auxiliary volume to be updated, or a new auxiliary volume to be created. ModelVolumeState key(state.step[istep].timestamp, instance.instance_id.id); auto it = std::lower_bound(aux_volume_state.begin(), aux_volume_state.end(), key, model_volume_state_lower); From 760f74ce6a2cb458f52fe693afd247b69a0e247e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 22 Mar 2023 12:36:32 +0100 Subject: [PATCH 06/32] CutGizmo: Respect to the SLA shift --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index e9b6fa6946..5c18e9e968 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -876,6 +876,7 @@ void GLGizmoCut3D::on_set_state() } m_selected.clear(); m_parent.set_use_color_clip_plane(false); + m_c->selection_info()->set_use_shift(false); } } @@ -1239,7 +1240,10 @@ BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center, { const Selection& selection = m_parent.get_selection(); - const Vec3d& instance_offset = selection.get_first_volume()->get_instance_offset(); + const auto first_volume = selection.get_first_volume(); + Vec3d instance_offset = first_volume->get_instance_offset(); + instance_offset[Z] += first_volume->get_sla_shift_z(); + const auto cut_matrix = Transform3d::Identity() * rotation_m.inverse() * translation_transform(instance_offset - plane_center); const Selection::IndicesList& idxs = selection.get_volume_idxs(); @@ -1357,6 +1361,12 @@ void GLGizmoCut3D::render_clipper_cut() void GLGizmoCut3D::on_render() { + if (m_state == On) { + // This gizmo is showing the object elevated. Tell the common + // SelectionInfo object to lie about the actual shift. + m_c->selection_info()->set_use_shift(true); + } + update_clipper(); init_picking_models(); From 6b1c9119bed3e88534beeebbf30870b02fe0d157 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 15 Feb 2023 16:27:03 +0100 Subject: [PATCH 07/32] Add code to extract sla supports outline for arrangement Add functionality to libnest to support on_packed handler for all items. Use it to swap arrange polygon from envelope to core poly after packing was succesful. Solving brim issue by offset adjustments of arrange polygons Only in sla yet --- src/libnest2d/include/libnest2d/nester.hpp | 18 +++++ .../include/libnest2d/placers/nfpplacer.hpp | 1 + src/libslic3r/Arrange.cpp | 4 ++ src/libslic3r/Arrange.hpp | 2 +- src/slic3r/GUI/Jobs/ArrangeJob.cpp | 68 ++++++++++++++++++- src/slic3r/GUI/Jobs/ArrangeJob.hpp | 2 + 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/libnest2d/include/libnest2d/nester.hpp b/src/libnest2d/include/libnest2d/nester.hpp index 52c738a4c1..78da28759c 100644 --- a/src/libnest2d/include/libnest2d/nester.hpp +++ b/src/libnest2d/include/libnest2d/nester.hpp @@ -70,6 +70,7 @@ class _Item { int binid_{BIN_ID_UNSET}, priority_{0}; bool fixed_{false}; + std::function on_packed_; public: @@ -205,6 +206,23 @@ public: sl::vertex(sh_, idx) = v; } + void setShape(RawShape rsh) + { + sh_ = std::move(rsh); + invalidateCache(); + } + + void setOnPackedFn(std::function onpackedfn) + { + on_packed_ = onpackedfn; + } + + void onPacked() + { + if (on_packed_) + on_packed_(*this); + } + /** * @brief Calculate the shape area. * diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index a17d549822..0ef0929e16 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -901,6 +901,7 @@ public: if(can_pack) { ret = PackResult(item); + item.onPacked(); merged_pile_ = nfp::merge(merged_pile_, item.transformedShape()); } else { ret = PackResult(best_overfit); diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 31751ab322..b3293e17f2 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -583,8 +583,12 @@ static void process_arrangeable(const ArrangePolygon &arrpoly, outp.emplace_back(std::move(p)); outp.back().rotation(rotation); outp.back().translation({offs.x(), offs.y()}); + outp.back().inflate(arrpoly.inflation); outp.back().binId(arrpoly.bed_idx); outp.back().priority(arrpoly.priority); + outp.back().setOnPackedFn([&arrpoly](Item &itm){ + itm.inflate(-arrpoly.inflation); + }); } template auto call_with_bed(const Points &bed, Fn &&fn) diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index 6d4001a50c..4ed00668c9 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -71,7 +71,7 @@ static const constexpr int UNARRANGED = -1; /// polygon belongs: UNARRANGED means no place for the polygon /// (also the initial state before arrange), 0..N means the index of the bed. /// Zero is the physical bed, larger than zero means a virtual bed. -struct ArrangePolygon { +struct ArrangePolygon { ExPolygon poly; /// The 2D silhouette to be arranged Vec2crd translation{0, 0}; /// The translation of the poly double rotation{0.0}; /// The rotation of the poly in radians diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 4595ae2544..72a938ab33 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -2,6 +2,8 @@ #include "libslic3r/BuildVolume.hpp" #include "libslic3r/Model.hpp" +#include "libslic3r/SLAPrint.hpp" +#include "libslic3r/Geometry/ConvexHull.hpp" #include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" @@ -11,6 +13,7 @@ #include "slic3r/GUI/NotificationManager.hpp" #include "slic3r/GUI/format.hpp" + #include "libnest2d/common.hpp" #include @@ -76,6 +79,7 @@ void ArrangeJob::clear_input() m_selected.reserve(count + 1 /* for optional wti */); m_unselected.reserve(count + 1 /* for optional wti */); m_unprintable.reserve(cunprint /* for optional wti */); + m_min_inflation = 0; } void ArrangeJob::prepare_all() { @@ -145,6 +149,50 @@ void ArrangeJob::prepare_selected() { for (auto &p : m_unselected) p.translation(X) -= p.bed_idx * stride; } +static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret, + const SLAPrintObject &po, + const ModelInstance &inst, + coord_t min_infl) +{ + auto laststep = po.last_completed_step(); + + if (laststep < slaposCount && laststep > slaposSupportTree) { + auto omesh = po.get_mesh_to_print(); + auto &smesh = po.support_mesh(); + + Vec3d rotation = inst.get_rotation(); + rotation.z() = 0.; + Transform3f trafo_instance = + Geometry::assemble_transform(inst.get_offset().z() * Vec3d::UnitZ(), + rotation, + inst.get_scaling_factor(), + inst.get_mirror()).cast(); + + trafo_instance = trafo_instance * po.trafo().cast().inverse(); + + auto polys = reserve_vector(3); + auto zlvl = -po.get_elevation(); + + if (omesh) { + polys.emplace_back(its_convex_hull_2d_above(*omesh, trafo_instance, zlvl)); + ret.poly.contour = polys.back(); + ret.poly.holes = {}; + } + + polys.emplace_back(its_convex_hull_2d_above(smesh.its, trafo_instance, zlvl)); + ret.poly.contour = Geometry::convex_hull(polys); + ret.poly.holes = {}; + + // The 1.1 multiplier is a safety gap, as the offset might be bigger + // in sharp edges of a polygon, depending on clipper's offset algorithm + coord_t infl = 1.1 * scaled(po.config().pad_brim_size.getFloat() + + po.config().pad_around_object.getBool() * + po.config().pad_object_gap.getFloat()); + + ret.inflation = std::max(infl, min_infl); + } +} + arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi) { arrangement::ArrangePolygon ap = get_arrange_poly(mi, m_plater); @@ -156,12 +204,28 @@ arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi) m_unarranged.emplace_back(mi); }; + if (m_plater->printer_technology() == ptSLA) { + auto obj_id = mi->get_object()->id(); + const SLAPrintObject *po = + m_plater->sla_print().get_print_object_by_model_object_id(obj_id); + + if (po) { + update_arrangepoly_slaprint(ap, *po, *mi, m_min_inflation); + m_min_inflation = std::max(m_min_inflation, ap.inflation); + } + } else { + // TODO: get fff supports outline + } + return ap; } void ArrangeJob::prepare() { wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all(); + for (auto &ap : m_selected) { + ap.inflation = m_min_inflation; + } } void ArrangeJob::process(Ctl &ctl) @@ -286,7 +350,9 @@ template<> arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, const Plater * plater) { - return get_arrange_poly(PtrWrapper{inst}, plater); + auto ap = get_arrange_poly(PtrWrapper{inst}, plater); + + return ap; } arrangement::ArrangeParams get_arrange_params(Plater *p) diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index 106cc57ddf..4b75868a03 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -21,6 +21,8 @@ class ArrangeJob : public Job ArrangePolygons m_selected, m_unselected, m_unprintable; std::vector m_unarranged; + coord_t m_min_inflation = 0; + Plater *m_plater; // clear m_selected and m_unselected, reserve space for next usage From e585fd22218f4679d4ba86fbfbb0b63504854d58 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Mar 2023 10:16:13 +0100 Subject: [PATCH 08/32] Fixed duplication of auxiliary volumes when GLCanvas3D::reload_scene() is called for SLA printers --- src/slic3r/GUI/3DScene.cpp | 32 ++++++++++++++++++-------------- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 843aa6a337..f8b41da8a3 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -603,24 +603,28 @@ void GLVolumeCollection::load_object_auxiliary( }; // Get the support mesh. - TriangleMesh supports_mesh = print_object->support_mesh(); - if (!supports_mesh.empty()) { - supports_mesh.transform(mesh_trafo_inv); - TriangleMesh convex_hull = supports_mesh.convex_hull_3d(); - for (const std::pair& instance_idx : instances) { - const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; - add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposSupportTree, supports_mesh, GLVolume::SLA_SUPPORT_COLOR, convex_hull); + if (milestone == SLAPrintObjectStep::slaposSupportTree) { + TriangleMesh supports_mesh = print_object->support_mesh(); + if (!supports_mesh.empty()) { + supports_mesh.transform(mesh_trafo_inv); + TriangleMesh convex_hull = supports_mesh.convex_hull_3d(); + for (const std::pair& instance_idx : instances) { + const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; + add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposSupportTree, supports_mesh, GLVolume::SLA_SUPPORT_COLOR, convex_hull); + } } } // Get the pad mesh. - TriangleMesh pad_mesh = print_object->pad_mesh(); - if (!pad_mesh.empty()) { - pad_mesh.transform(mesh_trafo_inv); - TriangleMesh convex_hull = pad_mesh.convex_hull_3d(); - for (const std::pair& instance_idx : instances) { - const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; - add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposPad, pad_mesh, GLVolume::SLA_PAD_COLOR, convex_hull); + if (milestone == SLAPrintObjectStep::slaposPad) { + TriangleMesh pad_mesh = print_object->pad_mesh(); + if (!pad_mesh.empty()) { + pad_mesh.transform(mesh_trafo_inv); + TriangleMesh convex_hull = pad_mesh.convex_hull_3d(); + for (const std::pair& instance_idx : instances) { + const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first]; + add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposPad, pad_mesh, GLVolume::SLA_PAD_COLOR, convex_hull); + } } } } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e6b23c4b8f..ad1c8fe03b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2162,7 +2162,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re } update_volumes_colors_by_extruder(); - // Update selection indices based on the old/new GLVolumeCollection. + // Update selection indices based on the old/new GLVolumeCollection. if (m_selection.get_mode() == Selection::Instance) m_selection.instances_changed(instance_ids_selected); else From 3c5ecd4a8fb473d06fde8555633856239ff81a20 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 16 Feb 2023 16:06:21 +0100 Subject: [PATCH 09/32] FFF arrange minding skirt and brim distances many thanks to @individ-divided and @jschuh --- src/libslic3r/Print.hpp | 5 ++ src/slic3r/GUI/Jobs/ArrangeJob.cpp | 75 +++++++++++++++++++++++------- src/slic3r/GUI/Jobs/ArrangeJob.hpp | 4 +- src/slic3r/GUI/Jobs/FillBedJob.cpp | 22 ++++++++- src/slic3r/GUI/Jobs/FillBedJob.hpp | 1 + 5 files changed, 89 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 9fbbe378a1..f5712c3de6 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -565,6 +565,11 @@ public: SpanOfConstPtrs objects() const { return SpanOfConstPtrs(const_cast(m_objects.data()), m_objects.size()); } PrintObject* get_object(size_t idx) { return const_cast(m_objects[idx]); } const PrintObject* get_object(size_t idx) const { return m_objects[idx]; } + const PrintObject* get_print_object_by_model_object_id(ObjectID object_id) const { + auto it = std::find_if(m_objects.begin(), m_objects.end(), + [object_id](const PrintObject* obj) { return obj->model_object()->id() == object_id; }); + return (it == m_objects.end()) ? nullptr : *it; + } // PrintObject by its ObjectID, to be used to uniquely bind slicing warnings to their source PrintObjects // in the notification center. const PrintObject* get_object(ObjectID object_id) const { diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 72a938ab33..67c6298f89 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -2,6 +2,7 @@ #include "libslic3r/BuildVolume.hpp" #include "libslic3r/Model.hpp" +#include "libslic3r/Print.hpp" #include "libslic3r/SLAPrint.hpp" #include "libslic3r/Geometry/ConvexHull.hpp" @@ -79,7 +80,6 @@ void ArrangeJob::clear_input() m_selected.reserve(count + 1 /* for optional wti */); m_unselected.reserve(count + 1 /* for optional wti */); m_unprintable.reserve(cunprint /* for optional wti */); - m_min_inflation = 0; } void ArrangeJob::prepare_all() { @@ -151,8 +151,7 @@ void ArrangeJob::prepare_selected() { static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret, const SLAPrintObject &po, - const ModelInstance &inst, - coord_t min_infl) + const ModelInstance &inst) { auto laststep = po.last_completed_step(); @@ -189,10 +188,22 @@ static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret, po.config().pad_around_object.getBool() * po.config().pad_object_gap.getFloat()); - ret.inflation = std::max(infl, min_infl); + ret.inflation = infl; } } +static coord_t brim_offset(const PrintObject &po, const ModelInstance &inst) +{ + const BrimType brim_type = po.config().brim_type.value; + const float brim_separation = po.config().brim_separation.getFloat(); + const float brim_width = po.config().brim_width.getFloat(); + const bool has_outer_brim = brim_type == BrimType::btOuterOnly || + brim_type == BrimType::btOuterAndInner; + + // How wide is the brim? (in scaled units) + return has_outer_brim ? scaled(brim_width + brim_separation) : 0; +} + arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi) { arrangement::ArrangePolygon ap = get_arrange_poly(mi, m_plater); @@ -204,27 +215,40 @@ arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi) m_unarranged.emplace_back(mi); }; - if (m_plater->printer_technology() == ptSLA) { - auto obj_id = mi->get_object()->id(); - const SLAPrintObject *po = - m_plater->sla_print().get_print_object_by_model_object_id(obj_id); + return ap; +} - if (po) { - update_arrangepoly_slaprint(ap, *po, *mi, m_min_inflation); - m_min_inflation = std::max(m_min_inflation, ap.inflation); - } - } else { - // TODO: get fff supports outline +coord_t get_skirt_offset(const Plater* plater) { + float skirt_inset = 0.f; + // Try to subtract the skirt from the bed shape so we don't arrange outside of it. + if (plater->printer_technology() == ptFFF && plater->fff_print().has_skirt()) { + const auto& print = plater->fff_print(); + skirt_inset = print.config().skirts.value * print.skirt_flow().width() + + print.config().skirt_distance.value; } - return ap; + return scaled(skirt_inset); } void ArrangeJob::prepare() { wxGetKeyState(WXK_SHIFT) ? prepare_selected() : prepare_all(); + + coord_t min_offset = 0; for (auto &ap : m_selected) { - ap.inflation = m_min_inflation; + min_offset = std::max(ap.inflation, min_offset); + } + + if (m_plater->printer_technology() == ptSLA) { + // Apply the max offset for all the objects + for (auto &ap : m_selected) { + ap.inflation = min_offset; + } + } else { // it's fff, brims only need to be minded from bed edges + for (auto &ap : m_selected) { + ap.inflation = 0; + } + m_min_bed_inset = min_offset; } } @@ -238,6 +262,8 @@ void ArrangeJob::process(Ctl &ctl) prepare(); params = get_arrange_params(m_plater); get_bed_shape(*m_plater->config(), bed); + coord_t min_inset = get_skirt_offset(m_plater) + m_min_bed_inset; + params.min_bed_distance = std::max(params.min_bed_distance, min_inset); }).wait(); auto count = unsigned(m_selected.size() + m_unprintable.size()); @@ -352,6 +378,23 @@ arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, { auto ap = get_arrange_poly(PtrWrapper{inst}, plater); + auto obj_id = inst->get_object()->id(); + if (plater->printer_technology() == ptSLA) { + const SLAPrintObject *po = + plater->sla_print().get_print_object_by_model_object_id(obj_id); + + if (po) { + update_arrangepoly_slaprint(ap, *po, *inst); + } + } else { + const PrintObject *po = + plater->fff_print().get_print_object_by_model_object_id(obj_id); + + if (po) { + ap.inflation = brim_offset(*po, *inst); + } + } + return ap; } diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index 4b75868a03..a422d44070 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -21,7 +21,7 @@ class ArrangeJob : public Job ArrangePolygons m_selected, m_unselected, m_unprintable; std::vector m_unarranged; - coord_t m_min_inflation = 0; + coord_t m_min_bed_inset = 0.; Plater *m_plater; @@ -104,6 +104,8 @@ arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, arrangement::ArrangeParams get_arrange_params(Plater *p); +coord_t get_skirt_offset(const Plater* plater); + }} // namespace Slic3r::GUI #endif // ARRANGEJOB_HPP diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 6a173683f6..b8a579ed5d 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -18,6 +18,7 @@ void FillBedJob::prepare() m_selected.clear(); m_unselected.clear(); m_bedpts.clear(); + m_min_bed_inset = 0.; m_object_idx = m_plater->get_selected_object_idx(); if (m_object_idx == -1) @@ -29,7 +30,7 @@ void FillBedJob::prepare() m_selected.reserve(model_object->instances.size()); for (ModelInstance *inst : model_object->instances) if (inst->printable) { - ArrangePolygon ap = get_arrange_poly(PtrWrapper{inst}, m_plater); + ArrangePolygon ap = get_arrange_poly(inst, m_plater); // Existing objects need to be included in the result. Only // the needed amount of object will be added, no more. ++ap.priority; @@ -101,6 +102,23 @@ void FillBedJob::prepare() for (auto &p : m_unselected) if (p.bed_idx > 0) p.translation(X) -= p.bed_idx * stride; + + coord_t min_offset = 0; + for (auto &ap : m_selected) { + min_offset = std::max(ap.inflation, min_offset); + } + + if (m_plater->printer_technology() == ptSLA) { + // Apply the max offset for all the objects + for (auto &ap : m_selected) { + ap.inflation = min_offset; + } + } else { // it's fff, brims only need to be minded from bed edges + for (auto &ap : m_selected) { + ap.inflation = 0; + } + m_min_bed_inset = min_offset; + } } void FillBedJob::process(Ctl &ctl) @@ -110,6 +128,8 @@ void FillBedJob::process(Ctl &ctl) ctl.call_on_main_thread([this, ¶ms] { prepare(); params = get_arrange_params(m_plater); + coord_t min_inset = get_skirt_offset(m_plater) + m_min_bed_inset; + params.min_bed_distance = std::max(params.min_bed_distance, min_inset); }).wait(); ctl.update_status(0, statustxt); diff --git a/src/slic3r/GUI/Jobs/FillBedJob.hpp b/src/slic3r/GUI/Jobs/FillBedJob.hpp index b1417bbbd4..b953e0e981 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.hpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.hpp @@ -16,6 +16,7 @@ class FillBedJob : public Job ArrangePolygons m_selected; ArrangePolygons m_unselected; + coord_t m_min_bed_inset = 0.; Points m_bedpts; From 333d0727efc0f66235c1bbf4269c105d80b6cfb4 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 20 Feb 2023 14:10:23 +0100 Subject: [PATCH 10/32] Handling brim offset in SLA without the need to slice the object --- src/slic3r/GUI/Jobs/ArrangeJob.cpp | 48 +++++++++++++++++------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 67c6298f89..8115136a57 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -97,28 +97,28 @@ void ArrangeJob::prepare_all() { void ArrangeJob::prepare_selected() { clear_input(); - + Model &model = m_plater->model(); double stride = bed_stride(m_plater); - + std::vector obj_sel(model.objects.size(), nullptr); for (auto &s : m_plater->get_selection().get_content()) if (s.first < int(obj_sel.size())) obj_sel[size_t(s.first)] = &s.second; - + // Go through the objects and check if inside the selection for (size_t oidx = 0; oidx < model.objects.size(); ++oidx) { const Selection::InstanceIdxsList * instlist = obj_sel[oidx]; ModelObject *mo = model.objects[oidx]; - + std::vector inst_sel(mo->instances.size(), false); - + if (instlist) for (auto inst_id : *instlist) inst_sel[size_t(inst_id)] = true; - + for (size_t i = 0; i < inst_sel.size(); ++i) { ModelInstance * mi = mo->instances[i]; ArrangePolygon &&ap = get_arrange_poly_(mi); @@ -127,11 +127,11 @@ void ArrangeJob::prepare_selected() { (inst_sel[i] ? m_selected : m_unselected) : m_unprintable; - + cont.emplace_back(std::move(ap)); } } - + if (auto wti = get_wipe_tower(*m_plater)) { ArrangePolygon &&ap = get_arrange_poly(wti, m_plater); @@ -139,20 +139,34 @@ void ArrangeJob::prepare_selected() { m_unselected; cont.emplace_back(std::move(ap)); } - + // If the selection was empty arrange everything - if (m_selected.empty()) m_selected.swap(m_unselected); - + if (m_selected.empty()) + m_selected.swap(m_unselected); + // The strides have to be removed from the fixed items. For the // arrangeable (selected) items bed_idx is ignored and the // translation is irrelevant. - for (auto &p : m_unselected) p.translation(X) -= p.bed_idx * stride; + for (auto &p : m_unselected) + p.translation(X) -= p.bed_idx * stride; } static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret, const SLAPrintObject &po, const ModelInstance &inst) { + // The 1.1 multiplier is a safety gap, as the offset might be bigger + // in sharp edges of a polygon, depending on clipper's offset algorithm + coord_t pad_infl = 0; + { + double infl = po.config().pad_enable.getBool() * ( + po.config().pad_brim_size.getFloat() + + po.config().pad_around_object.getBool() * + po.config().pad_object_gap.getFloat() ); + + pad_infl = scaled(1.1 * infl); + } + auto laststep = po.last_completed_step(); if (laststep < slaposCount && laststep > slaposSupportTree) { @@ -181,15 +195,9 @@ static void update_arrangepoly_slaprint(arrangement::ArrangePolygon &ret, polys.emplace_back(its_convex_hull_2d_above(smesh.its, trafo_instance, zlvl)); ret.poly.contour = Geometry::convex_hull(polys); ret.poly.holes = {}; - - // The 1.1 multiplier is a safety gap, as the offset might be bigger - // in sharp edges of a polygon, depending on clipper's offset algorithm - coord_t infl = 1.1 * scaled(po.config().pad_brim_size.getFloat() + - po.config().pad_around_object.getBool() * - po.config().pad_object_gap.getFloat()); - - ret.inflation = infl; } + + ret.inflation = pad_infl; } static coord_t brim_offset(const PrintObject &po, const ModelInstance &inst) From 92e0c1351319d2a8e2d4f5c399d3694a85e1be2d Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 20 Feb 2023 14:10:59 +0100 Subject: [PATCH 11/32] Try to handle fff supports in arrange after slicing Not really precise yet --- src/slic3r/GUI/Jobs/ArrangeJob.cpp | 45 +++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 8115136a57..826dc24076 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -212,6 +212,49 @@ static coord_t brim_offset(const PrintObject &po, const ModelInstance &inst) return has_outer_brim ? scaled(brim_width + brim_separation) : 0; } +template +Polygon support_layers_chull (Points &pts, It from_lyr, It to_lyr) { + + size_t cap = 0; + for (auto it = from_lyr; it != to_lyr; ++it) { + for (const ExPolygon &expoly : (*it)->support_islands) + cap += expoly.contour.points.size(); + } + + pts.reserve(pts.size() + cap); + + for (auto it = from_lyr; it != to_lyr; ++it) { + for (const ExPolygon &expoly : (*it)->support_islands) + std::copy(expoly.contour.begin(), expoly.contour.end(), + std::back_inserter(pts)); + } + + Polygon ret = Geometry::convex_hull(pts); + + return ret; +} + +static void update_arrangepoly_fffprint(arrangement::ArrangePolygon &ret, + const PrintObject &po, + const ModelInstance &inst) +{ + auto laststep = po.last_completed_step(); + + coord_t infl = brim_offset(po, inst); + + if (laststep < posCount && laststep > posSupportMaterial) { + Points pts = std::move(ret.poly.contour.points); + Polygon poly = support_layers_chull(pts, + po.support_layers().begin(), + po.support_layers().end()); + + ret.poly.contour = std::move(poly); + ret.poly.holes = {}; + } + + ret.inflation = infl; +} + arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi) { arrangement::ArrangePolygon ap = get_arrange_poly(mi, m_plater); @@ -399,7 +442,7 @@ arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, plater->fff_print().get_print_object_by_model_object_id(obj_id); if (po) { - ap.inflation = brim_offset(*po, *inst); + update_arrangepoly_fffprint(ap, *po, *inst); } } From 84284b44189d73fd57c6a34a80fcea9403859b6c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 23 Mar 2023 11:42:46 +0100 Subject: [PATCH 12/32] Fixed crash when scaling object to fit print volume with SLA printers --- src/slic3r/GUI/GLCanvas3D.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ad1c8fe03b..a433f6dbd5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2119,10 +2119,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re // Shift-up all volumes of the object so that it has the right elevation with respect to the print bed for (GLVolume* volume : m_volumes.volumes) { - if (volume->object_idx() < (int)m_model->objects.size() && m_model->objects[volume->object_idx()]->instances[volume->instance_idx()]->is_printable()) { - const SLAPrintObject* po = sla_print->objects()[volume->object_idx()]; - float zoffs = po->get_current_elevation() / sla_print->relative_correction().z(); - volume->set_sla_shift_z(zoffs); + const ModelObject* model_object = (volume->object_idx() < (int)m_model->objects.size()) ? m_model->objects[volume->object_idx()] : nullptr; + if (model_object != nullptr && model_object->instances[volume->instance_idx()]->is_printable()) { + const SLAPrintObject* po = sla_print->get_print_object_by_model_object_id(model_object->id()); + if (po != nullptr) + volume->set_sla_shift_z(po->get_current_elevation() / sla_print->relative_correction().z()); } } } From 582f51cdfd9360cf81dc82843a838faf7a87b4dd Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Mar 2023 08:36:43 +0100 Subject: [PATCH 13/32] Fixed crash when opening Emboss Gizmo pressing 'T' key after slicing an object using SLA printer --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index dd18cb878a..a4ba6de32b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -3444,7 +3444,7 @@ void priv::find_closest_volume(const Selection &selection, for (unsigned int id : indices) { const GLVolume *gl_volume = selection.get_volume(id); const ModelVolume *volume = get_model_volume(*gl_volume, objects); - if (!volume->is_model_part()) continue; + if (volume == nullptr || !volume->is_model_part()) continue; Slic3r::Polygon hull = CameraUtils::create_hull2d(camera, *gl_volume); Vec2d c = hull.centroid().cast(); Vec2d d = c - screen_center; From 6ba067ad36b10641744d88423ce29bbea85b2256 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Mar 2023 08:40:32 +0100 Subject: [PATCH 14/32] Fixed crash when trying to add text on an object sliced using SLA printer by right clicking on supports or pad --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index a4ba6de32b..2155174706 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -3394,6 +3394,7 @@ bool priv::start_create_volume_on_surface_job( { assert(gl_volume != nullptr); if (gl_volume == nullptr) return false; + if (gl_volume->volume_idx() < 0) return false; Plater *plater = wxGetApp().plater(); const ModelObjectPtrs &objects = plater->model().objects; From 7f1df7b110c89864b1a10bc52055e6f194645d24 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 24 Mar 2023 12:57:07 +0100 Subject: [PATCH 15/32] Fixed Fit to print volume command when applied to an object sliced using SLA printer --- src/slic3r/GUI/GLCanvas3D.cpp | 15 ++++++++++++--- src/slic3r/GUI/Selection.cpp | 14 +++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index dc4acebbc6..b5b4a9ca0d 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3605,6 +3605,9 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) int instance_idx = v->instance_idx(); int volume_idx = v->volume_idx(); + if (volume_idx < 0) + continue; + std::pair done_id(object_idx, instance_idx); if (0 <= object_idx && object_idx < (int)m_model->objects.size()) { @@ -3619,7 +3622,7 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) #else model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); #endif // ENABLE_WORLD_COORDINATE - else if (volume_idx >= 0 && selection_mode == Selection::Volume) + else if (selection_mode == Selection::Volume) #if ENABLE_WORLD_COORDINATE model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); #else @@ -3710,6 +3713,9 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) const int instance_idx = v->instance_idx(); const int volume_idx = v->volume_idx(); + if (volume_idx < 0) + continue; + done.insert(std::pair(object_idx, instance_idx)); // Rotate instances/volumes. @@ -3723,7 +3729,7 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); #endif // ENABLE_WORLD_COORDINATE } - else if (selection_mode == Selection::Volume && volume_idx >= 0) { + else if (selection_mode == Selection::Volume) { #if ENABLE_WORLD_COORDINATE model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); #else @@ -3786,6 +3792,9 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) const int instance_idx = v->instance_idx(); const int volume_idx = v->volume_idx(); + if (volume_idx < 0) + continue; + done.insert(std::pair(object_idx, instance_idx)); // Rotate instances/volumes @@ -3799,7 +3808,7 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); #endif // ENABLE_WORLD_COORDINATE } - else if (selection_mode == Selection::Volume && volume_idx >= 0) { + else if (selection_mode == Selection::Volume) { #if ENABLE_WORLD_COORDINATE model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2b77fe7ff4..28cf367fdf 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1396,6 +1396,18 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) // used to keep track whether the undo/redo snapshot has already been taken bool undoredo_snapshot = false; + if (wxGetApp().plater()->printer_technology() == ptSLA) { + // remove SLA auxiliary volumes from the selection to ensure that the proper bounding box is calculated + std::vector to_remove; + for (unsigned int i : m_list) { + if ((*m_volumes)[i]->volume_idx() < 0) + to_remove.push_back(i); + } + + if (!to_remove.empty()) + remove_volumes(m_mode, to_remove); + } + switch (volume.type()) { case BuildVolume::Type::Rectangle: { undoredo_snapshot = fit_rectangle(volume, !undoredo_snapshot); break; } @@ -3006,7 +3018,7 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV continue; const Transform3d::ConstLinearPart& rotation0 = volumes[idx_volume_first]->get_instance_transformation().get_matrix().linear(); for (int i = idx_volume_first + 1; i < (int)volumes.size(); ++i) - if (volumes[i]->object_idx() == idx_object) { + if (volumes[i]->object_idx() == idx_object && volumes[i]->volume_idx() >= 0) { const Transform3d::ConstLinearPart& rotation = volumes[i]->get_instance_transformation().get_matrix().linear(); assert(is_rotation_xy_synchronized(rotation, rotation0)); } From 989ca9d8ee4ce442508d2ef949f561d551fc033c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 27 Mar 2023 16:00:13 +0200 Subject: [PATCH 16/32] CutGizmo: Fix for Cut by Line --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index c65f4fad07..5d8a69e417 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -2298,7 +2298,10 @@ bool GLGizmoCut3D::process_cut_line(SLAGizmoEventType action, const Vec2d& mouse const Vec3d new_plane_center = m_bb_center + cross_dir * cross_dir.dot(pt - m_bb_center); // update transformed bb const auto new_tbb = transformed_bounding_box(new_plane_center, m); - const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset(); + const GLVolume* first_volume = m_parent.get_selection().get_first_volume(); + Vec3d instance_offset = first_volume->get_instance_offset(); + instance_offset[Z] += first_volume->get_sla_shift_z(); + const Vec3d trans_center_pos = m.inverse() * (new_plane_center - instance_offset) + new_tbb.center(); if (new_tbb.contains(trans_center_pos)) { Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Cut by line"), UndoRedo::SnapshotType::GizmoAction); From 56d15253d41953e2a319f7cf195f1059e6a0075a Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Tue, 28 Mar 2023 16:07:00 +0200 Subject: [PATCH 17/32] Fix update of model after finish text jobs. --- src/slic3r/GUI/Jobs/EmbossJob.cpp | 65 +++++++++++++++++++++++-------- src/slic3r/GUI/Jobs/EmbossJob.hpp | 2 +- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/slic3r/GUI/Jobs/EmbossJob.cpp b/src/slic3r/GUI/Jobs/EmbossJob.cpp index 208cb2c0bd..a265c4de9f 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.cpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.cpp @@ -483,10 +483,46 @@ TriangleMesh priv::create_default_mesh() return triangle_mesh; } +namespace{ +void update_volume_name(const ModelVolume &volume, const ObjectList *obj_list) +{ + if (obj_list == nullptr) + return; + + const std::vector* objects = obj_list->objects(); + if (objects == nullptr) + return; + + int object_idx = -1; + int volume_idx = -1; + for (size_t oi = 0; oi < objects->size(); ++oi) { + const ModelObject *mo = objects->at(oi); + if (mo == nullptr) + continue; + if (volume.get_object()->id() != mo->id()) + continue; + const ModelVolumePtrs& volumes = mo->volumes; + for (size_t vi = 0; vi < volumes.size(); ++vi) { + const ModelVolume *mv = volumes[vi]; + if (mv == nullptr) + continue; + if (mv->id() == volume.id()){ + object_idx = static_cast(oi); + volume_idx = static_cast(vi); + break; + } + } + if (volume_idx > 0) + break; + } + obj_list->update_name_in_list(object_idx, volume_idx); +} +} + void UpdateJob::update_volume(ModelVolume *volume, TriangleMesh &&mesh, const TextConfiguration &text_configuration, - const std::string &volume_name) + std::string_view volume_name) { // check inputs bool is_valid_input = @@ -506,19 +542,12 @@ void UpdateJob::update_volume(ModelVolume *volume, // discard information about rotation, should not be stored in volume volume->text_configuration->style.prop.angle.reset(); - GUI_App &app = wxGetApp(); // may be move to input - GLCanvas3D *canvas = app.plater()->canvas3D(); - const Selection &selection = canvas->get_selection(); - const GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin()); - int object_idx = gl_volume->object_idx(); + GUI_App &app = wxGetApp(); // may be move ObjectList and Plater to input? + // update volume name in right panel( volume / object name) if (volume->name != volume_name) { volume->name = volume_name; - - // update volume name in right panel( volume / object name) - int volume_idx = gl_volume->volume_idx(); - ObjectList *obj_list = app.obj_list(); - obj_list->update_name_in_list(object_idx, volume_idx); + update_volume_name(*volume, app.obj_list()); } // When text is object. @@ -528,11 +557,12 @@ void UpdateJob::update_volume(ModelVolume *volume, volume->get_object()->ensure_on_bed(); // redraw scene - bool refresh_immediately = false; - canvas->reload_scene(refresh_immediately); + Plater *plater = app.plater(); + if (plater == nullptr) + return; - // Change buttons "Export G-code" into "Slice now" - canvas->post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); + // Update Model and redraw scene + plater->update(); } void priv::update_volume(TriangleMesh &&mesh, const DataUpdate &data, Transform3d* tr) @@ -646,8 +676,9 @@ void priv::create_volume( if (manager.get_current_type() != GLGizmosManager::Emboss) manager.open_gizmo(GLGizmosManager::Emboss); - // redraw scene - canvas->reload_scene(true); + // update model and redraw scene + //canvas->reload_scene(true); + plater->update(); } ModelVolume *priv::get_volume(ModelObjectPtrs &objects, diff --git a/src/slic3r/GUI/Jobs/EmbossJob.hpp b/src/slic3r/GUI/Jobs/EmbossJob.hpp index d3896c0a65..d4b32cf616 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.hpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.hpp @@ -145,7 +145,7 @@ public: static void update_volume(ModelVolume *volume, TriangleMesh &&mesh, const TextConfiguration &text_configuration, - const std::string &volume_name); + std::string_view volume_name); }; struct SurfaceVolumeData From 392dbba96f13026041e97f6d0e8042d05e326423 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Tue, 28 Mar 2023 17:10:56 +0200 Subject: [PATCH 18/32] Fix offsets for SLA Text dragging with visible supports. --- src/slic3r/GUI/SurfaceDrag.cpp | 72 ++++++++++++---------------------- src/slic3r/GUI/SurfaceDrag.hpp | 3 ++ 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/slic3r/GUI/SurfaceDrag.cpp b/src/slic3r/GUI/SurfaceDrag.cpp index a202ae5de4..40b01a2af8 100644 --- a/src/slic3r/GUI/SurfaceDrag.cpp +++ b/src/slic3r/GUI/SurfaceDrag.cpp @@ -9,50 +9,6 @@ #include "libslic3r/Emboss.hpp" namespace Slic3r::GUI { - -/// -/// Calculate offset from mouse position to center of text -/// -/// Position on screen[in Px] e.g. mouse position -/// Selected volume(text) -/// Actual position and view direction of camera -/// Offset in screen coordinate -static Vec2d calc_screen_offset_to_volume_center(const Vec2d &screen_coor, const ModelVolume &volume, const Camera &camera) -{ - const Transform3d &volume_tr = volume.get_matrix(); - assert(volume.text_configuration.has_value()); - - auto calc_offset = [&screen_coor, &volume_tr, &camera, &volume](const Transform3d &instrance_tr) -> Vec2d { - Transform3d to_world = instrance_tr * volume_tr; - - // Use fix of .3mf loaded tranformation when exist - if (volume.text_configuration->fix_3mf_tr.has_value()) - to_world = to_world * (*volume.text_configuration->fix_3mf_tr); - // zero point of volume in world coordinate system - Vec3d volume_center = to_world.translation(); - // screen coordinate of volume center - Vec2i coor = CameraUtils::project(camera, volume_center); - return coor.cast() - screen_coor; - }; - - auto object = volume.get_object(); - assert(!object->instances.empty()); - // Speed up for one instance - if (object->instances.size() == 1) - return calc_offset(object->instances.front()->get_matrix()); - - Vec2d nearest_offset; - double nearest_offset_size = std::numeric_limits::max(); - for (const ModelInstance *instance : object->instances) { - Vec2d offset = calc_offset(instance->get_matrix()); - double offset_size = offset.norm(); - if (nearest_offset_size < offset_size) - continue; - nearest_offset_size = offset_size; - nearest_offset = offset; - } - return nearest_offset; -} // Calculate scale in world for check in debug [[maybe_unused]] static std::optional calc_scale(const Matrix3d &from, const Matrix3d &to, const Vec3d &dir) @@ -109,7 +65,8 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, gl_volumes[hovered_idx_] != gl_volume) return false; - const ModelObject *object = get_model_object(*gl_volume, canvas.get_model()->objects); + const ModelObjectPtrs &objects = canvas.get_model()->objects; + const ModelObject *object = get_model_object(*gl_volume, objects); assert(object != nullptr); if (object == nullptr) return false; @@ -148,7 +105,26 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, // wxCoord == int --> wx/types.h Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY()); Vec2d mouse_pos = mouse_coord.cast(); - Vec2d mouse_offset = calc_screen_offset_to_volume_center(mouse_pos, *volume, camera); + + // world_matrix_fixed() without sla shift + Transform3d to_world = world_matrix_fixed(*gl_volume, objects); + + // zero point of volume in world coordinate system + Vec3d volume_center = to_world.translation(); + // screen coordinate of volume center + Vec2i coor = CameraUtils::project(camera, volume_center); + Vec2d mouse_offset = coor.cast() - mouse_pos; + Vec2d mouse_offset_without_sla_shift = mouse_offset; + if (double sla_shift = gl_volume->get_sla_shift_z(); !is_approx(sla_shift, 0.)) { + Transform3d to_world_without_sla_move = instance->get_matrix() * volume->get_matrix(); + if (volume->text_configuration.has_value() && volume->text_configuration->fix_3mf_tr.has_value()) + to_world_without_sla_move = to_world_without_sla_move * (*volume->text_configuration->fix_3mf_tr); + // zero point of volume in world coordinate system + volume_center = to_world_without_sla_move.translation(); + // screen coordinate of volume center + coor = CameraUtils::project(camera, volume_center); + mouse_offset_without_sla_shift = coor.cast() - mouse_pos; + } Transform3d volume_tr = gl_volume->get_volume_transformation().get_matrix(); @@ -165,7 +141,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, std::optional start_angle; if (up_limit.has_value()) start_angle = Emboss::calc_up(world_tr, *up_limit); - surface_drag = SurfaceDrag{mouse_offset, world_tr, instance_tr_inv, gl_volume, condition, start_angle}; + surface_drag = SurfaceDrag{mouse_offset, world_tr, instance_tr_inv, gl_volume, condition, start_angle, true, mouse_offset_without_sla_shift}; // disable moving with object by mouse canvas.enable_moving(false); @@ -181,7 +157,7 @@ bool on_mouse_surface_drag(const wxMouseEvent &mouse_event, // wxCoord == int --> wx/types.h Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY()); Vec2d mouse_pos = mouse_coord.cast(); - Vec2d offseted_mouse = mouse_pos + surface_drag->mouse_offset; + Vec2d offseted_mouse = mouse_pos + surface_drag->mouse_offset_without_sla_shift; std::optional hit = ray_from_camera( raycast_manager, offseted_mouse, camera, &surface_drag->condition); diff --git a/src/slic3r/GUI/SurfaceDrag.hpp b/src/slic3r/GUI/SurfaceDrag.hpp index bb2600c28f..48d6a33fe2 100644 --- a/src/slic3r/GUI/SurfaceDrag.hpp +++ b/src/slic3r/GUI/SurfaceDrag.hpp @@ -39,6 +39,9 @@ struct SurfaceDrag // Flag whether coordinate hit some volume bool exist_hit = true; + + // hold screen coor offset of cursor from object center without SLA shift + Vec2d mouse_offset_without_sla_shift; }; /// From cc5660ad8cf28a134cad5164061d890441655612 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Wed, 29 Mar 2023 10:45:11 +0200 Subject: [PATCH 19/32] Lock for rotation. --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 39 +++++++++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 2 ++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index ec2a74f962..a3cdb92a53 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -223,6 +223,10 @@ enum class IconType : unsigned { system_selector, open_file, exclamation, + lock, + lock_bold, + unlock, + unlock_bold, // automatic calc of icon's count _count }; @@ -779,12 +783,12 @@ GLGizmoEmboss::GuiCfg GLGizmoEmboss::create_gui_configuration() ImGui::CalcTextSize(tr.boldness.c_str()).x, ImGui::CalcTextSize(tr.skew_ration.c_str()).x, ImGui::CalcTextSize(tr.from_surface.c_str()).x, - ImGui::CalcTextSize(tr.rotation.c_str()).x, + ImGui::CalcTextSize(tr.rotation.c_str()).x + cfg.icon_width + 2*space, ImGui::CalcTextSize(tr.keep_up.c_str()).x, ImGui::CalcTextSize(tr.collection.c_str()).x }); cfg.advanced_input_offset = max_advanced_text_width + 3 * space + cfg.indent; - + cfg.lock_offset = cfg.advanced_input_offset - (cfg.icon_width + space); // calculate window size float window_title = line_height + 2*style.FramePadding.y + 2 * style.WindowTitleAlign.y; float input_height = line_height_with_spacing + 2*style.FramePadding.y; @@ -806,9 +810,9 @@ GLGizmoEmboss::GuiCfg GLGizmoEmboss::create_gui_configuration() + 2 * (cfg.icon_width + space); cfg.minimal_window_size = ImVec2(window_width, window_height); - // 9 = useSurface, charGap, lineGap, bold, italic, surfDist, rotation, keepUp, textFaceToCamera + // 8 = useSurface, charGap, lineGap, bold, italic, surfDist, rotation, textFaceToCamera // 4 = 1px for fix each edit image of drag float - float advance_height = input_height * 9 + 8; + float advance_height = input_height * 8 + 8; cfg.minimal_window_size_with_advance = ImVec2(cfg.minimal_window_size.x, cfg.minimal_window_size.y + advance_height); @@ -2652,8 +2656,8 @@ void GLGizmoEmboss::draw_height(bool use_inch) { float &value = m_style_manager.get_style().prop.size_in_mm; const EmbossStyle* stored_style = m_style_manager.get_stored_style(); - const float *stored = ((stored_style)? &stored_style->prop.size_in_mm : nullptr); - const char *size_format = ((use_inch) ? "%.2f in" : "%.1f mm"); + const float *stored = (stored_style != nullptr)? &stored_style->prop.size_in_mm : nullptr; + const char *size_format = use_inch ? "%.2f in" : "%.1f mm"; const std::string revert_text_size = _u8L("Revert text size."); const std::string& name = m_gui_cfg->translations.height; if (rev_input_mm(name, value, stored, revert_text_size, 0.1f, 1.f, size_format, use_inch, m_scale_height)) @@ -2913,10 +2917,10 @@ void GLGizmoEmboss::draw_advanced() &stored_style->prop.distance : nullptr; m_imgui->disabled_begin(!allowe_surface_distance); - bool use_inch = wxGetApp().app_config->get_bool("use_inches"); const std::string undo_move_tooltip = _u8L("Undo translation"); const wxString move_tooltip = _L("Distance of the center of text from model surface"); bool is_moved = false; + bool use_inch = wxGetApp().app_config->get_bool("use_inches"); if (use_inch) { std::optional distance_inch; if (distance.has_value()) distance_inch = (*distance * ObjectManipulation::mm_to_in); @@ -2982,16 +2986,23 @@ void GLGizmoEmboss::draw_advanced() process(); } - ImGui::Text("%s", tr.keep_up.c_str()); - ImGui::SameLine(m_gui_cfg->advanced_input_offset); - if (ImGui::Checkbox("##keep_up", &m_keep_up)) { + // Keep up - lock button icon + ImGui::SameLine(m_gui_cfg->lock_offset); + const IconManager::Icon &icon = get_icon(m_icons, m_keep_up ? IconType::lock : IconType::unlock, IconState::activable); + const IconManager::Icon &icon_hover = get_icon(m_icons, m_keep_up ? IconType::lock_bold : IconType::unlock_bold, IconState::activable); + const IconManager::Icon &icon_disable = get_icon(m_icons, m_keep_up ? IconType::lock : IconType::unlock, IconState::disabled); + if (button(icon, icon_hover, icon_disable)) { + m_keep_up = !m_keep_up; if (m_keep_up) { // copy angle to volume m_volume->text_configuration->style.prop.angle = font_prop.angle; } } if (ImGui::IsItemHovered()) - ImGui::SetTooltip("%s", _u8L("Lock the text's rotation when moving text along the object's surface.").c_str()); + ImGui::SetTooltip("%s", (m_keep_up? + _u8L("Unlock the text's up orientation when moving text along the object's surface."): + _u8L("Lock the text's up orientation when moving text along the object's surface.") + ).c_str()); // when more collection add selector if (ff.font_file->infos.size() > 1) { @@ -3270,7 +3281,11 @@ void GLGizmoEmboss::init_icons() "make_unbold.svg", "search.svg", "open.svg", - "exclamation.svg" + "exclamation.svg", + "lock_closed.svg", // lock, + "lock_closed_f.svg",// lock_bold, + "lock_open.svg", // unlock, + "lock_open_f.svg" // unlock_bold, }; assert(filenames.size() == static_cast(IconType::_count)); std::string path = resources_dir() + "/icons/"; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index a57def86e5..d461425af6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -182,6 +182,8 @@ private: float input_offset = 0.f; float advanced_input_offset = 0.f; + float lock_offset = 0.f; + ImVec2 text_size; // maximal size of face name image From eec51c67d32e18b079e72a4c9d4745a0d2f8f727 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 29 Mar 2023 10:49:35 +0200 Subject: [PATCH 20/32] Refactoring of PrintObject::discover_vertical_shells() for readability and efficiency. Also added an experiment of adding one more "ensuring" layer to support top / bottom surfaces, disabled with one_more_layer_below_top_bottom_surfaces --- src/libslic3r/PrintObject.cpp | 61 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 61067ed18d..26b359c0e7 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1373,43 +1373,56 @@ void PrintObject::discover_vertical_shells() } #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ polygons_append(holes, cache_top_botom_regions[idx_layer].holes); + auto combine_holes = [&holes](const Polygons &holes2) { + if (holes.empty() || holes2.empty()) + holes.clear(); + else + holes = intersection(holes, holes2); + }; + auto combine_shells = [&shell](const Polygons &shells2) { + if (shell.empty()) + shell = std::move(shells2); + else if (! shells2.empty()) { + polygons_append(shell, shells2); + // Running the union_ using the Clipper library piece by piece is cheaper + // than running the union_ all at once. + shell = union_(shell); + } + }; + static constexpr const bool one_more_layer_below_top_bottom_surfaces = false; if (int n_top_layers = region_config.top_solid_layers.value; n_top_layers > 0) { // Gather top regions projected to this layer. coordf_t print_z = layer->print_z; - for (int i = int(idx_layer) + 1; - i < int(cache_top_botom_regions.size()) && - (i < int(idx_layer) + n_top_layers || - m_layers[i]->print_z - print_z < region_config.top_solid_min_thickness - EPSILON); + int i = int(idx_layer) + 1; + int itop = int(idx_layer) + n_top_layers; + for (; i < int(cache_top_botom_regions.size()) && + (i < itop || m_layers[i]->print_z - print_z < region_config.top_solid_min_thickness - EPSILON); ++ i) { const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[i]; - if (! holes.empty()) - holes = intersection(holes, cache.holes); - if (! cache.top_surfaces.empty()) { - polygons_append(shell, cache.top_surfaces); - // Running the union_ using the Clipper library piece by piece is cheaper - // than running the union_ all at once. - shell = union_(shell); - } + combine_holes(cache.holes); + combine_shells(cache.top_surfaces); } + if (one_more_layer_below_top_bottom_surfaces) + if (i < int(cache_top_botom_regions.size()) && + (i <= itop || m_layers[i]->bottom_z() - print_z < region_config.top_solid_min_thickness - EPSILON)) + combine_holes(cache_top_botom_regions[i].holes); } if (int n_bottom_layers = region_config.bottom_solid_layers.value; n_bottom_layers > 0) { // Gather bottom regions projected to this layer. coordf_t bottom_z = layer->bottom_z(); - for (int i = int(idx_layer) - 1; - i >= 0 && - (i > int(idx_layer) - n_bottom_layers || - bottom_z - m_layers[i]->bottom_z() < region_config.bottom_solid_min_thickness - EPSILON); + int i = int(idx_layer) - 1; + int ibottom = int(idx_layer) - n_bottom_layers; + for (; i >= 0 && + (i > ibottom || bottom_z - m_layers[i]->bottom_z() < region_config.bottom_solid_min_thickness - EPSILON); -- i) { const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[i]; - if (! holes.empty()) - holes = intersection(holes, cache.holes); - if (! cache.bottom_surfaces.empty()) { - polygons_append(shell, cache.bottom_surfaces); - // Running the union_ using the Clipper library piece by piece is cheaper - // than running the union_ all at once. - shell = union_(shell); - } + combine_holes(cache.holes); + combine_shells(cache.bottom_surfaces); } + if (one_more_layer_below_top_bottom_surfaces) + if (i >= 0 && + (i > ibottom || bottom_z - m_layers[i]->print_z < region_config.bottom_solid_min_thickness - EPSILON)) + combine_holes(cache_top_botom_regions[i].holes); } #ifdef SLIC3R_DEBUG_SLICE_PROCESSING { From f71ea4b615c74772d807f2478296243ea8a1e85d Mon Sep 17 00:00:00 2001 From: rtyr <36745189+rtyr@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:54:03 +0200 Subject: [PATCH 21/32] MK4 resources --- .../profiles/PrusaResearch/MK4_thumbnail.png | Bin 0 -> 69761 bytes resources/profiles/PrusaResearch/mk4.svg | 101 ++++++++++++++++++ resources/profiles/PrusaResearch/mk4_bed.stl | Bin 0 -> 91884 bytes 3 files changed, 101 insertions(+) create mode 100644 resources/profiles/PrusaResearch/MK4_thumbnail.png create mode 100644 resources/profiles/PrusaResearch/mk4.svg create mode 100644 resources/profiles/PrusaResearch/mk4_bed.stl diff --git a/resources/profiles/PrusaResearch/MK4_thumbnail.png b/resources/profiles/PrusaResearch/MK4_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..2b729f930c5ab6a9891d8326cff3adfaa7e993ba GIT binary patch literal 69761 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℞Jvrj`T)MEYcGWKKKLm0t(12@ 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 IM6N<$f;Jq2^8f$< literal 0 HcmV?d00001 diff --git a/resources/profiles/PrusaResearch/mk4.svg b/resources/profiles/PrusaResearch/mk4.svg new file mode 100644 index 0000000000..70a3b5ecaf --- /dev/null +++ b/resources/profiles/PrusaResearch/mk4.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/profiles/PrusaResearch/mk4_bed.stl b/resources/profiles/PrusaResearch/mk4_bed.stl new file mode 100644 index 0000000000000000000000000000000000000000..6aff36f0bcbda670a4d3ed645dcac8ff112d3462 GIT binary patch literal 91884 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 literal 0 HcmV?d00001 From 6f9f7ad47aae7eca8cd417c27dd30e79ab1abc34 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Wed, 29 Mar 2023 10:55:48 +0200 Subject: [PATCH 22/32] change to constexpr --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index d461425af6..b66f42b0fb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -256,7 +256,7 @@ private: std::vector bad = {}; // Configuration of font encoding - static const wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM; + static constexpr wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM; // Identify if preview texture exists GLuint texture_id = 0; From 0ed47616f9bad15997f5f12be362b6bacda6f488 Mon Sep 17 00:00:00 2001 From: rtyr <36745189+rtyr@users.noreply.github.com> Date: Wed, 29 Mar 2023 11:22:09 +0200 Subject: [PATCH 23/32] Added MK4 profiles. --- resources/profiles/PrusaResearch.idx | 3 + resources/profiles/PrusaResearch.ini | 2419 ++++++++++++++++++++++++-- 2 files changed, 2252 insertions(+), 170 deletions(-) diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx index 77fdf5a83b..a108d837fd 100644 --- a/resources/profiles/PrusaResearch.idx +++ b/resources/profiles/PrusaResearch.idx @@ -1,4 +1,5 @@ min_slic3r_version = 2.6.0-alpha5 +1.9.0-alpha1 Added profiles for Original Prusa MK4. 1.9.0-alpha0 Updated output filename format. 1.7.0-alpha2 Updated compatibility condition in some filament profiles (Prusa XL). 1.7.0-alpha1 Added profiles for Original Prusa XL. Added filament profile for Prusament PETG Tungsten 75%. @@ -8,10 +9,12 @@ min_slic3r_version = 2.6.0-alpha1 1.6.0-alpha1 Updated FW version notification. Decreased min layer time for PLA. 1.6.0-alpha0 Default top fill set to monotonic lines. Updated infill/perimeter overlap values. Updated output filename format. Enabled dynamic overhang speeds. min_slic3r_version = 2.5.1-rc0 +1.6.3 Added SLA materials. 1.6.2 Updated compatibility condition in some filament profiles (Prusa XL). 1.6.1 Added filament profile for Prusament PETG Tungsten 75%. Updated Prusa XL profiles. 1.6.0 Added Original Prusa XL profiles. Updated acceleration settings for Prusa MINI. Updated infill/perimeter overlap values. min_slic3r_version = 2.5.0-alpha0 +1.5.9 Added SLA materials. 1.5.8 Added filament profile for Prusament PETG Tungsten 75%. Updated FW version notification. 1.5.7 Added filament profile for Prusament PETG Carbon Fiber and Fiberthree F3 PA-GF30 Pro. 1.5.6 Updated FW version notification (MK2.5/MK3 family). Added filament profile for Kimya PEBA-S. diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index f57a8110d7..0194657972 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -5,7 +5,7 @@ name = Prusa Research # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.9.0-alpha0 +config_version = 1.9.0-alpha1 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/ changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% @@ -14,14 +14,14 @@ changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% # also the first model installed & the first nozzle installed will be activated after install. # Printer model name will be shown by the installation wizard. -[printer_model:XL] -name = Original Prusa XL -variants = 0.6; 0.25; 0.3; 0.4; 0.5; 0.8 +[printer_model:MK4] +name = Original Prusa MK4 +variants = 0.4; 0.25; 0.3; 0.5; 0.6; 0.8 technology = FFF -family = XL -bed_model = xl_bed.stl -bed_texture = xl.svg -default_materials = Generic PLA @PG 0.6; Generic ABS @PG 0.6; Generic PETG @PG 0.6; Prusament PLA @PG 0.6; Prusament PETG @PG 0.6; Prusament ASA @PG 0.6; Prusament PC Blend @PG 0.6; Prusament PC Blend Carbon Fiber @PG 0.6; Prusament PVB @PG 0.6; Prusament PA11 Carbon Fiber @PG 0.6 +family = MK4 +bed_model = mk4_bed.stl +bed_texture = mk4.svg +default_materials = Generic PLA @PG; Generic ABS @MK4; Generic PETG @PG; Prusament PLA @PG; Prusament PETG @PG; Prusament ASA @MK4; Prusament PC Blend @MK4; Prusament PC Blend Carbon Fiber @MK4; Prusament PVB @PG; Prusament PA11 Carbon Fiber @PG [printer_model:MINI] name = Original Prusa MINI && MINI+ @@ -68,6 +68,15 @@ bed_model = mk3_bed.stl bed_texture = mk3.svg default_materials = Generic PLA; Generic ABS; Generic PETG; Prusament PLA @MMU2; Prusament PETG @MMU2; Prusament ASA @MMU2; Verbatim BVOH @MMU2; Prusament PC Blend @MMU2; Prusament PC Blend Carbon Fiber @MMU2; Prusament PVB @MMU2 +[printer_model:XL] +name = Original Prusa XL +variants = 0.6; 0.25; 0.3; 0.4; 0.5; 0.8 +technology = FFF +family = XL +bed_model = xl_bed.stl +bed_texture = xl.svg +default_materials = Generic PLA @PG 0.6; Generic ABS @PG 0.6; Generic PETG @PG 0.6; Prusament PLA @PG 0.6; Prusament PETG @PG 0.6; Prusament ASA @PG 0.6; Prusament PC Blend @PG 0.6; Prusament PC Blend Carbon Fiber @PG 0.6; Prusament PVB @PG 0.6; Prusament PA11 Carbon Fiber @PG 0.6 + [printer_model:MK2.5S] name = Original Prusa i3 MK2.5S variants = 0.4; 0.25; 0.6; 0.8 @@ -284,6 +293,30 @@ raft_first_layer_density = 80% ## gcode_substitutions = "; stop printing object\\s(.*)\\s+id:(\\d+)\\s+.*";"$0\\nM486 S-1\\n";r;;"; printing object\\s(.*)\\s+id:(\\d+)\\s+.*";"$0\\nM486 S$2\\nM486 N$1\\n";r; output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{printing_filament_types}_{printer_model}_{print_time}.gcode +[print:*MK4*] +inherits = *common* +single_extruder_multi_material_priming = 0 +travel_speed = 200 +travel_speed_z = 12 +fill_density = 15% +default_acceleration = 1000 +bridge_acceleration = 800 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +infill_anchor = 2 +perimeter_acceleration = 800 +first_layer_acceleration = 600 +fill_pattern = grid +skirts = 0 +extruder_clearance_height = 13 +extruder_clearance_radius = 45 +first_layer_speed = 20 +support_material_threshold = 45 +raft_first_layer_density = 80% +## gcode_substitutions = "; stop printing object\\s(.*)\\s+id:(\\d+)\\s+.*";"$0\\nM486 S-1\\n";r;;"; printing object\\s(.*)\\s+id:(\\d+)\\s+.*";"$0\\nM486 S$2\\nM486 N$1\\n";r; +output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{printing_filament_types}_{printer_model}_{print_time}.gcode + [print:*MK306*] inherits = *MK3* fill_pattern = gyroid @@ -363,6 +396,9 @@ infill_anchor = 1 perimeters = 3 brim_separation = 0 +[print:*0.25nozzleMK4*] +inherits = *0.25nozzleXL* + [print:*0.3nozzle*] external_perimeter_extrusion_width = 0.33 extrusion_width = 0.33 @@ -434,6 +470,9 @@ fill_density = 20% support_material_interface_spacing = 0.25 infill_anchor = 2.5 +[print:*0.6nozzleMK4*] +inherits = *0.6nozzleXL* + [print:*0.6nozzleMINI*] inherits = *0.6nozzleMK3* infill_extrusion_width = 0.68 @@ -502,6 +541,13 @@ support_material_style = snug raft_first_layer_expansion = 2 default_acceleration = 1250 infill_anchor = 2.5 +first_layer_acceleration = 500 + +[print:*0.8nozzleMK4*] +inherits = *0.8nozzleXL* +default_acceleration = 1000 +infill_acceleration = 2000 +first_layer_acceleration = 600 [print:*soluble_support*] overhangs = 1 @@ -1848,7 +1894,7 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.25 [print:0.05mm ULTRADETAIL @XL 0.3] inherits = *0.05mm*; *XL*; *0.3nozzle* -top_solid_layers = 12 +top_solid_layers = 14 bottom_solid_layers = 9 support_material_contact_distance = 0.07 raft_contact_distance = 0.07 @@ -1987,6 +2033,8 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.3 [print:0.07mm ULTRADETAIL @XL 0.4] inherits = *0.07mm*; *XL* +thick_bridges = 1 +bridge_flow_ratio = 0.6 top_infill_extrusion_width = 0.4 first_layer_extrusion_width = 0.45 perimeter_extrusion_width = 0.4 @@ -2173,13 +2221,13 @@ bridge_acceleration = 1000 first_layer_acceleration = 600 default_acceleration = 1250 max_print_speed = 200 -external_perimeter_extrusion_width = 0.55 -extrusion_width = 0.55 +external_perimeter_extrusion_width = 0.5 +extrusion_width = 0.5 first_layer_extrusion_width = 0.5 -infill_extrusion_width = 0.55 -perimeter_extrusion_width = 0.55 -solid_infill_extrusion_width = 0.55 -top_infill_extrusion_width = 0.42 +infill_extrusion_width = 0.5 +perimeter_extrusion_width = 0.5 +solid_infill_extrusion_width = 0.5 +top_infill_extrusion_width = 0.45 support_material_extrusion_width = 0.38 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.4 @@ -2311,6 +2359,7 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.5 [print:0.15mm DETAIL @XL 0.6] inherits = *0.15mm*; *XL*; *0.6nozzleXL* +fill_pattern = gyroid perimeter_speed = 45 external_perimeter_speed = 30 small_perimeter_speed = 30 @@ -2345,6 +2394,7 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.6 [print:0.20mm DETAIL @XL 0.6] inherits = *0.20mm*; *XL*; *0.6nozzleXL* +fill_pattern = gyroid perimeter_speed = 50 external_perimeter_speed = 35 small_perimeter_speed = 30 @@ -2425,7 +2475,7 @@ external_perimeter_acceleration = 1000 perimeter_acceleration = 1200 solid_infill_acceleration = 2000 infill_acceleration = 3000 -top_solid_layers = 4 +top_solid_layers = 5 bottom_solid_layers = 4 default_acceleration = 1250 dynamic_overhang_speeds = 35,20,15,15 @@ -2603,6 +2653,910 @@ top_solid_infill_acceleration = 800 solid_infill_acceleration = 2000 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 +## MK4 ## + +## MK4 - 0.25mm nozzle + +[print:0.05mm ULTRADETAIL @MK4 0.25] +inherits = *0.05mm*; *MK4*; *0.25nozzleMK4* +support_material_contact_distance = 0.07 +raft_contact_distance = 0.1 +perimeter_speed = 30 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 40 +solid_infill_speed = 40 +top_solid_infill_speed = 25 +support_material_speed = 30 +support_material_interface_speed = 80% +gap_fill_speed = 25 +gcode_resolution = 0.006 +external_perimeter_acceleration = 300 +perimeter_acceleration = 300 +top_solid_infill_acceleration = 600 +solid_infill_acceleration = 800 +infill_acceleration = 800 +bridge_acceleration = 300 +first_layer_acceleration = 600 +default_acceleration = 800 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.25 + +[print:0.07mm ULTRADETAIL @MK4 0.25] +inherits = *0.07mm*; *MK4*; *0.25nozzleMK4* +perimeter_speed = 30 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 45 +solid_infill_speed = 45 +top_solid_infill_speed = 35 +support_material_speed = 30 +support_material_interface_speed = 80% +support_material_contact_distance = 0.07 +gap_fill_speed = 25 +bridge_speed = 20 +external_perimeter_acceleration = 300 +perimeter_acceleration = 300 +top_solid_infill_acceleration = 500 +solid_infill_acceleration = 800 +infill_acceleration = 1000 +bridge_acceleration = 300 +first_layer_acceleration = 600 +default_acceleration = 800 +max_print_speed = 200 +gcode_resolution = 0.006 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.25 + +[print:0.10mm QUALITY @MK4 0.25] +inherits = *0.10mm*; *MK4*; *0.25nozzleMK4* +perimeter_speed = 35 +external_perimeter_speed = 20 +small_perimeter_speed = 25 +infill_speed = 60 +solid_infill_speed = 60 +top_solid_infill_speed = 30 +support_material_speed = 40 +support_material_interface_speed = 85% +support_material_contact_distance = 0.07 +gap_fill_speed = 30 +bridge_speed = 20 +external_perimeter_acceleration = 400 +perimeter_acceleration = 500 +top_solid_infill_acceleration = 600 +solid_infill_acceleration = 800 +infill_acceleration = 1200 +bridge_acceleration = 500 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.25 + +[print:0.12mm QUALITY @MK4 0.25] +inherits = *0.12mm*; *MK4*; *0.25nozzleMK4* +perimeter_speed = 30 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 60 +solid_infill_speed = 60 +top_solid_infill_speed = 30 +support_material_speed = 50 +support_material_interface_speed = 80% +support_material_contact_distance = 0.08 +gap_fill_speed = 40 +bridge_speed = 25 +external_perimeter_acceleration = 500 +perimeter_acceleration = 500 +top_solid_infill_acceleration = 600 +solid_infill_acceleration = 1000 +infill_acceleration = 1200 +bridge_acceleration = 500 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +gcode_resolution = 0.008 +perimeter_extrusion_width = 0.27 +external_perimeter_extrusion_width = 0.27 +infill_extrusion_width = 0.27 +solid_infill_extrusion_width = 0.27 +top_infill_extrusion_width = 0.25 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.25 + +[print:0.15mm SPEED @MK4 0.25] +inherits = *0.15mm*; *MK4*; *0.25nozzleMK4* +perimeter_speed = 35 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 80 +solid_infill_speed = 60 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 80% +support_material_contact_distance = 0.08 +gap_fill_speed = 45 +bridge_speed = 25 +external_perimeter_acceleration = 500 +perimeter_acceleration = 500 +top_solid_infill_acceleration = 600 +solid_infill_acceleration = 1000 +infill_acceleration = 1200 +bridge_acceleration = 500 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.3 +perimeter_extrusion_width = 0.27 +external_perimeter_extrusion_width = 0.27 +infill_extrusion_width = 0.27 +solid_infill_extrusion_width = 0.27 +top_infill_extrusion_width = 0.25 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.25 + +## MK4 - 0.3mm nozzle + +[print:0.05mm ULTRADETAIL @MK4 0.3] +inherits = *0.05mm*; *MK4*; *0.3nozzle* +top_solid_layers = 14 +bottom_solid_layers = 9 +support_material_contact_distance = 0.07 +raft_contact_distance = 0.07 +perimeter_speed = 25 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 45 +solid_infill_speed = 45 +top_solid_infill_speed = 35 +support_material_speed = 40 +support_material_interface_speed = 80% +gap_fill_speed = 25 +gcode_resolution = 0.006 +external_perimeter_acceleration = 300 +perimeter_acceleration = 300 +top_solid_infill_acceleration = 600 +solid_infill_acceleration = 800 +infill_acceleration = 800 +bridge_acceleration = 500 +default_acceleration = 800 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.3 + +[print:0.08mm DETAIL @MK4 0.3] +inherits = *0.07mm*; *MK4*; *0.3nozzle* +layer_height = 0.08 +support_material_contact_distance = 0.08 +raft_contact_distance = 0.08 +perimeter_speed = 30 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 60 +solid_infill_speed = 60 +top_solid_infill_speed = 35 +support_material_speed = 40 +support_material_interface_speed = 80% +gap_fill_speed = 25 +bridge_speed = 20 +external_perimeter_acceleration = 500 +perimeter_acceleration = 600 +top_solid_infill_acceleration = 700 +solid_infill_acceleration = 800 +infill_acceleration = 1000 +bridge_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +perimeters = 3 +gcode_resolution = 0.006 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.3 + +[print:0.12mm QUALITY @MK4 0.3] +inherits = *0.12mm*; *MK4*; *0.3nozzle* +support_material_contact_distance = 0.1 +raft_contact_distance = 0.1 +perimeter_speed = 35 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 80 +solid_infill_speed = 80 +top_solid_infill_speed = 30 +support_material_speed = 45 +support_material_interface_speed = 85% +gap_fill_speed = 40 +bridge_speed = 25 +external_perimeter_acceleration = 600 +perimeter_acceleration = 800 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1200 +infill_acceleration = 1500 +bridge_acceleration = 800 +default_acceleration = 1000 +max_print_speed = 200 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.3 + +[print:0.16mm SPEED @MK4 0.3] +inherits = *0.16mm*; *MK4*; *0.3nozzle* +support_material_contact_distance = 0.15 +raft_contact_distance = 0.15 +perimeter_speed = 50 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 90 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +support_material_speed = 45 +support_material_interface_speed = 80% +gap_fill_speed = 40 +bridge_speed = 25 +external_perimeter_acceleration = 600 +perimeter_acceleration = 800 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1250 +bridge_acceleration = 800 +default_acceleration = 1000 +max_print_speed = 200 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.3 + +[print:0.20mm DRAFT @MK4 0.3] +inherits = *0.20mm*; *MK4*; *0.3nozzle* +support_material_contact_distance = 0.18 +raft_contact_distance = 0.18 +perimeter_speed = 50 +external_perimeter_speed = 35 +small_perimeter_speed = 30 +infill_speed = 90 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 80% +gap_fill_speed = 45 +bridge_speed = 25 +external_perimeter_acceleration = 700 +perimeter_acceleration = 800 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1250 +bridge_acceleration = 800 +default_acceleration = 1250 +max_print_speed = 200 +first_layer_extrusion_width = 0.4 +perimeter_extrusion_width = 0.35 +external_perimeter_extrusion_width = 0.35 +infill_extrusion_width = 0.35 +solid_infill_extrusion_width = 0.35 +top_infill_extrusion_width = 0.3 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.3 + +## MK4 - 0.4mm nozzle + +[print:0.05mm ULTRADETAIL @MK4 0.4] +inherits = *0.05mm*; *MK4* +thick_bridges = 1 +bridge_flow_ratio = 0.6 +top_infill_extrusion_width = 0.4 +first_layer_extrusion_width = 0.45 +perimeter_extrusion_width = 0.4 +external_perimeter_extrusion_width = 0.4 +infill_extrusion_width = 0.4 +solid_infill_extrusion_width = 0.4 +perimeters = 3 +support_material_contact_distance = 0.1 +raft_contact_distance = 0.1 +perimeter_speed = 30 +external_perimeter_speed = 20 +small_perimeter_speed = 20 +infill_speed = 40 +solid_infill_speed = 40 +top_solid_infill_speed = 30 +support_material_style = snug +support_material_interface_layers = 0 +support_material_speed = 30 +support_material_interface_speed = 80% +support_material_spacing = 1.5 +gap_fill_speed = 25 +gcode_resolution = 0.006 +external_perimeter_acceleration = 300 +perimeter_acceleration = 300 +top_solid_infill_acceleration = 500 +solid_infill_acceleration = 700 +infill_acceleration = 800 +bridge_acceleration = 300 +default_acceleration = 800 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.07mm ULTRADETAIL @MK4 0.4] +inherits = *0.07mm*; *MK4* +thick_bridges = 1 +bridge_flow_ratio = 0.6 +top_infill_extrusion_width = 0.4 +first_layer_extrusion_width = 0.45 +perimeter_extrusion_width = 0.4 +external_perimeter_extrusion_width = 0.4 +infill_extrusion_width = 0.4 +solid_infill_extrusion_width = 0.4 +perimeters = 3 +support_material_contact_distance = 0.1 +raft_contact_distance = 0.1 +perimeter_speed = 35 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 45 +solid_infill_speed = 45 +top_solid_infill_speed = 30 +support_material_style = snug +support_material_interface_layers = 0 +support_material_speed = 35 +support_material_interface_speed = 80% +support_material_spacing = 1.5 +gap_fill_speed = 25 +gcode_resolution = 0.006 +external_perimeter_acceleration = 300 +perimeter_acceleration = 300 +top_solid_infill_acceleration = 500 +solid_infill_acceleration = 800 +infill_acceleration = 800 +bridge_acceleration = 300 +first_layer_acceleration = 600 +default_acceleration = 800 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.10mm DETAIL @MK4 0.4] +inherits = *0.10mm*; *MK4* +support_material_contact_distance = 0.17 +raft_contact_distance = 0.15 +perimeter_speed = 45 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 80 +solid_infill_speed = 80 +top_solid_infill_speed = 35 +support_material_style = snug +support_material_interface_layers = 5 +support_material_speed = 40 +support_material_interface_speed = 85% +support_material_xy_spacing = 80% +gap_fill_speed = 40 +bridge_speed = 20 +external_perimeter_acceleration = 500 +perimeter_acceleration = 700 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1250 +infill_acceleration = 1500 +bridge_acceleration = 700 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.5 +perimeter_extrusion_width = 0.4 +external_perimeter_extrusion_width = 0.4 +infill_extrusion_width = 0.4 +solid_infill_extrusion_width = 0.4 +top_infill_extrusion_width = 0.4 +perimeters = 3 +gcode_resolution = 0.006 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.15mm QUALITY @MK4 0.4] +inherits = *0.15mm*; *MK4* +perimeter_speed = 45 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 90 +solid_infill_speed = 90 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.2 +raft_contact_distance = 0.15 +support_material_style = snug +support_material_interface_layers = 5 +support_material_speed = 45 +support_material_interface_speed = 80% +support_material_xy_spacing = 80% +gap_fill_speed = 40 +bridge_speed = 25 +external_perimeter_acceleration = 700 +perimeter_acceleration = 900 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +bridge_acceleration = 1000 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.5 +support_material_extrusion_width = 0.37 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.15mm SPEED @MK4 0.4] +inherits = *0.15mm*; *MK4* +perimeter_speed = 70 +external_perimeter_speed = 40 +small_perimeter_speed = 35 +infill_speed = 200 +solid_infill_speed = 200 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.2 +raft_contact_distance = 0.15 +support_material_style = snug +support_material_interface_layers = 5 +support_material_speed = 45 +support_material_interface_speed = 80% +support_material_xy_spacing = 80% +gap_fill_speed = 40 +bridge_speed = 25 +external_perimeter_acceleration = 800 +perimeter_acceleration = 1000 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +bridge_acceleration = 1000 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.5 +support_material_extrusion_width = 0.37 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.20mm QUALITY @MK4 0.4] +inherits = *0.20mm*; *MK4* +perimeter_speed = 45 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 90 +solid_infill_speed = 90 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.2 +raft_contact_distance = 0.2 +support_material_style = snug +support_material_interface_layers = 5 +support_material_xy_spacing = 80% +support_material_speed = 50 +support_material_interface_speed = 70% +gap_fill_speed = 40 +bridge_speed = 25 +external_perimeter_acceleration = 700 +perimeter_acceleration = 900 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +bridge_acceleration = 1000 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.5 +gcode_resolution = 0.008 +support_material_extrusion_width = 0.37 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.20mm SPEED @MK4 0.4] +inherits = *0.20mm*; *MK4* +perimeter_speed = 70 +external_perimeter_speed = 40 +small_perimeter_speed = 35 +infill_speed = 200 +solid_infill_speed = 200 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.2 +raft_contact_distance = 0.2 +support_material_style = snug +support_material_interface_layers = 5 +support_material_speed = 50 +support_material_interface_speed = 70% +support_material_xy_spacing = 80% +gap_fill_speed = 45 +bridge_speed = 25 +external_perimeter_acceleration = 800 +perimeter_acceleration = 1000 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +bridge_acceleration = 1000 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.5 +support_material_extrusion_width = 0.37 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +[print:0.30mm DRAFT @MK4 0.4] +inherits = *0.30mm*; *MK4* +bottom_solid_layers = 3 +perimeter_speed = 70 +external_perimeter_speed = 40 +small_perimeter_speed = 40 +infill_speed = 95 +solid_infill_speed = 85 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.2 +raft_contact_distance = 0.2 +support_material_style = snug +support_material_interface_layers = 5 +support_material_speed = 60 +support_material_interface_speed = 70% +support_material_xy_spacing = 80% +gap_fill_speed = 45 +bridge_speed = 25 +external_perimeter_acceleration = 1000 +perimeter_acceleration = 1100 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1700 +infill_acceleration = 2000 +bridge_acceleration = 1000 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +external_perimeter_extrusion_width = 0.5 +extrusion_width = 0.5 +first_layer_extrusion_width = 0.5 +infill_extrusion_width = 0.5 +perimeter_extrusion_width = 0.5 +solid_infill_extrusion_width = 0.5 +top_infill_extrusion_width = 0.45 +support_material_extrusion_width = 0.38 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.4 + +## MK4 - 0.5mm nozzle + +[print:0.10mm DETAIL @MK4 0.5] +inherits = *0.10mm*; *MK4*; *0.5nozzle* +fill_pattern = gyroid +perimeter_speed = 40 +external_perimeter_speed = 25 +small_perimeter_speed = 25 +infill_speed = 80 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 85% +support_material_style = snug +support_material_interface_layers = 4 +gap_fill_speed = 40 +bridge_speed = 30 +external_perimeter_acceleration = 700 +perimeter_acceleration = 800 +solid_infill_acceleration = 1200 +infill_acceleration = 1500 +bridge_acceleration = 1000 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +first_layer_extrusion_width = 0.5 +perimeter_extrusion_width = 0.5 +external_perimeter_extrusion_width = 0.5 +infill_extrusion_width = 0.5 +solid_infill_extrusion_width = 0.5 +top_infill_extrusion_width = 0.45 +perimeters = 2 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.5 + +[print:0.15mm QUALITY @MK4 0.5] +inherits = *0.15mm*; *MK4*; *0.5nozzle* +fill_pattern = gyroid +perimeter_speed = 45 +external_perimeter_speed = 30 +small_perimeter_speed = 25 +infill_speed = 120 +solid_infill_speed = 120 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 70% +support_material_style = snug +support_material_interface_layers = 4 +gap_fill_speed = 40 +bridge_speed = 30 +external_perimeter_acceleration = 800 +perimeter_acceleration = 900 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +bridge_acceleration = 1000 +first_layer_acceleration = 600 +default_acceleration = 1000 +max_print_speed = 200 +gcode_resolution = 0.008 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.5 + +[print:0.20mm QUALITY @MK4 0.5] +inherits = 0.15mm QUALITY @MK4 0.5; *0.20mm*; *MK4*; *0.5nozzle* +perimeter_speed = 50 +external_perimeter_speed = 35 +small_perimeter_speed = 30 +gcode_resolution = 0.01 +support_material_interface_layers = 4 +infill_speed = 200 +solid_infill_speed = 120 +support_material_speed = 50 +support_material_interface_speed = 70% +external_perimeter_acceleration = 800 +perimeter_acceleration = 900 +infill_acceleration = 2000 +default_acceleration = 1000 +max_print_speed = 200 + +[print:0.25mm SPEED @MK4 0.5] +inherits = *0.25mm*; *MK4*; *0.5nozzle* +bottom_solid_layers = 3 +perimeter_speed = 70 +external_perimeter_speed = 40 +small_perimeter_speed = 35 +infill_speed = 200 +solid_infill_speed = 100 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 75% +support_material_style = snug +support_material_interface_layers = 4 +support_material_contact_distance = 0.25 +raft_contact_distance = 0.25 +gap_fill_speed = 45 +bridge_speed = 25 +external_perimeter_acceleration = 900 +perimeter_acceleration = 1000 +infill_acceleration = 2000 +bridge_acceleration = 800 +default_acceleration = 1000 +max_print_speed = 200 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.5 + +[print:0.32mm DRAFT @MK4 0.5] +inherits = *0.32mm*; *MK4*; *0.5nozzle* +bottom_solid_layers = 3 +perimeter_speed = 70 +external_perimeter_speed = 45 +small_perimeter_speed = 40 +infill_speed = 200 +solid_infill_speed = 100 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 75% +support_material_style = snug +support_material_interface_layers = 4 +support_material_contact_distance = 0.3 +support_material_extrusion_width = 0.42 +raft_contact_distance = 0.3 +gap_fill_speed = 45 +bridge_speed = 25 +external_perimeter_acceleration = 1000 +perimeter_acceleration = 1000 +infill_acceleration = 2000 +bridge_acceleration = 1000 +default_acceleration = 1000 +max_print_speed = 200 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.5 + +## MK4 - 0.6mm nozzle + +[print:0.15mm DETAIL @MK4 0.6] +inherits = *0.15mm*; *MK4*; *0.6nozzleMK4* +fill_pattern = gyroid +perimeter_speed = 45 +external_perimeter_speed = 30 +small_perimeter_speed = 30 +infill_speed = 100 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.22 +raft_contact_distance = 0.2 +support_material_style = snug +support_material_interface_layers = 4 +support_material_speed = 50 +support_material_interface_speed = 80% +gap_fill_speed = 40 +bridge_speed = 25 +extrusion_width = 0.65 +external_perimeter_extrusion_width = 0.6 +first_layer_extrusion_width = 0.65 +infill_extrusion_width = 0.6 +perimeter_extrusion_width = 0.6 +solid_infill_extrusion_width = 0.6 +top_infill_extrusion_width = 0.5 +support_material_extrusion_width = 0.5 +external_perimeter_acceleration = 800 +perimeter_acceleration = 800 +infill_acceleration = 2000 +bridge_acceleration = 800 +default_acceleration = 1000 +bridge_flow_ratio = 1 +max_print_speed = 200 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[print:0.20mm DETAIL @MK4 0.6] +inherits = *0.20mm*; *MK4*; *0.6nozzleMK4* +fill_pattern = gyroid +perimeter_speed = 50 +external_perimeter_speed = 35 +small_perimeter_speed = 30 +infill_speed = 120 +solid_infill_speed = 80 +support_material_contact_distance = 0.22 +raft_contact_distance = 0.2 +support_material_style = snug +support_material_interface_layers = 4 +top_solid_infill_speed = 40 +support_material_speed = 50 +support_material_interface_speed = 80% +gap_fill_speed = 40 +bridge_speed = 25 +extrusion_width = 0.65 +external_perimeter_extrusion_width = 0.6 +first_layer_extrusion_width = 0.65 +infill_extrusion_width = 0.6 +perimeter_extrusion_width = 0.6 +solid_infill_extrusion_width = 0.6 +top_infill_extrusion_width = 0.5 +support_material_extrusion_width = 0.5 +external_perimeter_acceleration = 800 +perimeter_acceleration = 900 +infill_acceleration = 2000 +default_acceleration = 1000 +bridge_flow_ratio = 1 +max_print_speed = 200 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[print:0.25mm QUALITY @MK4 0.6] +inherits = *0.25mm*; *MK4*; *0.6nozzleMK4* +perimeter_speed = 60 +external_perimeter_speed = 35 +small_perimeter_speed = 30 +infill_speed = 200 +solid_infill_speed = 80 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.25 +raft_contact_distance = 0.25 +support_material_style = snug +support_material_interface_layers = 4 +support_material_speed = 50 +support_material_interface_speed = 75% +gap_fill_speed = 40 +bridge_speed = 25 +extrusion_width = 0.65 +top_infill_extrusion_width = 0.55 +support_material_extrusion_width = 0.5 +external_perimeter_acceleration = 800 +perimeter_acceleration = 1000 +infill_acceleration = 2000 +bridge_acceleration = 1000 +default_acceleration = 1000 +bridge_flow_ratio = 1 +top_solid_layers = 5 +bottom_solid_layers = 4 +max_print_speed = 200 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[print:0.32mm SPEED @MK4 0.6] +inherits = *0.32mm*; *MK4*; *0.6nozzleMK4* +perimeter_speed = 65 +external_perimeter_speed = 40 +small_perimeter_speed = 35 +infill_speed = 200 +solid_infill_speed = 70 +top_solid_infill_speed = 45 +support_material_contact_distance = 0.25 +raft_contact_distance = 0.25 +support_material_style = snug +support_material_interface_layers = 4 +support_material_speed = 50 +support_material_interface_speed = 75% +gap_fill_speed = 50 +bridge_speed = 25 +extrusion_width = 0.68 +external_perimeter_extrusion_width = 0.68 +first_layer_extrusion_width = 0.65 +infill_extrusion_width = 0.68 +perimeter_extrusion_width = 0.68 +solid_infill_extrusion_width = 0.68 +top_infill_extrusion_width = 0.55 +support_material_extrusion_width = 0.5 +external_perimeter_acceleration = 800 +perimeter_acceleration = 1000 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +first_layer_acceleration = 600 +default_acceleration = 1000 +bridge_flow_ratio = 0.95 +max_print_speed = 200 +bottom_solid_layers = 3 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[print:0.40mm DRAFT @MK4 0.6] +inherits = *0.40mm*; *MK4*; *0.6nozzleMK4* +perimeter_speed = 60 +external_perimeter_speed = 40 +small_perimeter_speed = 35 +infill_speed = 200 +solid_infill_speed = 55 +top_solid_infill_speed = 40 +support_material_contact_distance = 0.25 +raft_contact_distance = 0.25 +support_material_style = snug +support_material_interface_layers = 4 +support_material_speed = 50 +support_material_interface_speed = 80% +gap_fill_speed = 40 +bridge_speed = 25 +extrusion_width = 0.68 +external_perimeter_extrusion_width = 0.68 +first_layer_extrusion_width = 0.65 +infill_extrusion_width = 0.68 +perimeter_extrusion_width = 0.68 +solid_infill_extrusion_width = 0.68 +top_infill_extrusion_width = 0.6 +support_material_extrusion_width = 0.5 +external_perimeter_acceleration = 900 +perimeter_acceleration = 1000 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +default_acceleration = 1500 +bridge_flow_ratio = 0.95 +dynamic_overhang_speeds = 30,20,15,15 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +## MK4 - 0.8mm nozzle + +[print:0.30mm DETAIL @MK4 0.8] +inherits = *0.30mm*; *MK4*; *0.8nozzleMK4* +perimeter_speed = 45 +external_perimeter_speed = 30 +small_perimeter_speed = 30 +infill_speed = 70 +solid_infill_speed = 50 +support_material_speed = 40 +support_material_interface_speed = 90% +top_solid_infill_speed = 35 +bridge_speed = 22 +gap_fill_speed = 30 +top_infill_extrusion_width = 0.75 +support_material_extrusion_width = 0.7 +external_perimeter_acceleration = 800 +perimeter_acceleration = 1000 +bridge_acceleration = 1000 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 + +[print:0.40mm QUALITY @MK4 0.8] +inherits = *0.40mm*; *MK4*; *0.8nozzleMK4* +perimeter_speed = 45 +external_perimeter_speed = 35 +small_perimeter_speed = 30 +infill_speed = 65 +solid_infill_speed = 45 +top_solid_infill_speed = 35 +support_material_speed = 40 +support_material_interface_speed = 90% +bridge_speed = 22 +gap_fill_speed = 30 +top_infill_extrusion_width = 0.8 +support_material_extrusion_width = 0.7 +external_perimeter_acceleration = 800 +perimeter_acceleration = 1000 +bridge_acceleration = 1000 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 + +[print:0.55mm DRAFT @MK4 0.8] +inherits = *MK4*; *0.8nozzleMK4* +layer_height = 0.55 +top_solid_layers = 4 +bottom_solid_layers = 3 +perimeter_speed = 40 +external_perimeter_speed = 30 +small_perimeter_speed = 30 +infill_speed = 55 +solid_infill_speed = 35 +top_solid_infill_speed = 30 +support_material_speed = 35 +support_material_interface_speed = 90% +bridge_speed = 22 +gap_fill_speed = 30 +top_infill_extrusion_width = 0.8 +support_material_extrusion_width = 0.7 +perimeter_extrusion_width = 1 +external_perimeter_extrusion_width = 1 +external_perimeter_acceleration = 1000 +perimeter_acceleration = 1000 +bridge_acceleration = 1000 +top_solid_infill_acceleration = 800 +solid_infill_acceleration = 1500 +infill_acceleration = 2000 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 + # XXXXXXxxXXXXXXXXXXXXXX # XXX--- filament ---XXX # XXXXXXXXxxXXXXXXXXXXXX @@ -2611,7 +3565,7 @@ compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 cooling = 1 compatible_printers = # For now, all but selected filaments are disabled for the MMU 2.0 -compatible_printers_condition = ! single_extruder_multi_material and printer_model!="XL" +compatible_printers_condition = ! single_extruder_multi_material and printer_notes!~/.*PG.*/ end_filament_gcode = "; Filament-specific end gcode" extrusion_multiplier = 1 filament_loading_speed = 28 @@ -2654,11 +3608,11 @@ min_fan_speed = 100 temperature = 210 slowdown_below_layer_time = 10 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0" -compatible_printers_condition = ! single_extruder_multi_material and printer_model!="XL" +compatible_printers_condition = ! single_extruder_multi_material and printer_notes!~/.*PG.*/ [filament:*PLAPG*] start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.06{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.08{elsif nozzle_diameter[0]==0.35}0.07{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S36 ; set heatbreak target temp" -compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 +compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 slowdown_below_layer_time = 8 filament_cooling_final_speed = 2 filament_cooling_initial_speed = 3 @@ -2675,13 +3629,13 @@ filament_unloading_speed_start = 100 [filament:*PLA06PG*] inherits = *PLAPG* -compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.6 +compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 15.5 slowdown_below_layer_time = 10 [filament:*PLA08PG*] inherits = *PLAPG* -compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 +compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]==0.8 filament_max_volumetric_speed = 19 slowdown_below_layer_time = 18 @@ -2704,15 +3658,15 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no temperature = 240 filament_retract_length = 1 filament_retract_lift = 0.2 -compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:*PET06*] inherits = *PET* -compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) filament_max_volumetric_speed = 15 [filament:*PETPG*] -compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 +compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 filament_max_volumetric_speed = 10 start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.08{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.1{elsif nozzle_diameter[0]==0.35}0.09{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S40 ; set heatbreak target temp" filament_cooling_final_speed = 1 @@ -2733,24 +3687,25 @@ slowdown_below_layer_time = 9 [filament:*PET06PG*] inherits = *PETPG* -compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.6 +compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]==0.6 filament_max_volumetric_speed = 17 slowdown_below_layer_time = 12 +filament_retract_length = 0.9 [filament:*PET08PG*] inherits = *PETPG* -compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 +compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]==0.8 filament_max_volumetric_speed = 22 slowdown_below_layer_time = 18 +filament_retract_length = 0.8 [filament:*04PLUS*] -compatible_printers_condition = nozzle_diameter[0]>=0.4 and ! single_extruder_multi_material and printer_model!="XL" +compatible_printers_condition = nozzle_diameter[0]>=0.4 and ! single_extruder_multi_material and printer_notes!~/.*PG.*/ [filament:*04PLUSPG*] -compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="XL" +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ [filament:*PETMMU1*] -# inherits = *PET* filament_retract_length = nil filament_retract_speed = nil filament_retract_lift = 0.2 @@ -2834,7 +3789,7 @@ max_fan_speed = 30 min_fan_speed = 20 temperature = 255 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.02{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0" -compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:*ABSC*] inherits = *common* @@ -2856,7 +3811,7 @@ min_fan_speed = 15 min_print_speed = 15 temperature = 255 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.02{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0" -compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:*ABSPG*] compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 @@ -2884,6 +3839,21 @@ filament_max_volumetric_speed = 18 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 slowdown_below_layer_time = 25 +[filament:*ABSMK4*] +inherits = *ABSPG* +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 + +[filament:*ABS06MK4*] +inherits = *ABSMK4* +filament_max_volumetric_speed = 15 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[filament:*ABS08MK4*] +inherits = *ABSMK4* +filament_max_volumetric_speed = 18 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 +slowdown_below_layer_time = 25 + [filament:*PCPG*] inherits = *ABSPG* filament_max_volumetric_speed = 8 @@ -2902,6 +3872,22 @@ inherits = *PCPG* filament_max_volumetric_speed = 20 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 +[filament:*PCMK4*] +inherits = *ABSMK4* +filament_max_volumetric_speed = 8 +start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S45 ; set heatbreak target temp\n" +## idle_temperature = 170 + +[filament:*PC06MK4*] +inherits = *PCMK4* +filament_max_volumetric_speed = 14 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[filament:*PC08MK4*] +inherits = *PCMK4* +filament_max_volumetric_speed = 20 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 + [filament:*PAPG*] inherits = *ABSPG* filament_max_volumetric_speed = 5 @@ -2910,21 +3896,37 @@ bed_temperature = 105 ## idle_temperature = 170 [filament:*PA06PG*] -inherits = *PCPG* +inherits = *PAPG* filament_max_volumetric_speed = 7 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.6 [filament:*PA08PG*] -inherits = *PCPG* +inherits = *PAPG* filament_max_volumetric_speed = 10 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 +[filament:*PAMK4*] +inherits = *ABSMK4* +filament_max_volumetric_speed = 5 +start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S45 ; set heatbreak target temp\n" +## idle_temperature = 170 + +[filament:*PA06MK4*] +inherits = *PAMK4* +filament_max_volumetric_speed = 7 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[filament:*PA08MK4*] +inherits = *PAMK4* +filament_max_volumetric_speed = 10 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 + [filament:*FLEX*] inherits = *common* bed_temperature = 50 bridge_fan_speed = 80 # For now, all but selected filaments are disabled for the MMU 2.0 -compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) cooling = 0 disable_fan_first_layers = 3 extrusion_multiplier = 1.15 @@ -2945,7 +3947,7 @@ filament_retract_lift = 0 filament_wipe = 0 [filament:*FLEXPG*] -filament_max_volumetric_speed = 4 +filament_max_volumetric_speed = 3.5 filament_retract_speed = 60 filament_deretract_speed = 20 filament_retract_before_travel = 2 @@ -2955,14 +3957,33 @@ start_filament_gcode = "M900 K0 ; Filament gcode\n\nM142 S36 ; set heatbreak tar [filament:*FLEX06PG*] inherits = *FLEXPG* -filament_max_volumetric_speed = 6.5 +filament_max_volumetric_speed = 4.5 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.6 [filament:*FLEX08PG*] inherits = *FLEXPG* -filament_max_volumetric_speed = 9 +filament_max_volumetric_speed = 8 compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 +[filament:*FLEXMK4*] +filament_max_volumetric_speed = 4 +filament_retract_speed = 60 +filament_deretract_speed = 20 +filament_retract_before_travel = 2 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]>=0.3 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 +## idle_temperature = 170 +start_filament_gcode = "M900 K0 ; Filament gcode\n\nM142 S36 ; set heatbreak target temp" + +[filament:*FLEX06MK4*] +inherits = *FLEXMK4* +filament_max_volumetric_speed = 6.5 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[filament:*FLEX08MK4*] +inherits = *FLEXMK4* +filament_max_volumetric_speed = 9 +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 + [filament:ColorFabb bronzeFill] inherits = *PLA*; *04PLUS* filament_vendor = ColorFabb @@ -3049,12 +4070,27 @@ temperature = 270 inherits = ColorFabb HT; *PETPG* first_layer_bed_temperature = 100 bed_temperature = 105 +compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 [filament:ColorFabb HT @PG 0.6] inherits = ColorFabb HT @PG; *PET06PG* +compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.6 [filament:ColorFabb HT @PG 0.8] inherits = ColorFabb HT @PG; *PET08PG* +compatible_printers_condition = printer_model=="XL" and nozzle_diameter[0]==0.8 + +[filament:ColorFabb HT @MK4] +inherits = ColorFabb HT; *PETPG* +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 + +[filament:ColorFabb HT @MK4 0.6] +inherits = ColorFabb HT @MK4; *PET06PG* +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.6 + +[filament:ColorFabb HT @MK4 0.8] +inherits = ColorFabb HT @MK4; *PET08PG* +compatible_printers_condition = printer_model=="MK4" and nozzle_diameter[0]==0.8 [filament:ColorFabb PLA-PHA] inherits = *PLA* @@ -3160,7 +4196,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no temperature = 260 filament_retract_length = nil filament_retract_lift = 0.4 -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:ColorFabb XT-CF20 @PG] inherits = ColorFabb XT-CF20; *PETPG*; *04PLUSPG* @@ -3217,19 +4253,32 @@ min_fan_speed = 20 temperature = 260 filament_retract_length = nil filament_retract_lift = 0 -compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MINI" and printer_model!="XL" and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and num_extruders==1 && ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and single_extruder_multi_material) [filament:ColorFabb nGen flex @PG] inherits = ColorFabb nGen flex; *FLEXPG* -filament_max_volumetric_speed = 7 +filament_max_volumetric_speed = 6 filament_retract_length = 2.5 [filament:ColorFabb nGen flex @PG 0.6] inherits = ColorFabb nGen flex; *FLEX06PG* -filament_max_volumetric_speed = 9 +filament_max_volumetric_speed = 7 [filament:ColorFabb nGen flex @PG 0.8] inherits = ColorFabb nGen flex; *FLEX08PG* +filament_max_volumetric_speed = 10 + +[filament:ColorFabb nGen flex @MK4] +inherits = ColorFabb nGen flex; *FLEXMK4* +filament_max_volumetric_speed = 7 +filament_retract_length = 2.5 + +[filament:ColorFabb nGen flex @MK4 0.6] +inherits = ColorFabb nGen flex; *FLEX06MK4* +filament_max_volumetric_speed = 9 + +[filament:ColorFabb nGen flex @MK4 0.8] +inherits = ColorFabb nGen flex; *FLEX08MK4* filament_max_volumetric_speed = 12 [filament:Kimya PETG Carbon] @@ -3246,7 +4295,7 @@ temperature = 240 filament_retract_length = nil filament_retract_lift = 0.3 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.06{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0" -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Kimya PETG Carbon @PG] inherits = Kimya PETG Carbon; *PETPG*; *04PLUSPG* @@ -3268,12 +4317,13 @@ filament_colour = #804040 filament_max_volumetric_speed = 6 first_layer_temperature = 260 temperature = 260 -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Kimya ABS Carbon @PG] inherits = Kimya ABS Carbon; *ABSPG*; *04PLUSPG* bed_temperature = 105 filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="XL" [filament:Kimya ABS Carbon @PG 0.6] inherits = Kimya ABS Carbon @PG; *ABS06PG* @@ -3283,6 +4333,19 @@ filament_max_volumetric_speed = 10 inherits = Kimya ABS Carbon @PG; *ABS08PG* filament_max_volumetric_speed = 14 +[filament:Kimya ABS Carbon @MK4] +inherits = Kimya ABS Carbon; *ABSMK4* +filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="MK4" + +[filament:Kimya ABS Carbon @MK4 0.6] +inherits = Kimya ABS Carbon @MK4; *ABS06MK4* +filament_max_volumetric_speed = 10 + +[filament:Kimya ABS Carbon @MK4 0.8] +inherits = Kimya ABS Carbon @MK4; *ABS08MK4* +filament_max_volumetric_speed = 14 + [filament:Kimya ABS Kevlar] inherits = Kimya ABS Carbon filament_vendor = Kimya @@ -3291,6 +4354,7 @@ filament_density = 1.037 [filament:Kimya ABS Kevlar @PG] inherits = Kimya ABS Kevlar; *ABSPG*; *04PLUSPG* bed_temperature = 105 +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="XL" [filament:Kimya ABS Kevlar @PG 0.6] inherits = Kimya ABS Kevlar @PG; *ABS06PG* @@ -3300,6 +4364,18 @@ filament_max_volumetric_speed = 10 inherits = Kimya ABS Kevlar @PG; *ABS08PG* filament_max_volumetric_speed = 14 +[filament:Kimya ABS Kevlar @MK4] +inherits = Kimya ABS Kevlar; *ABSMK4*; *04PLUSPG* +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="MK4" + +[filament:Kimya ABS Kevlar @MK4 0.6] +inherits = Kimya ABS Kevlar @MK4; *ABS06MK4* +filament_max_volumetric_speed = 10 + +[filament:Kimya ABS Kevlar @MK4 0.8] +inherits = Kimya ABS Kevlar @MK4; *ABS08MK4* +filament_max_volumetric_speed = 14 + [filament:Kimya PEBA-S] inherits = *PET* filament_vendor = Kimya @@ -3312,7 +4388,7 @@ filament_max_volumetric_speed = 6.5 filament_type = PEBA min_fan_speed = 30 max_fan_speed = 30 -compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:Kimya PEBA-S @PG] inherits = Kimya PEBA-S; *PETPG* @@ -3387,6 +4463,15 @@ inherits = Fillamentum ABS @PG; *ABS06PG* [filament:Fillamentum ABS @PG 0.8] inherits = Fillamentum ABS @PG; *ABS08PG* +[filament:Fillamentum ABS @MK4] +inherits = Fillamentum ABS; *ABSMK4* + +[filament:Fillamentum ABS @MK4 0.6] +inherits = Fillamentum ABS @MK4; *ABS06MK4* + +[filament:Fillamentum ABS @MK4 0.8] +inherits = Fillamentum ABS @MK4; *ABS08MK4* + [filament:Fillamentum ASA] inherits = *ABS* filament_vendor = Fillamentum @@ -3413,6 +4498,15 @@ inherits = Fillamentum ASA @PG; *ABS06PG* [filament:Fillamentum ASA @PG 0.8] inherits = Fillamentum ASA @PG; *ABS08PG* +[filament:Fillamentum ASA @MK4] +inherits = Fillamentum ASA; *ABSMK4* + +[filament:Fillamentum ASA @MK4 0.6] +inherits = Fillamentum ASA @MK4; *ABS06MK4* + +[filament:Fillamentum ASA @MK4 0.8] +inherits = Fillamentum ASA @MK4; *ABS08MK4* + [filament:Prusament ASA] inherits = *ABS* filament_vendor = Prusa Polymers @@ -3434,7 +4528,7 @@ disable_fan_first_layers = 4 filament_type = ASA filament_colour = #FFF2EC start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.02{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0" -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:Prusament ASA @PG] inherits = Prusament ASA; *ABSPG* @@ -3449,6 +4543,17 @@ inherits = Prusament ASA @PG; *ABS08PG* first_layer_temperature = 265 temperature = 265 +[filament:Prusament ASA @MK4] +inherits = Prusament ASA; *ABSMK4* + +[filament:Prusament ASA @MK4 0.6] +inherits = Prusament ASA @MK4; *ABS06MK4* + +[filament:Prusament ASA @MK4 0.8] +inherits = Prusament ASA @MK4; *ABS08MK4* +first_layer_temperature = 265 +temperature = 265 + [filament:Prusament PC Blend] inherits = *ABS* filament_vendor = Prusa Polymers @@ -3472,7 +4577,7 @@ filament_type = PC filament_colour = #DEE0E6 filament_max_volumetric_speed = 8 filament_retract_lift = 0.2 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.07{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0" [filament:Prusament PC Blend @PG] @@ -3487,6 +4592,18 @@ filament_max_volumetric_speed = 13 inherits = Prusament PC Blend @PG; *PC08PG* filament_max_volumetric_speed = 18 +[filament:Prusament PC Blend @MK4] +inherits = Prusament PC Blend; *PCMK4* +filament_max_volumetric_speed = 9 + +[filament:Prusament PC Blend @MK4 0.6] +inherits = Prusament PC Blend @MK4; *PC06MK4* +filament_max_volumetric_speed = 13 + +[filament:Prusament PC Blend @MK4 0.8] +inherits = Prusament PC Blend @MK4; *PC08MK4* +filament_max_volumetric_speed = 18 + [filament:Prusament PC Blend @MK2] inherits = Prusament PC Blend first_layer_bed_temperature = 105 @@ -3506,7 +4623,7 @@ fan_below_layer_time = 10 filament_colour = #BBBBBB filament_retract_length = nil filament_retract_lift = nil -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PC Blend Carbon Fiber @PG] inherits = Prusament PC Blend Carbon Fiber; *PCPG* @@ -3519,6 +4636,17 @@ filament_max_volumetric_speed = 13 inherits = Prusament PC Blend Carbon Fiber; *PC08PG* filament_max_volumetric_speed = 18 +[filament:Prusament PC Blend Carbon Fiber @MK4] +inherits = Prusament PC Blend Carbon Fiber; *PCMK4* + +[filament:Prusament PC Blend Carbon Fiber @MK4 0.6] +inherits = Prusament PC Blend Carbon Fiber; *PC06MK4* +filament_max_volumetric_speed = 13 + +[filament:Prusament PC Blend Carbon Fiber @MK4 0.8] +inherits = Prusament PC Blend Carbon Fiber; *PC08MK4* +filament_max_volumetric_speed = 18 + [filament:Prusament PC Blend Carbon Fiber @MK2] inherits = Prusament PC Blend Carbon Fiber first_layer_bed_temperature = 105 @@ -3539,7 +4667,7 @@ temperature = 285 first_layer_bed_temperature = 90 bed_temperature = 115 fan_below_layer_time = 10 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PA11 Carbon Fiber @PG] inherits = Prusament PA11 Carbon Fiber; *PCPG* @@ -3553,6 +4681,18 @@ filament_max_volumetric_speed = 8 inherits = Prusament PA11 Carbon Fiber @PG; *PC08PG* filament_max_volumetric_speed = 10 +[filament:Prusament PA11 Carbon Fiber @MK4] +inherits = Prusament PA11 Carbon Fiber; *PCMK4* +filament_max_volumetric_speed = 6.5 + +[filament:Prusament PA11 Carbon Fiber @MK4 0.6] +inherits = Prusament PA11 Carbon Fiber @MK4; *PC06MK4* +filament_max_volumetric_speed = 8 + +[filament:Prusament PA11 Carbon Fiber @MK4 0.8] +inherits = Prusament PA11 Carbon Fiber @MK4; *PC08MK4* +filament_max_volumetric_speed = 10 + [filament:Prusament PA11 Carbon Fiber @MK2] inherits = Prusament PA11 Carbon Fiber first_layer_bed_temperature = 90 @@ -3646,7 +4786,7 @@ inherits = *ABSC* filament_vendor = Generic filament_cost = 27.82 filament_density = 1.04 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic ABS @PG] inherits = Generic ABS; *ABSPG* @@ -3660,6 +4800,17 @@ inherits = Generic ABS @PG; *ABS08PG* first_layer_temperature = 265 temperature = 265 +[filament:Generic ABS @MK4] +inherits = Generic ABS; *ABSMK4* + +[filament:Generic ABS @MK4 0.6] +inherits = Generic ABS @MK4; *ABS06MK4* + +[filament:Generic ABS @MK4 0.8] +inherits = Generic ABS @MK4; *ABS08MK4* +first_layer_temperature = 265 +temperature = 265 + [filament:Esun ABS] inherits = *ABSC* filament_vendor = Esun @@ -3677,6 +4828,15 @@ inherits = Esun ABS @PG; *ABS06PG* [filament:Esun ABS @PG 0.8] inherits = Esun ABS @PG; *ABS08PG* +[filament:Esun ABS @MK4] +inherits = Esun ABS; *ABSMK4* + +[filament:Esun ABS @MK4 0.6] +inherits = Esun ABS @MK4; *ABS06MK4* + +[filament:Esun ABS @MK4 0.8] +inherits = Esun ABS @MK4; *ABS08MK4* + [filament:Hatchbox ABS] inherits = *ABSC* filament_vendor = Hatchbox @@ -3694,6 +4854,15 @@ inherits = Hatchbox ABS @PG; *ABS06PG* [filament:Hatchbox ABS @PG 0.8] inherits = Hatchbox ABS @PG; *ABS08PG* +[filament:Hatchbox ABS @MK4] +inherits = Hatchbox ABS; *ABSMK4* + +[filament:Hatchbox ABS @MK4 0.6] +inherits = Hatchbox ABS @MK4; *ABS06MK4* + +[filament:Hatchbox ABS @MK4 0.8] +inherits = Hatchbox ABS @MK4; *ABS08MK4* + [filament:Filament PM ABS] inherits = *ABSC* renamed_from = "Plasty Mladec ABS" @@ -3712,6 +4881,15 @@ inherits = Filament PM ABS @PG; *ABS06PG* [filament:Filament PM ABS @PG 0.8] inherits = Filament PM ABS @PG; *ABS08PG* +[filament:Filament PM ABS @MK4] +inherits = Filament PM ABS; *ABSMK4* + +[filament:Filament PM ABS @MK4 0.6] +inherits = Filament PM ABS @MK4; *ABS06MK4* + +[filament:Filament PM ABS @MK4 0.8] +inherits = Filament PM ABS @MK4; *ABS08MK4* + [filament:Verbatim ABS] inherits = *ABSC* filament_vendor = Verbatim @@ -3730,13 +4908,22 @@ inherits = Verbatim ABS @PG; *ABS06PG* [filament:Verbatim ABS @PG 0.8] inherits = Verbatim ABS @PG; *ABS08PG* +[filament:Verbatim ABS @MK4] +inherits = Verbatim ABS; *ABSMK4* + +[filament:Verbatim ABS @MK4 0.6] +inherits = Verbatim ABS @MK4; *ABS06MK4* + +[filament:Verbatim ABS @MK4 0.8] +inherits = Verbatim ABS @MK4; *ABS08MK4* + [filament:Generic PETG] inherits = *PET* renamed_from = "Generic PET" filament_vendor = Generic filament_cost = 27.82 filament_density = 1.27 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic PETG @PG] inherits = Generic PETG; *PETPG* @@ -3766,12 +4953,15 @@ filament_spool_weight = 230 [filament:Extrudr DuraPro ASA @PG] inherits = Extrudr DuraPro ASA; *ABSPG* filament_max_volumetric_speed = 10 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Extrudr DuraPro ASA @PG 0.6] inherits = Extrudr DuraPro ASA @PG; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Extrudr DuraPro ASA @PG 0.8] inherits = Extrudr DuraPro ASA @PG; *ABS08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Extrudr PETG] inherits = *PET* @@ -3809,7 +4999,7 @@ filament_density = 1.29 filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=198" first_layer_temperature = 235 temperature = 235 -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) filament_spool_weight = 230 [filament:Extrudr XPETG CF @PG] @@ -4030,6 +5220,17 @@ inherits = Extrudr Flex Hard @PG; *FLEX06PG* [filament:Extrudr Flex Hard @PG 0.8] inherits = Extrudr Flex Hard @PG; *FLEX08PG* +[filament:Extrudr Flex Hard @MK4] +inherits = Extrudr Flex Hard; *FLEXMK4* +extrusion_multiplier = 1.1 +filament_retract_length = 2.5 + +[filament:Extrudr Flex Hard @MK4 0.6] +inherits = Extrudr Flex Hard @MK4; *FLEX06MK4* + +[filament:Extrudr Flex Hard @MK4 0.8] +inherits = Extrudr Flex Hard @MK4; *FLEX08MK4* + [filament:Extrudr Flex Medium] inherits = *FLEX* filament_vendor = Extrudr @@ -4056,6 +5257,17 @@ inherits = Extrudr Flex Medium @PG; *FLEX06PG* [filament:Extrudr Flex Medium @PG 0.8] inherits = Extrudr Flex Medium @PG; *FLEX08PG* +[filament:Extrudr Flex Medium @MK4] +inherits = Extrudr Flex Medium; *FLEXMK4* +extrusion_multiplier = 1.1 +filament_retract_length = 2.5 + +[filament:Extrudr Flex Medium @MK4 0.6] +inherits = Extrudr Flex Medium @MK4; *FLEX06MK4* + +[filament:Extrudr Flex Medium @MK4 0.8] +inherits = Extrudr Flex Medium @MK4; *FLEX08MK4* + [filament:Extrudr Flex SemiSoft] inherits = *FLEX* filament_vendor = Extrudr @@ -4085,6 +5297,20 @@ filament_max_volumetric_speed = 5 inherits = Extrudr Flex SemiSoft @PG; *FLEX08PG* filament_max_volumetric_speed = 8 +[filament:Extrudr Flex SemiSoft @MK4] +inherits = Extrudr Flex SemiSoft; *FLEXMK4* +extrusion_multiplier = 1.1 +filament_retract_length = 3 +filament_max_volumetric_speed = 3 + +[filament:Extrudr Flex SemiSoft @MK4 0.6] +inherits = Extrudr Flex SemiSoft @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 5 + +[filament:Extrudr Flex SemiSoft @MK4 0.8] +inherits = Extrudr Flex SemiSoft @MK4; *FLEX08MK4* +filament_max_volumetric_speed = 8 + [filament:addnorth Adamant S1] inherits = *FLEX* filament_vendor = addnorth @@ -4121,12 +5347,27 @@ filament_retract_lift = 0.2 [filament:addnorth Adamant S1 @PG 0.6] inherits = addnorth Adamant S1 @PG; *FLEX06PG* -filament_max_volumetric_speed = 5.5 +filament_max_volumetric_speed = 4.5 [filament:addnorth Adamant S1 @PG 0.8] inherits = addnorth Adamant S1 @PG; *FLEX08PG* filament_max_volumetric_speed = 9 +[filament:addnorth Adamant S1 @MK4] +inherits = addnorth Adamant S1; *FLEXMK4* +filament_max_volumetric_speed = 3 +filament_retract_length = 1.5 +filament_retract_restart_extra = 0 +filament_retract_lift = 0.2 + +[filament:addnorth Adamant S1 @MK4 0.6] +inherits = addnorth Adamant S1 @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 5.5 + +[filament:addnorth Adamant S1 @MK4 0.8] +inherits = addnorth Adamant S1 @MK4; *FLEX08MK4* +filament_max_volumetric_speed = 9 + [filament:addnorth Adura X] inherits = *PET* filament_vendor = addnorth @@ -4152,21 +5393,39 @@ filament_retract_lift = 0.4 filament_max_volumetric_speed = 4 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.08{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0" filament_spool_weight = 0 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="XL" and printer_model!="MK2SMM" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and printer_model!="MK2SMM" and ! single_extruder_multi_material [filament:addnorth Adura X @PG] inherits = addnorth Adura X; *PETPG* first_layer_bed_temperature = 100 bed_temperature = 105 filament_max_volumetric_speed = 4 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="XL" and ! single_extruder_multi_material [filament:addnorth Adura X @PG 0.6] inherits = addnorth Adura X @PG; *PET06PG* filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_model=="XL" and ! single_extruder_multi_material [filament:addnorth Adura X @PG 0.8] inherits = addnorth Adura X @PG; *PET08PG* filament_max_volumetric_speed = 8 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model=="XL" and ! single_extruder_multi_material + +[filament:addnorth Adura X @MK4] +inherits = addnorth Adura X; *PETPG* +filament_max_volumetric_speed = 4 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="MK4" and ! single_extruder_multi_material + +[filament:addnorth Adura X @MK4 0.6] +inherits = addnorth Adura X @MK4; *PET06PG* +filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_model=="MK4" and ! single_extruder_multi_material + +[filament:addnorth Adura X @MK4 0.8] +inherits = addnorth Adura X @MK4; *PET08PG* +filament_max_volumetric_speed = 8 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model=="MK4" and ! single_extruder_multi_material [filament:addnorth Adura X @MINI] inherits = addnorth Adura X @@ -4305,6 +5564,19 @@ filament_max_volumetric_speed = 6 inherits = addnorth OBC Polyethylene @PG; *FLEX08PG* filament_max_volumetric_speed = 10 +[filament:addnorth OBC Polyethylene @MK4] +inherits = addnorth OBC Polyethylene; *FLEXMK4* +filament_max_volumetric_speed = 4 +filament_retract_length = 1.5 + +[filament:addnorth OBC Polyethylene @MK4 0.6] +inherits = addnorth OBC Polyethylene @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6 + +[filament:addnorth OBC Polyethylene @MK4 0.8] +inherits = addnorth OBC Polyethylene @MK4; *FLEX08MK4* +filament_max_volumetric_speed = 10 + [filament:addnorth PETG] inherits = *PET* filament_vendor = addnorth @@ -4375,7 +5647,7 @@ filament_retract_length = 1.4 filament_max_volumetric_speed = 5 filament_spool_weight = 0 filament_notes = "Please use a nozzle that is resistant to abrasive filaments, like hardened steel." -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="XL" and printer_model!="MK2SMM" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and printer_model!="MK2SMM" and ! single_extruder_multi_material [filament:addnorth Rigid X @PG] inherits = addnorth Rigid X; *PETPG*; *04PLUSPG* @@ -4421,7 +5693,7 @@ slowdown_below_layer_time = 15 min_print_speed = 20 filament_spool_weight = 0 filament_retract_length = 1 -compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:addnorth Textura @PG] inherits = addnorth Textura; *PLAPG* @@ -4458,19 +5730,22 @@ disable_fan_first_layers = 3 fan_below_layer_time = 60 slowdown_below_layer_time = 15 bridge_fan_speed = 20 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Filamentworld ABS @PG] inherits = Filamentworld ABS; *ABSPG* first_layer_bed_temperature = 100 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filamentworld ABS @PG 0.6] inherits = Filamentworld ABS @PG; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filamentworld ABS @PG 0.8] inherits = Filamentworld ABS @PG; *ABS08PG* first_layer_temperature = 240 temperature = 240 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filamentworld ABS @MINI] inherits = Filamentworld ABS @@ -4552,7 +5827,7 @@ filament_vendor = Filament PM filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 -compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Filament PM PETG @PG] inherits = Filament PM PETG; *PETPG* @@ -4568,7 +5843,7 @@ inherits = *PLA* filament_vendor = Generic filament_cost = 25.4 filament_density = 1.24 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic PLA @PG] inherits = Generic PLA; *PLAPG* @@ -4707,6 +5982,15 @@ inherits = 3D-Fuel Workday ABS @PG; *ABS06PG* [filament:3D-Fuel Workday ABS @PG 0.8] inherits = 3D-Fuel Workday ABS @PG; *ABS08PG* +[filament:3D-Fuel Workday ABS @MK4] +inherits = 3D-Fuel Workday ABS; *ABSMK4* + +[filament:3D-Fuel Workday ABS @MK4 0.6] +inherits = 3D-Fuel Workday ABS @MK4; *ABS06MK4* + +[filament:3D-Fuel Workday ABS @MK4 0.8] +inherits = 3D-Fuel Workday ABS @MK4; *ABS08MK4* + [filament:3D-Fuel Workday ABS @MINI] inherits = 3D-Fuel Workday ABS; *ABSMINI* @@ -4817,7 +6101,7 @@ filament_max_volumetric_speed = 1.2 filament_retract_length = 0 filament_retract_speed = nil filament_retract_lift = nil -compatible_printers_condition = nozzle_diameter[0]>=0.35 and nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.35 and nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic FLEX @PG] inherits = Generic FLEX; *FLEXPG* @@ -4835,10 +6119,32 @@ extrusion_multiplier = 1.08 [filament:Generic FLEX @PG 0.6] inherits = Generic FLEX @PG; *FLEX06PG* -filament_max_volumetric_speed = 6 +filament_max_volumetric_speed = 4 [filament:Generic FLEX @PG 0.8] inherits = Generic FLEX @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Generic FLEX @MK4] +inherits = Generic FLEX; *FLEXMK4* +filament_max_volumetric_speed = 3 +filament_retract_length = 2.5 +fan_always_on = 1 +min_fan_speed = 30 +max_fan_speed = 30 +cooling = 1 +filament_retract_lift = 0 +slowdown_below_layer_time = 10 +first_layer_temperature = 230 +temperature = 230 +extrusion_multiplier = 1.08 + +[filament:Generic FLEX @MK4 0.6] +inherits = Generic FLEX @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6 + +[filament:Generic FLEX @MK4 0.8] +inherits = Generic FLEX @MK4; *FLEX08MK4* filament_max_volumetric_speed = 9 [filament:Fillamentum Flexfill 92A] @@ -4860,16 +6166,30 @@ full_fan_speed_layer = 6 [filament:Fillamentum Flexfill 92A @PG] inherits = Fillamentum Flexfill 92A; *FLEXPG* -filament_max_volumetric_speed = 3.5 +filament_max_volumetric_speed = 3 extrusion_multiplier = 1.1 filament_retract_length = 3.5 [filament:Fillamentum Flexfill 92A @PG 0.6] inherits = Fillamentum Flexfill 92A @PG; *FLEX06PG* -filament_max_volumetric_speed = 6.5 +filament_max_volumetric_speed = 4.5 [filament:Fillamentum Flexfill 92A @PG 0.8] inherits = Fillamentum Flexfill 92A @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Fillamentum Flexfill 92A @MK4] +inherits = Fillamentum Flexfill 92A; *FLEXMK4* +filament_max_volumetric_speed = 3.5 +extrusion_multiplier = 1.1 +filament_retract_length = 3.5 + +[filament:Fillamentum Flexfill 92A @MK4 0.6] +inherits = Fillamentum Flexfill 92A @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6.5 + +[filament:Fillamentum Flexfill 92A @MK4 0.8] +inherits = Fillamentum Flexfill 92A @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:AmazonBasics TPU] @@ -4906,10 +6226,23 @@ extrusion_multiplier = 1.1 [filament:AmazonBasics TPU @PG 0.6] inherits = AmazonBasics TPU @PG; *FLEX06PG* -filament_max_volumetric_speed = 6.5 +filament_max_volumetric_speed = 5 [filament:AmazonBasics TPU @PG 0.8] inherits = AmazonBasics TPU @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:AmazonBasics TPU @MK4] +inherits = AmazonBasics TPU; *FLEXMK4* +filament_retract_length = 2.5 +extrusion_multiplier = 1.1 + +[filament:AmazonBasics TPU @MK4 0.6] +inherits = AmazonBasics TPU @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6.5 + +[filament:AmazonBasics TPU @MK4 0.8] +inherits = AmazonBasics TPU @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:SainSmart TPU] @@ -4948,10 +6281,25 @@ filament_retract_length = 1.5 [filament:SainSmart TPU @PG 0.6] inherits = SainSmart TPU @PG; *FLEX06PG* -filament_max_volumetric_speed = 7 +filament_max_volumetric_speed = 6 [filament:SainSmart TPU @PG 0.8] inherits = SainSmart TPU @PG; *FLEX08PG* +filament_max_volumetric_speed = 9 + +[filament:SainSmart TPU @MK4] +inherits = SainSmart TPU; *FLEXMK4* +filament_max_volumetric_speed = 5 +first_layer_temperature = 235 +temperature = 235 +filament_retract_length = 1.5 + +[filament:SainSmart TPU @MK4 0.6] +inherits = SainSmart TPU @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 7 + +[filament:SainSmart TPU @MK4 0.8] +inherits = SainSmart TPU @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:NinjaTek NinjaFlex TPU] @@ -4983,16 +6331,30 @@ cooling = 1 [filament:NinjaTek NinjaFlex TPU @PG] inherits = NinjaTek NinjaFlex TPU; *FLEXPG* -filament_max_volumetric_speed = 3.5 +filament_max_volumetric_speed = 3 filament_retract_length = 3.5 extrusion_multiplier = 1.12 [filament:NinjaTek NinjaFlex TPU @PG 0.6] inherits = NinjaTek NinjaFlex TPU @PG; *FLEX06PG* -filament_max_volumetric_speed = 6.5 +filament_max_volumetric_speed = 4.5 [filament:NinjaTek NinjaFlex TPU @PG 0.8] inherits = NinjaTek NinjaFlex TPU @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:NinjaTek NinjaFlex TPU @MK4] +inherits = NinjaTek NinjaFlex TPU; *FLEXMK4* +filament_max_volumetric_speed = 3.5 +filament_retract_length = 3.5 +extrusion_multiplier = 1.12 + +[filament:NinjaTek NinjaFlex TPU @MK4 0.6] +inherits = NinjaTek NinjaFlex TPU @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6.5 + +[filament:NinjaTek NinjaFlex TPU @MK4 0.8] +inherits = NinjaTek NinjaFlex TPU @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:NinjaTek Cheetah TPU] @@ -5008,15 +6370,28 @@ temperature = 240 [filament:NinjaTek Cheetah TPU @PG] inherits = NinjaTek Cheetah TPU; *FLEXPG* -filament_max_volumetric_speed = 6 +filament_max_volumetric_speed = 5 filament_retract_length = 2.2 [filament:NinjaTek Cheetah TPU @PG 0.6] inherits = NinjaTek Cheetah TPU @PG; *FLEX06PG* -filament_max_volumetric_speed = 8 +filament_max_volumetric_speed = 7 [filament:NinjaTek Cheetah TPU @PG 0.8] inherits = NinjaTek Cheetah TPU @PG; *FLEX08PG* +filament_max_volumetric_speed = 10 + +[filament:NinjaTek Cheetah TPU @MK4] +inherits = NinjaTek Cheetah TPU; *FLEXMK4* +filament_max_volumetric_speed = 6 +filament_retract_length = 2.2 + +[filament:NinjaTek Cheetah TPU @MK4 0.6] +inherits = NinjaTek Cheetah TPU @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 8 + +[filament:NinjaTek Cheetah TPU @MK4 0.8] +inherits = NinjaTek Cheetah TPU @MK4; *FLEX08MK4* filament_max_volumetric_speed = 12 [filament:NinjaTek Cheetah TPU @MINI] @@ -5070,6 +6445,19 @@ filament_max_volumetric_speed = 5 inherits = Filatech FilaFlex40 @PG; *FLEX08PG* filament_max_volumetric_speed = 10 +[filament:Filatech FilaFlex40 @MK4] +inherits = Filatech FilaFlex40; *FLEXMK4* +filament_max_volumetric_speed = 4 +filament_retract_length = 2.5 + +[filament:Filatech FilaFlex40 @MK4 0.6] +inherits = Filatech FilaFlex40 @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 5 + +[filament:Filatech FilaFlex40 @MK4 0.8] +inherits = Filatech FilaFlex40 @MK4; *FLEX08MK4* +filament_max_volumetric_speed = 10 + [filament:Filatech FilaFlex30] inherits = Filatech FilaFlex40 temperature = 225 @@ -5084,10 +6472,23 @@ filament_retract_length = 3 [filament:Filatech FilaFlex30 @PG 0.6] inherits = Filatech FilaFlex30 @PG; *FLEX06PG* -filament_max_volumetric_speed = 7 +filament_max_volumetric_speed = 5 [filament:Filatech FilaFlex30 @PG 0.8] inherits = Filatech FilaFlex30 @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Filatech FilaFlex30 @MK4] +inherits = Filatech FilaFlex30; *FLEXMK4* +filament_max_volumetric_speed = 3.5 +filament_retract_length = 3 + +[filament:Filatech FilaFlex30 @MK4 0.6] +inherits = Filatech FilaFlex30 @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 7 + +[filament:Filatech FilaFlex30 @MK4 0.8] +inherits = Filatech FilaFlex30 @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:Filatech FilaFlex55] @@ -5132,16 +6533,30 @@ temperature = 235 [filament:Filatech TPU @PG] inherits = Filatech TPU; *FLEXPG* -filament_max_volumetric_speed = 5.5 +filament_max_volumetric_speed = 4.5 first_layer_temperature = 235 filament_retract_length = 2.2 [filament:Filatech TPU @PG 0.6] inherits = Filatech TPU @PG; *FLEX06PG* -filament_max_volumetric_speed = 7 +filament_max_volumetric_speed = 5 [filament:Filatech TPU @PG 0.8] inherits = Filatech TPU @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Filatech TPU @MK4] +inherits = Filatech TPU; *FLEXMK4* +filament_max_volumetric_speed = 5.5 +first_layer_temperature = 235 +filament_retract_length = 2.2 + +[filament:Filatech TPU @MK4 0.6] +inherits = Filatech TPU @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 7 + +[filament:Filatech TPU @MK4 0.8] +inherits = Filatech TPU @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:Filatech ABS] @@ -5161,6 +6576,15 @@ inherits = Filatech ABS @PG; *ABS06PG* [filament:Filatech ABS @PG 0.8] inherits = Filatech ABS @PG; *ABS08PG* +[filament:Filatech ABS @MK4] +inherits = Filatech ABS; *ABSMK4* + +[filament:Filatech ABS @MK4 0.6] +inherits = Filatech ABS @MK4; *ABS06MK4* + +[filament:Filatech ABS @MK4 0.8] +inherits = Filatech ABS @MK4; *ABS08MK4* + [filament:Filatech ABS @MINI] inherits = Filatech ABS; *ABSMINI* @@ -5172,17 +6596,20 @@ extrusion_multiplier = 0.95 filament_density = 1.1 first_layer_bed_temperature = 105 bed_temperature = 100 -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech FilaCarbon @PG] inherits = Filatech FilaCarbon; *ABSPG*; *04PLUSPG* first_layer_bed_temperature = 100 +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech FilaCarbon @PG 0.6] inherits = Filatech FilaCarbon @PG; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech FilaCarbon @PG 0.8] inherits = Filatech FilaCarbon @PG; *ABS08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech FilaCarbon @MINI] inherits = Filatech FilaCarbon; *ABSMINI* @@ -5251,12 +6678,15 @@ cooling = 0 [filament:Filatech FilaTough @PG] inherits = Filatech FilaTough; *ABSPG* +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech FilaTough @PG 0.6] inherits = Filatech FilaTough; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech FilaTough @PG 0.8] inherits = Filatech FilaTough; *ABS08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech HIPS] inherits = Prusa HIPS @@ -5268,7 +6698,7 @@ first_layer_temperature = 230 first_layer_bed_temperature = 100 temperature = 225 bed_temperature = 110 -compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech HIPS @PG] inherits = Filatech HIPS; *ABSPG* @@ -5290,6 +6720,24 @@ inherits = Filatech HIPS @PG; *ABS06PG* [filament:Filatech HIPS @PG 0.8] inherits = Filatech HIPS @PG; *ABS08PG* +[filament:Filatech HIPS @MK4] +inherits = Filatech HIPS; *ABSMK4* +bridge_fan_speed = 50 +cooling = 1 +extrusion_multiplier = 1 +fan_always_on = 1 +fan_below_layer_time = 10 +first_layer_temperature = 220 +temperature = 225 +max_fan_speed = 20 +min_fan_speed = 20 + +[filament:Filatech HIPS @MK4 0.6] +inherits = Filatech HIPS @MK4; *ABS06MK4* + +[filament:Filatech HIPS @MK4 0.8] +inherits = Filatech HIPS @MK4; *ABS08MK4* + [filament:Filatech HIPS @MINI] inherits = Filatech HIPS; *ABSMINI* @@ -5307,7 +6755,7 @@ cooling = 0 bridge_fan_speed = 25 filament_type = PA filament_max_volumetric_speed = 8 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Filatech PA @PG] inherits = Filatech PA; *ABSPG* @@ -5323,6 +6771,18 @@ filament_max_volumetric_speed = 10 inherits = Filatech PA @PG; *ABS08PG* filament_max_volumetric_speed = 12 +[filament:Filatech PA @MK4] +inherits = Filatech PA; *ABSMK4* +filament_max_volumetric_speed = 8 + +[filament:Filatech PA @MK4 0.6] +inherits = Filatech PA @MK4; *ABS06MK4* +filament_max_volumetric_speed = 10 + +[filament:Filatech PA @MK4 0.8] +inherits = Filatech PA @MK4; *ABS08MK4* +filament_max_volumetric_speed = 12 + [filament:Filatech PA @MK2] inherits = Filatech PA first_layer_bed_temperature = 105 @@ -5351,6 +6811,15 @@ inherits = Filatech PC @PG; *PC06PG* [filament:Filatech PC @PG 0.8] inherits = Filatech PC @PG; *PC08PG* +[filament:Filatech PC @MK4] +inherits = Filatech PC; *PCMK4* + +[filament:Filatech PC @MK4 0.6] +inherits = Filatech PC @MK4; *PC06MK4* + +[filament:Filatech PC @MK4 0.8] +inherits = Filatech PC @MK4; *PC08MK4* + [filament:Filatech PC @MK2] inherits = Filatech PC first_layer_bed_temperature = 105 @@ -5379,6 +6848,15 @@ inherits = Filatech PC-ABS; *PC06PG* [filament:Filatech PC-ABS @PG 0.8] inherits = Filatech PC-ABS; *PC08PG* +[filament:Filatech PC-ABS @MK4] +inherits = Filatech PC-ABS; *PCMK4* + +[filament:Filatech PC-ABS @MK4 0.6] +inherits = Filatech PC-ABS @MK4; *PC06MK4* + +[filament:Filatech PC-ABS @MK4 0.8] +inherits = Filatech PC-ABS @MK4; *PC08MK4* + [filament:Filatech PC-ABS @MK2] inherits = Filatech PC-ABS first_layer_bed_temperature = 105 @@ -5474,7 +6952,7 @@ filament_retract_lift = 0 filament_retract_speed = 40 filament_retract_before_travel = 2 filament_retract_layer_change = 0 -compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PRO1 @PG] inherits = Ultrafuse PRO1; *PLAPG* @@ -5519,6 +6997,15 @@ inherits = Ultrafuse ABS @PG; *ABS06PG* [filament:Ultrafuse ABS @PG 0.8] inherits = Ultrafuse ABS @PG; *ABS08PG* +[filament:Ultrafuse ABS @MK4] +inherits = Ultrafuse ABS; *ABSMK4* + +[filament:Ultrafuse ABS @MK4 0.6] +inherits = Ultrafuse ABS @MK4; *ABS06MK4* + +[filament:Ultrafuse ABS @MK4 0.8] +inherits = Ultrafuse ABS @MK4; *ABS08MK4* + [filament:Ultrafuse ABS @MINI] inherits = Ultrafuse ABS; *ABSMINI* filament_retract_layer_change = nil @@ -5547,6 +7034,15 @@ inherits = Ultrafuse ABS Fusion+ @PG; *ABS06PG* [filament:Ultrafuse ABS Fusion+ @PG 0.8] inherits = Ultrafuse ABS Fusion+ @PG; *ABS08PG* +[filament:Ultrafuse ABS Fusion+ @MK4] +inherits = Ultrafuse ABS Fusion+; *ABSMK4* + +[filament:Ultrafuse ABS Fusion+ @MK4 0.6] +inherits = Ultrafuse ABS Fusion+ @MK4; *ABS06MK4* + +[filament:Ultrafuse ABS Fusion+ @MK4 0.8] +inherits = Ultrafuse ABS Fusion+ @MK4; *ABS08MK4* + [filament:Ultrafuse ABS Fusion+ @MINI] inherits = Ultrafuse ABS Fusion+; *ABSMINI* first_layer_bed_temperature = 100 @@ -5582,6 +7078,18 @@ filament_max_volumetric_speed = 9 inherits = Ultrafuse ASA @PG; *ABS08PG* filament_max_volumetric_speed = 12 +[filament:Ultrafuse ASA @MK4] +inherits = Ultrafuse ASA; *ABSMK4* +filament_max_volumetric_speed = 5 + +[filament:Ultrafuse ASA @MK4 0.6] +inherits = Ultrafuse ASA @MK4; *ABS06MK4* +filament_max_volumetric_speed = 9 + +[filament:Ultrafuse ASA @MK4 0.8] +inherits = Ultrafuse ASA @MK4; *ABS08MK4* +filament_max_volumetric_speed = 12 + [filament:Ultrafuse ASA @MINI] inherits = Ultrafuse ASA; *ABSMINI* filament_type = ASA @@ -5607,6 +7115,15 @@ inherits = Ultrafuse HIPS @PG; *ABS06PG* [filament:Ultrafuse HIPS @PG 0.8] inherits = Ultrafuse HIPS @PG; *ABS08PG* +[filament:Ultrafuse HIPS @MK4] +inherits = Ultrafuse HIPS; *ABSMK4* + +[filament:Ultrafuse HIPS @MK4 0.6] +inherits = Ultrafuse HIPS @MK4; *ABS06MK4* + +[filament:Ultrafuse HIPS @MK4 0.8] +inherits = Ultrafuse HIPS @MK4; *ABS08MK4* + [filament:Ultrafuse HIPS @MINI] inherits = Ultrafuse HIPS; *ABSMINI* filament_type = HIPS @@ -5635,21 +7152,24 @@ filament_retract_before_travel = 2 filament_retract_layer_change = 0 filament_cost = 0 filament_spool_weight = 0 -compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.02{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0" filament_notes = "Material Description\nThe key features of Ultrafuse PA are the high strength and high modulus. Furthermore, Ultrafuse PA shows a good thermal distortion stability.\n\nPrinting Recommendations:\nApply PVA glue, Kapton tape or PA adhesive to a clean buildplate to improve adhesion." [filament:Ultrafuse PA @PG] inherits = Ultrafuse PA; *ABSPG* filament_max_volumetric_speed = 8 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PA @PG 0.6] inherits = Ultrafuse PA @PG; *ABS06PG* filament_max_volumetric_speed = 10 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PA @PG 0.8] inherits = Ultrafuse PA @PG; *ABS08PG* filament_max_volumetric_speed = 12 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PA6 GF30] inherits = Ultrafuse PA @@ -5673,17 +7193,19 @@ filament_deretract_speed = 30 filament_retract_lift = nil filament_wipe = 0 filament_notes = "Material Description\nUltrafuse® PA6 GF30 is a unique compound specifically developed for FFF printing. Due to the glass fiber content of 30%, parts tend to warp less. In addition the excellent layer adhesion and its compatibility with the water soluble support Ultrafuse® BVOH make this material the perfect solution to develop industrial applications on an FFF printer.\n\nWith its high wear and chemical resistance, high stiffness and strength, Ultrafuse® PA6 GF30 is perfect for a wide variety of applications in automotive, electronics or transportation.\n\nUltrafuse PA6 GF30 is designed for functional prototyping and demanding applications such as industrial tooling, transportation, electronics, small appliances, sports & leisure\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nUltrafuse PA6 GF30 can be printed directly onto a clean build plate. For challenging prints, use Magigoo PA gluestick to improve adhesion." -compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PA6 GF30 @PG 0.6] inherits = Ultrafuse PA6 GF30; *ABS06PG* filament_max_volumetric_speed = 10 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PA6 GF30 @PG 0.8] inherits = Ultrafuse PA6 GF30; *ABS08PG* filament_max_volumetric_speed = 14 first_layer_temperature = 275 temperature = 275 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PAHT-CF15] inherits = Ultrafuse PA6 GF30 @@ -5692,9 +7214,11 @@ filament_notes = "Material Description\nPAHT CF15 is a high-performance 3D print [filament:Ultrafuse PAHT-CF15 @PG 0.6] inherits = Ultrafuse PAHT-CF15; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PAHT-CF15 @PG 0.8] inherits = Ultrafuse PAHT-CF15; *ABS08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PC-ABS-FR] inherits = Ultrafuse ABS @@ -5711,7 +7235,7 @@ min_fan_speed = 20 max_fan_speed = 20 bridge_fan_speed = 30 disable_fan_first_layers = 4 -compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material filament_notes = "Material Description\nUltrafuse® PC/ABS FR Black is a V-0 flame retardant blend of Polycarbonate and ABS – two of the most used thermoplastics for engineering & electrical applications. The combination of these two materials results in a premium material with a mix of the excellent mechanical properties of PC and the comparably low printing temperature of ABS. Combined with a halogen free flame retardant, parts printed with Ultrafuse® PC/ABS FR Black feature great tensile and impact strength, higher thermal resistance than ABS and can fulfill the requirements of the UL94 V-0 standard.\n\nPrinting Recommendations:\nApply Magigoo PC to a clean build plate to improve adhesion." start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.07{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0" @@ -5729,6 +7253,18 @@ filament_max_volumetric_speed = 10 inherits = Ultrafuse PC-ABS-FR @PG; *ABS08PG* filament_max_volumetric_speed = 12 +[filament:Ultrafuse PC-ABS-FR @MK4] +inherits = Ultrafuse PC-ABS-FR; *ABSMK4* +filament_max_volumetric_speed = 8 + +[filament:Ultrafuse PC-ABS-FR @MK4 0.6] +inherits = Ultrafuse PC-ABS-FR @MK4; *ABS06MK4* +filament_max_volumetric_speed = 10 + +[filament:Ultrafuse PC-ABS-FR @MK4 0.8] +inherits = Ultrafuse PC-ABS-FR @MK4; *ABS08MK4* +filament_max_volumetric_speed = 12 + [filament:Ultrafuse PET-CF15] inherits = Ultrafuse PET filament_density = 1.36 @@ -5752,7 +7288,7 @@ filament_retract_lift = nil filament_wipe = 0 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0" filament_notes = "Material Description\nPET CF15 is a Carbon Fiber reinforced PET which has precisely tuned material properties, for a wide range of technical applications. The filament is very strong and stiff and has high heat resistance. With its high dimensional stability and low abrasiveness, the filament offers an easy to print experience which allows direct printing on glass or a PEI sheet. It is compatible with HiPS for breakaway support and water soluble support and has an excellent surface finish.\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nUltrafuse PET-CF15 can be printed directly onto a clean build plate. For challenging prints, use 3dLac to improve adhesion." -compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PET-CF15 @PG 0.6] inherits = Ultrafuse PET; *PET06PG* @@ -5803,19 +7339,22 @@ filament_deretract_speed = 25 filament_retract_layer_change = 0 filament_wipe = nil filament_notes = "Material Description\nUltrafuse PP is high-performance thermoplastic with low density, high elasticity and high resistance to fatigue. The mechanical properties make it an ideal material for 3D-printing applications which have to endure high stress or strain. The filament has high chemical resistance and a high isolation value. PP is one of the most used materials in the world, due to its versatility and ability to engineer lightweight tough parts.\n\nPrinting Recommendations:\nApply PP tape or Magigoo PP adhesive to the buildplate for optimal adhesion." -compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PP @PG] inherits = Ultrafuse PP; *ABSPG* filament_max_volumetric_speed = 2.5 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PP @PG 0.6] inherits = Ultrafuse PP @PG; *ABS06PG* filament_max_volumetric_speed = 4 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PP @PG 0.8] inherits = Ultrafuse PP @PG; *ABS08PG* filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PP-GF30] inherits = Ultrafuse PP @@ -5837,13 +7376,15 @@ filament_deretract_speed = 30 filament_retract_lift = nil filament_wipe = 0 filament_notes = "Ultrafuse PP GF30 is polypropylene, reinforced with 30% glass fiber content. The fibers in this compound are specially designed for 3D-printing filaments and are compatible with a wide range of standard FFF 3D-printers. The extreme stiffness makes this material highly suitable for demanding applications. Other key properties of PPGF30 are high heat resistance and improved UV-resistance. All these excellent properties make this filament highly suitable in an industrial environment.\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nApply PP strapping tape or PPGF adhesive to a clean build plate for optimal adhesion." -compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PP-GF30 @PG 0.6] inherits = Ultrafuse PP; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse PP-GF30 @PG 0.8] inherits = Ultrafuse PP; *ABS08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse TPC-45D] inherits = *FLEX* @@ -5934,10 +7475,26 @@ filament_retract_length = 3.5 [filament:Ultrafuse TPU-85A @PG 0.6] inherits = Ultrafuse TPU-85A @PG; *FLEX06PG* -filament_max_volumetric_speed = 6 +filament_max_volumetric_speed = 4 [filament:Ultrafuse TPU-85A @PG 0.8] inherits = Ultrafuse TPU-85A @PG; *FLEX08PG* +filament_max_volumetric_speed = 7 + +[filament:Ultrafuse TPU-85A @MK4] +inherits = Ultrafuse TPU-85A; *FLEXMK4* +filament_max_volumetric_speed = 3 +extrusion_multiplier = 1.1 +first_layer_temperature = 220 +temperature = 215 +filament_retract_length = 3.5 + +[filament:Ultrafuse TPU-85A @MK4 0.6] +inherits = Ultrafuse TPU-85A @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6 + +[filament:Ultrafuse TPU-85A @MK4 0.8] +inherits = Ultrafuse TPU-85A @MK4; *FLEX08MK4* filament_max_volumetric_speed = 8 [filament:Ultrafuse TPU-95A] @@ -5954,10 +7511,23 @@ filament_retract_length = 3 [filament:Ultrafuse TPU-95A @PG 0.6] inherits = Ultrafuse TPU-95A @PG; *FLEX06PG* -filament_max_volumetric_speed = 5 +filament_max_volumetric_speed = 3.5 [filament:Ultrafuse TPU-95A @PG 0.8] inherits = Ultrafuse TPU-95A @PG; *FLEX08PG* +filament_max_volumetric_speed = 6 + +[filament:Ultrafuse TPU-95A @MK4] +inherits = Ultrafuse TPU-95A; *FLEXMK4* +filament_max_volumetric_speed = 2.5 +filament_retract_length = 3 + +[filament:Ultrafuse TPU-95A @MK4 0.6] +inherits = Ultrafuse TPU-95A @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 5 + +[filament:Ultrafuse TPU-95A @MK4 0.8] +inherits = Ultrafuse TPU-95A @MK4; *FLEX08MK4* filament_max_volumetric_speed = 7 [filament:Ultrafuse rPET] @@ -6008,7 +7578,7 @@ cooling = 0 fan_always_on = 0 filament_max_volumetric_speed = 4 filament_type = METAL -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material start_filament_gcode = "M900 K0" filament_colour = #FFFFFF @@ -6016,11 +7586,13 @@ filament_colour = #FFFFFF inherits = Ultrafuse Metal; *ABSPG*; *04PLUSPG* filament_max_volumetric_speed = 4 start_filament_gcode = "M900 K0" +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Ultrafuse Metal @PG 0.6] inherits = Ultrafuse Metal @PG; *ABS06PG* filament_max_volumetric_speed = 4 start_filament_gcode = "M900 K0" +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Polymaker PC-Max] inherits = *ABS* @@ -6050,6 +7622,18 @@ filament_max_volumetric_speed = 12 inherits = Polymaker PC-Max @PG; *ABS08PG* filament_max_volumetric_speed = 15 +[filament:Polymaker PC-Max @MK4] +inherits = Polymaker PC-Max; *ABSMK4* +filament_max_volumetric_speed = 8 + +[filament:Polymaker PC-Max @MK4 0.6] +inherits = Polymaker PC-Max @MK4; *ABS06MK4* +filament_max_volumetric_speed = 12 + +[filament:Polymaker PC-Max @MK4 0.8] +inherits = Polymaker PC-Max @MK4; *ABS08MK4* +filament_max_volumetric_speed = 15 + [filament:PrimaSelect PVA+] inherits = *PLA* filament_vendor = PrimaSelect @@ -6086,7 +7670,7 @@ filament_vendor = Made for Prusa filament_cost = 27.82 filament_density = 1.08 filament_spool_weight = 230 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusa ABS @PG] inherits = Prusa ABS; *ABSPG* @@ -6100,6 +7684,17 @@ inherits = Prusa ABS @PG; *ABS08PG* first_layer_temperature = 265 temperature = 265 +[filament:Prusa ABS @MK4] +inherits = Prusa ABS; *ABSMK4* + +[filament:Prusa ABS @MK4 0.6] +inherits = Prusa ABS @MK4; *ABS06MK4* + +[filament:Prusa ABS @MK4 0.8] +inherits = Prusa ABS @MK4; *ABS08MK4* +first_layer_temperature = 265 +temperature = 265 + [filament:*ABS MMU2*] inherits = Prusa ABS compatible_printers_condition = nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.25 and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material @@ -6330,7 +7925,7 @@ max_fan_speed = 20 min_fan_speed = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.03{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0" temperature = 220 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic HIPS] inherits = *ABS* @@ -6350,7 +7945,7 @@ max_fan_speed = 20 min_fan_speed = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.03{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0" temperature = 230 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic HIPS @PG] inherits = Generic HIPS; *ABSPG* @@ -6362,6 +7957,15 @@ inherits = Generic HIPS @PG; *ABS06PG* [filament:Generic HIPS @PG 0.8] inherits = Generic HIPS @PG; *ABS08PG* +[filament:Generic HIPS @MK4] +inherits = Generic HIPS; *ABSMK4* + +[filament:Generic HIPS @MK4 0.6] +inherits = Generic HIPS @MK4; *ABS06MK4* + +[filament:Generic HIPS @MK4 0.8] +inherits = Generic HIPS @MK4; *ABS08MK4* + [filament:Prusa PETG] inherits = *PET* renamed_from = "Prusa PET" @@ -6369,7 +7973,7 @@ filament_vendor = Made for Prusa filament_cost = 27.82 filament_density = 1.27 filament_spool_weight = 230 -compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusa PETG @PG] inherits = Prusa PETG; *PETPG* @@ -6386,7 +7990,7 @@ filament_vendor = Verbatim filament_cost = 27.90 filament_density = 1.27 filament_spool_weight = 235 -compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim PETG @PG] inherits = Verbatim PETG; *PETPG* @@ -6406,7 +8010,7 @@ filament_cost = 36.29 filament_density = 1.27 filament_spool_weight = 201 filament_type = PETG -compatible_printers_condition = nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PETG @PG] inherits = Prusament PETG; *PETPG* @@ -6428,7 +8032,7 @@ extrusion_multiplier = 1.03 filament_cost = 54.99 filament_density = 1.27 filament_colour = #BBBBBB -compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:Prusament PETG Carbon Fiber @PG] inherits = Prusament PETG; *PETPG*; *04PLUSPG* @@ -6439,34 +8043,34 @@ inherits = Prusament PETG Carbon Fiber @PG; *PET06PG* [filament:Prusament PETG Carbon Fiber @PG 0.8] inherits = Prusament PETG Carbon Fiber @PG; *PET08PG* -[filament:Prusament PETG Tungsten 75%] -inherits = *PET* -filament_vendor = Prusa Polymers -filament_colour = #BBBBBB -first_layer_temperature = 255 -temperature = 265 -filament_cost = 277.09 -filament_density = 4 -filament_spool_weight = 201 -filament_type = PETG -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) -cooling = 0 -min_fan_speed = 50 -max_fan_speed = 70 -start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.01{else}0{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif nozzle_diameter[0]==0.4}M900 K12{else}M900 K0{endif} ; Filament gcode LA 1.0" +## [filament:Prusament PETG Tungsten 75%] +## inherits = *PET* +## filament_vendor = Prusa Polymers +## filament_colour = #BBBBBB +## first_layer_temperature = 255 +## temperature = 265 +## filament_cost = 277.09 +## filament_density = 4 +## filament_spool_weight = 201 +## filament_type = PETG +## compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) +## cooling = 0 +## min_fan_speed = 50 +## max_fan_speed = 70 +## start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.01{else}0{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif nozzle_diameter[0]==0.4}M900 K12{else}M900 K0{endif} ; Filament gcode LA 1.0" -[filament:Prusament PETG Tungsten 75% @PG] -inherits = Prusament PETG Tungsten 75%; *PETPG* -filament_max_volumetric_speed = 8 -start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.01{else}0{endif} ; Filament gcode" +## [filament:Prusament PETG Tungsten 75% @PG] +## inherits = Prusament PETG Tungsten 75%; *PETPG* +## filament_max_volumetric_speed = 8 +## start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.01{else}0{endif} ; Filament gcode" -[filament:Prusament PETG Tungsten 75% @PG 0.6] -inherits = Prusament PETG Tungsten 75% @PG; *PET06PG* -filament_max_volumetric_speed = 9 +## [filament:Prusament PETG Tungsten 75% @PG 0.6] +## inherits = Prusament PETG Tungsten 75% @PG; *PET06PG* +## filament_max_volumetric_speed = 9 -[filament:Prusament PETG Tungsten 75% @PG 0.8] -inherits = Prusament PETG Tungsten 75% @PG; *PET08PG* -filament_max_volumetric_speed = 10 +## [filament:Prusament PETG Tungsten 75% @PG 0.8] +## inherits = Prusament PETG Tungsten 75% @PG; *PET08PG* +## filament_max_volumetric_speed = 10 [filament:Prusa PETG @0.6 nozzle] inherits = *PET06* @@ -6635,7 +8239,7 @@ filament_vendor = Made for Prusa filament_cost = 27.82 filament_density = 1.24 filament_spool_weight = 230 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusa PLA @PG] inherits = Prusa PLA; *PLAPG* @@ -6781,6 +8385,17 @@ inherits = Eolas Prints TPU 93A @PG; *FLEX06PG* [filament:Eolas Prints TPU 93A @PG 0.8] inherits = Eolas Prints TPU 93A @PG; *FLEX08PG* +[filament:Eolas Prints TPU 93A @MK4] +inherits = Eolas Prints TPU 93A; *FLEXMK4* +extrusion_multiplier = 1.1 +filament_retract_length = 2.5 + +[filament:Eolas Prints TPU 93A @MK4 0.6] +inherits = Eolas Prints TPU 93A @MK4; *FLEX06MK4* + +[filament:Eolas Prints TPU 93A @MK4 0.8] +inherits = Eolas Prints TPU 93A @MK4; *FLEX08MK4* + [filament:Print With Smile PLA] inherits = *PLA* filament_vendor = Print With Smile @@ -6860,6 +8475,17 @@ inherits = Print With Smile ASA @PG; *ABS08PG* first_layer_temperature = 255 temperature = 255 +[filament:Print With Smile ASA @MK4] +inherits = Print With Smile ASA; *ABSMK4* + +[filament:Print With Smile ASA @MK4 0.6] +inherits = Print With Smile ASA @MK4; *ABS06MK4* + +[filament:Print With Smile ASA @MK4 0.8] +inherits = Print With Smile ASA @MK4; *ABS08MK4* +first_layer_temperature = 255 +temperature = 255 + [filament:Print With Smile ABS] inherits = *ABSC* filament_vendor = Print With Smile @@ -6882,6 +8508,15 @@ inherits = Print With Smile ABS @PG; *ABS06PG* [filament:Print With Smile ABS @PG 0.8] inherits = Print With Smile ABS @PG; *ABS08PG* +[filament:Print With Smile ABS @MK4] +inherits = Print With Smile ABS; *ABSMK4* + +[filament:Print With Smile ABS @MK4 0.6] +inherits = Print With Smile ABS @MK4; *ABS06MK4* + +[filament:Print With Smile ABS @MK4 0.8] +inherits = Print With Smile ABS @MK4; *ABS08MK4* + [filament:Print With Smile PETG CF] inherits = Extrudr XPETG CF filament_vendor = Print With Smile @@ -6930,14 +8565,27 @@ filament_deretract_speed = 20 [filament:Print With Smile TPU96A @PG] inherits = Print With Smile TPU96A; *FLEXPG* filament_retract_length = 2 -filament_max_volumetric_speed = 3 +filament_max_volumetric_speed = 2.5 [filament:Print With Smile TPU96A @PG 0.6] inherits = Print With Smile TPU96A @PG; *FLEX06PG* -filament_max_volumetric_speed = 5 +filament_max_volumetric_speed = 3.5 [filament:Print With Smile TPU96A @PG 0.8] inherits = Print With Smile TPU96A @PG; *FLEX08PG* +filament_max_volumetric_speed = 7 + +[filament:Print With Smile TPU96A @MK4] +inherits = Print With Smile TPU96A; *FLEXMK4* +filament_retract_length = 2 +filament_max_volumetric_speed = 3 + +[filament:Print With Smile TPU96A @MK4 0.6] +inherits = Print With Smile TPU96A @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 5 + +[filament:Print With Smile TPU96A @MK4 0.8] +inherits = Print With Smile TPU96A @MK4; *FLEX08MK4* filament_max_volumetric_speed = 8 [filament:Fiberlogy Easy PLA] @@ -6966,7 +8614,7 @@ filament_vendor = Fiberlogy filament_spool_weight = 330 filament_cost = 20 filament_density = 1.27 -compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material first_layer_bed_temperature = 80 bed_temperature = 80 first_layer_temperature = 235 @@ -7019,6 +8667,15 @@ inherits = Fiberlogy ASA @PG; *ABS06PG* [filament:Fiberlogy ASA @PG 0.8] inherits = Fiberlogy ASA @PG; *ABS08PG* +[filament:Fiberlogy ASA @MK4] +inherits = Fiberlogy ASA; *ABSMK4* + +[filament:Fiberlogy ASA @MK4 0.6] +inherits = Fiberlogy ASA @MK4; *ABS06MK4* + +[filament:Fiberlogy ASA @MK4 0.8] +inherits = Fiberlogy ASA @MK4; *ABS08MK4* + [filament:Fiberlogy ASA @MINI] inherits = Fiberlogy ASA; *ABSMINI* @@ -7042,12 +8699,15 @@ disable_fan_first_layers = 5 [filament:Fiberlogy Easy ABS @PG] inherits = Fiberlogy Easy ABS; *ABSPG* +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberlogy Easy ABS @PG 0.6] inherits = Fiberlogy Easy ABS; *ABS06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberlogy Easy ABS @PG 0.8] inherits = Fiberlogy Easy ABS; *ABS08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberlogy Easy ABS @MINI] inherits = Fiberlogy Easy ABS; *ABSMINI* @@ -7139,7 +8799,7 @@ filament_spool_weight = 330 [filament:Fiberlogy FiberFlex 40D @PG] inherits = Fiberlogy FiberFlex 40D; *FLEXPG* -filament_max_volumetric_speed = 4 +filament_max_volumetric_speed = 3 filament_retract_length = 2.2 extrusion_multiplier = 1.1 first_layer_temperature = 220 @@ -7147,10 +8807,26 @@ temperature = 220 [filament:Fiberlogy FiberFlex 40D @PG 0.6] inherits = Fiberlogy FiberFlex 40D @PG; *FLEX06PG* -filament_max_volumetric_speed = 6 +filament_max_volumetric_speed = 4.5 [filament:Fiberlogy FiberFlex 40D @PG 0.8] inherits = Fiberlogy FiberFlex 40D @PG; *FLEX08PG* +filament_max_volumetric_speed = 9 + +[filament:Fiberlogy FiberFlex 40D @MK4] +inherits = Fiberlogy FiberFlex 40D; *FLEXMK4* +filament_max_volumetric_speed = 4 +filament_retract_length = 2.2 +extrusion_multiplier = 1.1 +first_layer_temperature = 220 +temperature = 220 + +[filament:Fiberlogy FiberFlex 40D @MK4 0.6] +inherits = Fiberlogy FiberFlex 40D @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6 + +[filament:Fiberlogy FiberFlex 40D @MK4 0.8] +inherits = Fiberlogy FiberFlex 40D @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:Fiberlogy FiberFlex 40D @MINI] @@ -7184,15 +8860,28 @@ filament_retract_length = 1.2 [filament:Fiberlogy MattFlex 40D @PG] inherits = Fiberlogy MattFlex 40D; *FLEXPG* -filament_max_volumetric_speed = 4 +filament_max_volumetric_speed = 3 filament_retract_length = 2.2 [filament:Fiberlogy MattFlex 40D @PG 0.6] inherits = Fiberlogy MattFlex 40D @PG; *FLEX06PG* -filament_max_volumetric_speed = 6 +filament_max_volumetric_speed = 4.5 [filament:Fiberlogy MattFlex 40D @PG 0.8] inherits = Fiberlogy MattFlex 40D @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Fiberlogy MattFlex 40D @MK4] +inherits = Fiberlogy MattFlex 40D; *FLEXMK4* +filament_max_volumetric_speed = 4 +filament_retract_length = 2.2 + +[filament:Fiberlogy MattFlex 40D @MK4 0.6] +inherits = Fiberlogy MattFlex 40D @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 6 + +[filament:Fiberlogy MattFlex 40D @MK4 0.8] +inherits = Fiberlogy MattFlex 40D @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:Fiberlogy FiberFlex 30D] @@ -7208,7 +8897,7 @@ filament_retract_length = 1.2 [filament:Fiberlogy FiberFlex 30D @PG] inherits = Fiberlogy FiberFlex 30D; *FLEXPG* -filament_max_volumetric_speed = 3.5 +filament_max_volumetric_speed = 2.5 filament_retract_length = 3 first_layer_temperature = 220 temperature = 220 @@ -7218,10 +8907,28 @@ extrusion_multiplier = 1.1 [filament:Fiberlogy FiberFlex 30D @PG 0.6] inherits = Fiberlogy FiberFlex 30D @PG; *FLEX06PG* -filament_max_volumetric_speed = 7 +filament_max_volumetric_speed = 5 [filament:Fiberlogy FiberFlex 30D @PG 0.8] inherits = Fiberlogy FiberFlex 30D @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Fiberlogy FiberFlex 30D @MK4] +inherits = Fiberlogy FiberFlex 30D; *FLEXMK4* +filament_max_volumetric_speed = 3.5 +filament_retract_length = 3 +first_layer_temperature = 220 +temperature = 220 +first_layer_bed_temperature = 55 +bed_temperature = 55 +extrusion_multiplier = 1.1 + +[filament:Fiberlogy FiberFlex 30D @MK4 0.6] +inherits = Fiberlogy FiberFlex 30D @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 7 + +[filament:Fiberlogy FiberFlex 30D @MK4 0.8] +inherits = Fiberlogy FiberFlex 30D @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:Fiberlogy FiberSatin] @@ -7367,6 +9074,18 @@ filament_max_volumetric_speed = 8 inherits = Fiberlogy Nylon PA12 @PG; *ABS08PG* filament_max_volumetric_speed = 11 +[filament:Fiberlogy Nylon PA12 @MK4] +inherits = Fiberlogy Nylon PA12; *ABSMK4* +filament_max_volumetric_speed = 6 + +[filament:Fiberlogy Nylon PA12 @MK4 0.6] +inherits = Fiberlogy Nylon PA12 @MK4; *ABS06MK4* +filament_max_volumetric_speed = 8 + +[filament:Fiberlogy Nylon PA12 @MK4 0.8] +inherits = Fiberlogy Nylon PA12 @MK4; *ABS08MK4* +filament_max_volumetric_speed = 11 + [filament:Fiberlogy Nylon PA12+CF15] inherits = Fiberlogy Nylon PA12 extrusion_multiplier = 0.97 @@ -7382,13 +9101,14 @@ fan_below_layer_time = 20 bridge_fan_speed = 30 fan_always_on = 0 filament_max_volumetric_speed = 8 -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberlogy Nylon PA12+CF15 @PG] inherits = Fiberlogy Nylon PA12+CF15; *ABSPG*; *04PLUSPG* first_layer_bed_temperature = 100 bed_temperature = 105 filament_max_volumetric_speed = 8 +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="XL" and ! single_extruder_multi_material [filament:Fiberlogy Nylon PA12+CF15 @PG 0.6] inherits = Fiberlogy Nylon PA12+CF15 @PG; *ABS06PG* @@ -7398,6 +9118,19 @@ filament_max_volumetric_speed = 10 inherits = Fiberlogy Nylon PA12+CF15 @PG; *ABS08PG* filament_max_volumetric_speed = 12 +[filament:Fiberlogy Nylon PA12+CF15 @MK4] +inherits = Fiberlogy Nylon PA12+CF15; *ABSMK4*; *04PLUSPG* +filament_max_volumetric_speed = 8 +compatible_printers_condition = nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_model=="MK4" and ! single_extruder_multi_material + +[filament:Fiberlogy Nylon PA12+CF15 @MK4 0.6] +inherits = Fiberlogy Nylon PA12+CF15 @MK4; *ABS06MK4* +filament_max_volumetric_speed = 10 + +[filament:Fiberlogy Nylon PA12+CF15 @MK4 0.8] +inherits = Fiberlogy Nylon PA12+CF15 @MK4; *ABS08MK4* +filament_max_volumetric_speed = 12 + [filament:Fiberlogy Nylon PA12+GF15] inherits = Fiberlogy Nylon PA12+CF15 filament_density = 1.13 @@ -7415,6 +9148,18 @@ filament_density = 1.13 inherits = Fiberlogy Nylon PA12+CF15 @PG 0.8 filament_density = 1.13 +[filament:Fiberlogy Nylon PA12+GF15 @MK4] +inherits = Fiberlogy Nylon PA12+CF15 @MK4 +filament_density = 1.13 + +[filament:Fiberlogy Nylon PA12+GF15 @MK4 0.6] +inherits = Fiberlogy Nylon PA12+CF15 @MK4 0.6 +filament_density = 1.13 + +[filament:Fiberlogy Nylon PA12+GF15 @MK4 0.8] +inherits = Fiberlogy Nylon PA12+CF15 @MK4 0.8 +filament_density = 1.13 + [filament:Fiberlogy PP] inherits = *ABS* filament_vendor = Fiberlogy @@ -7441,16 +9186,19 @@ filament_max_volumetric_speed = 5 [filament:Fiberlogy PP @PG] inherits = Fiberlogy PP; *ABSPG* filament_max_volumetric_speed = 5 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberlogy PP @PG 0.6] inherits = Fiberlogy PP @PG; *ABS06PG* filament_max_volumetric_speed = 7 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberlogy PP @PG 0.8] inherits = Fiberlogy PP @PG; *ABS08PG* filament_max_volumetric_speed = 10 first_layer_temperature = 250 temperature = 250 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Filament PM PLA] inherits = *PLA* @@ -7602,7 +9350,7 @@ filament_cost = 36.29 filament_density = 1.24 filament_spool_weight = 201 filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa" -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PLA @PG] inherits = Prusament PLA; *PLAPG* @@ -7629,7 +9377,7 @@ filament_max_volumetric_speed = 8 filament_type = PVB filament_soluble = 1 filament_colour = #FFFF6F -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.05{else}0.08{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0" @@ -7743,16 +9491,30 @@ filament_deretract_speed = 20 [filament:Fillamentum Flexfill 98A @PG] inherits = Fillamentum Flexfill 98A; *FLEXPG* -filament_max_volumetric_speed = 3 +filament_max_volumetric_speed = 2.5 filament_retract_length = 3 extrusion_multiplier = 1.08 [filament:Fillamentum Flexfill 98A @PG 0.6] inherits = Fillamentum Flexfill 98A @PG; *FLEX06PG* -filament_max_volumetric_speed = 5 +filament_max_volumetric_speed = 3 [filament:Fillamentum Flexfill 98A @PG 0.8] inherits = Fillamentum Flexfill 98A @PG; *FLEX08PG* +filament_max_volumetric_speed = 8 + +[filament:Fillamentum Flexfill 98A @MK4] +inherits = Fillamentum Flexfill 98A; *FLEXMK4* +filament_max_volumetric_speed = 3 +filament_retract_length = 3 +extrusion_multiplier = 1.08 + +[filament:Fillamentum Flexfill 98A @MK4 0.6] +inherits = Fillamentum Flexfill 98A @MK4; *FLEX06MK4* +filament_max_volumetric_speed = 4 + +[filament:Fillamentum Flexfill 98A @MK4 0.8] +inherits = Fillamentum Flexfill 98A @MK4; *FLEX08MK4* filament_max_volumetric_speed = 10 [filament:ColorFabb VarioShore TPU] @@ -7770,6 +9532,10 @@ temperature = 220 inherits = ColorFabb VarioShore TPU; *FLEXPG* filament_max_volumetric_speed = 1.5 +[filament:ColorFabb VarioShore TPU @MK4] +inherits = ColorFabb VarioShore TPU; *FLEXMK4* +filament_max_volumetric_speed = 1.5 + [filament:Taulman Bridge] inherits = *common* filament_vendor = Taulman @@ -7791,7 +9557,7 @@ temperature = 260 max_fan_speed = 0 min_fan_speed = 0 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.08{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0" -compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Taulman Bridge @PG] inherits = Taulman Bridge; *ABSPG* @@ -7808,6 +9574,20 @@ filament_max_volumetric_speed = 12 first_layer_temperature = 270 temperature = 270 +[filament:Taulman Bridge @MK4] +inherits = Taulman Bridge; *ABSMK4* +filament_max_volumetric_speed = 7 + +[filament:Taulman Bridge @MK4 0.6] +inherits = Taulman Bridge @MK4; *ABS06MK4* +filament_max_volumetric_speed = 9 + +[filament:Taulman Bridge @MK4 0.8] +inherits = Taulman Bridge @MK4; *ABS08MK4* +filament_max_volumetric_speed = 12 +first_layer_temperature = 270 +temperature = 270 + [filament:Taulman Bridge @MINI] inherits = Taulman Bridge bed_temperature = 90 @@ -7844,14 +9624,17 @@ temperature = 250 [filament:Fillamentum Nylon FX256 @PG] inherits = Fillamentum Nylon FX256; *PAPG* filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fillamentum Nylon FX256 @PG 0.6] inherits = Fillamentum Nylon FX256 @PG; *PA06PG* filament_max_volumetric_speed = 8 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fillamentum Nylon FX256 @PG 0.8] inherits = Fillamentum Nylon FX256 @PG; *PA08PG* filament_max_volumetric_speed = 11 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA Pure Pro] inherits = *common* @@ -7881,19 +9664,28 @@ filament_retract_speed = 40 filament_retract_lift = nil filament_retract_before_travel = 1.5 filament_wipe = 0 -compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA Pure Pro @PG] inherits = Fiberthree F3 PA Pure Pro; *PAPG* filament_max_volumetric_speed = 5 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA Pure Pro @PG 0.6] inherits = Fiberthree F3 PA Pure Pro @PG; *PA06PG* filament_max_volumetric_speed = 7 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA Pure Pro @PG 0.8] inherits = Fiberthree F3 PA Pure Pro @PG; *PA08PG* filament_max_volumetric_speed = 10 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-CF Pro] inherits = *common* @@ -7923,19 +9715,28 @@ filament_retract_speed = 40 filament_retract_lift = nil filament_retract_before_travel = 1.5 filament_wipe = 0 -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-CF Pro @PG] inherits = Fiberthree F3 PA-CF Pro; *PAPG* filament_max_volumetric_speed = 5 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-CF Pro @PG 0.6] inherits = Fiberthree F3 PA-CF Pro; *PA06PG* filament_max_volumetric_speed = 7 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-CF Pro @PG 0.8] inherits = Fiberthree F3 PA-CF Pro; *PA08PG* filament_max_volumetric_speed = 10 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-GF Pro] inherits = Fiberthree F3 PA-CF Pro @@ -7949,14 +9750,23 @@ min_fan_speed = 15 [filament:Fiberthree F3 PA-GF Pro @PG] inherits = Fiberthree F3 PA-GF Pro; *PAPG* filament_max_volumetric_speed = 5 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-GF Pro @PG 0.6] inherits = Fiberthree F3 PA-GF Pro @PG; *PA06PG* filament_max_volumetric_speed = 7 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-GF Pro @PG 0.8] inherits = Fiberthree F3 PA-GF Pro @PG; *PA08PG* filament_max_volumetric_speed = 10 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-GF30 Pro] inherits = Prusament PC Blend Carbon Fiber @@ -7969,7 +9779,7 @@ temperature = 285 first_layer_bed_temperature = 90 bed_temperature = 90 fan_below_layer_time = 10 -compatible_printers_condition = printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material max_fan_speed = 15 min_fan_speed = 15 filament_type = PA @@ -7978,14 +9788,23 @@ filament_max_volumetric_speed = 6 [filament:Fiberthree F3 PA-GF30 Pro @PG] inherits = Fiberthree F3 PA-GF30 Pro; *PAPG* filament_max_volumetric_speed = 6 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-GF30 Pro @PG 0.6] inherits = Fiberthree F3 PA-GF30 Pro @PG; *PA06PG* filament_max_volumetric_speed = 7.5 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Fiberthree F3 PA-GF30 Pro @PG 0.8] inherits = Fiberthree F3 PA-GF30 Pro @PG; *PA08PG* filament_max_volumetric_speed = 10 +bed_temperature = 90 +first_layer_bed_temperature = 90 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Taulman T-Glase] inherits = *PET* @@ -8003,12 +9822,15 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Taulman T-Glase @PG] inherits = Taulman T-Glase; *PAPG* +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Taulman T-Glase @PG 0.6] inherits = Taulman T-Glase @PG; *PA06PG* +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Taulman T-Glase @PG 0.8] inherits = Taulman T-Glase @PG; *PA08PG* +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim PLA] inherits = *PLA* @@ -8055,14 +9877,17 @@ temperature = 210 [filament:Verbatim BVOH @PG] inherits = Verbatim BVOH; *ABSPG* filament_max_volumetric_speed = 4 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim BVOH @PG 0.6] inherits = Verbatim BVOH @PG; *ABS06PG* filament_max_volumetric_speed = 6 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim BVOH @PG 0.8] inherits = Verbatim BVOH @PG; *ABS08PG* filament_max_volumetric_speed = 9 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim BVOH @MMU2] inherits = Verbatim BVOH @@ -8148,14 +9973,17 @@ temperature = 220 [filament:Verbatim PP @PG] inherits = Verbatim PP; *ABSPG* filament_max_volumetric_speed = 5 +compatible_printers_condition = nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim PP @PG 0.6] inherits = Verbatim PP @PG; *ABS06PG* filament_max_volumetric_speed = 7 +compatible_printers_condition = nozzle_diameter[0]==0.6 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:Verbatim PP @PG 0.8] inherits = Verbatim PP @PG; *ABS08PG* filament_max_volumetric_speed = 10 +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes=~/.*PG.*/ and ! single_extruder_multi_material [filament:FormFutura Centaur PP] inherits = *common* @@ -8181,7 +10009,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no temperature = 235 filament_wipe = 0 filament_retract_lift = 0 -compatible_printers_condition = nozzle_diameter[0]>=0.35 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]>=0.35 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:FormFutura Centaur PP @PG] inherits = FormFutura Centaur PP; *PETPG* @@ -8437,12 +10265,12 @@ filament_cost = 54.99 filament_colour = #BBBBBB compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]>=0.4 and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 -[filament:Prusament PETG Tungsten 75% @MINI] -inherits = Prusament PETG Tungsten 75%; *PETMINI* -full_fan_speed_layer = 5 -start_filament_gcode = "M900 K0" -filament_colour = #BBBBBB -compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MINI" +## [filament:Prusament PETG Tungsten 75% @MINI] +## inherits = Prusament PETG Tungsten 75%; *PETMINI* +## full_fan_speed_layer = 5 +## start_filament_gcode = "M900 K0" +## filament_colour = #BBBBBB +## compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MINI" [filament:Kimya PETG Carbon @MINI] inherits = Kimya PETG Carbon; *PETMINI* @@ -8697,14 +10525,14 @@ first_layer_temperature = 220 temperature = 220 filament_max_volumetric_speed = 15 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic ABS @0.8 nozzle] inherits = Generic ABS first_layer_temperature = 265 temperature = 265 filament_max_volumetric_speed = 15 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic PETG @0.8 nozzle] inherits = Generic PETG @@ -8713,7 +10541,7 @@ temperature = 250 filament_max_volumetric_speed = 20 filament_retract_lift = 0.2 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusa PLA @0.8 nozzle] inherits = Prusa PLA @@ -8721,7 +10549,7 @@ first_layer_temperature = 220 temperature = 220 filament_max_volumetric_speed = 15 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusa PETG @0.8 nozzle] inherits = Prusa PETG @@ -8729,26 +10557,26 @@ first_layer_temperature = 240 temperature = 250 filament_max_volumetric_speed = 20 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusa ABS @0.8 nozzle] inherits = Prusa ABS first_layer_temperature = 265 temperature = 265 filament_max_volumetric_speed = 15 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic FLEX @0.8 nozzle] inherits = Generic FLEX filament_max_volumetric_speed = 4.3 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Generic HIPS @0.8 nozzle] inherits = Generic HIPS first_layer_temperature = 240 temperature = 240 filament_max_volumetric_speed = 15 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PLA @0.8 nozzle] inherits = Prusament PLA @@ -8756,7 +10584,7 @@ first_layer_temperature = 225 temperature = 225 filament_max_volumetric_speed = 15 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PETG @0.8 nozzle] inherits = Prusament PETG @@ -8765,7 +10593,7 @@ temperature = 260 filament_max_volumetric_speed = 20 filament_retract_lift = 0.2 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PETG Carbon Fiber @0.8 nozzle] inherits = Prusament PETG @0.8 nozzle @@ -8781,64 +10609,64 @@ first_layer_temperature = 265 temperature = 265 filament_max_volumetric_speed = 15 slowdown_below_layer_time = 20 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PC Blend @0.8 nozzle] inherits = Prusament PC Blend filament_max_volumetric_speed = 13 filament_retract_lift = 0.25 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PC Blend Carbon Fiber @0.8 nozzle] inherits = Prusament PC Blend Carbon Fiber filament_max_volumetric_speed = 13 filament_retract_lift = 0.25 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PA11 Carbon Fiber @0.8 nozzle] inherits = Prusament PA11 Carbon Fiber filament_max_volumetric_speed = 11 -compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and nozzle_diameter[0]==0.8 and printer_model!="MINI" and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material [filament:Prusament PA11 Carbon Fiber @0.8 nozzle MK2] inherits = Prusament PA11 Carbon Fiber @MK2 filament_max_volumetric_speed = 11 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="XL" and printer_notes=~/.*PRINTER_MODEL_MK(2|2.5).*/ and ! (printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2|2.5).*/ and ! (printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and single_extruder_multi_material) [filament:Prusament PC Blend @0.8 nozzle MK2] inherits = Prusament PC Blend @MK2 filament_max_volumetric_speed = 13 filament_retract_lift = 0.25 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_model!="XL" and printer_notes=~/.*PRINTER_MODEL_MK(2|2.5).*/ and ! (printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and single_extruder_multi_material) +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="MK2SMM" and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2|2.5).*/ and ! (printer_notes=~/.*PRINTER_MODEL_MK2.5.*/ and single_extruder_multi_material) [filament:Prusament PVB @0.8 nozzle] inherits = Prusament PVB first_layer_temperature = 225 temperature = 225 filament_max_volumetric_speed = 15 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and ! single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and ! single_extruder_multi_material slowdown_below_layer_time = 20 ## Filaments 0.8 nozzle MMU2 [filament:Generic HIPS @MMU2 0.8 nozzle] inherits = Generic HIPS @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material [filament:Prusament ASA @MMU2 0.8 nozzle] inherits = Prusament ASA @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material slowdown_below_layer_time = 20 filament_max_volumetric_speed = 14 [filament:Prusament PC Blend @MMU2 0.8 nozzle] inherits = Prusament PC Blend @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 12 [filament:Generic PETG @MMU2 0.8 nozzle] inherits = Generic PETG @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 18 first_layer_temperature = 240 temperature = 240 @@ -8847,7 +10675,7 @@ filament_ramming_parameters = "120 140 5.51613 5.6129 5.70968 5.77419 5.77419 5. [filament:Prusament PETG @MMU2 0.8 nozzle] inherits = Prusament PETG @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 18 first_layer_temperature = 240 temperature = 240 @@ -8864,26 +10692,26 @@ filament_colour = #BBBBBB [filament:Generic PLA @MMU2 0.8 nozzle] inherits = Generic PLA @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 14 first_layer_temperature = 215 temperature = 210 [filament:Prusament PLA @MMU2 0.8 nozzle] inherits = Prusament PLA @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 14 first_layer_temperature = 215 temperature = 210 [filament:Verbatim BVOH @MMU2 0.8 nozzle] inherits = Verbatim BVOH @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 8 [filament:PrimaSelect PVA+ @MMU2 0.8 nozzle] inherits = PrimaSelect PVA+ @MMU2 -compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_model!="XL" and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material +compatible_printers_condition = nozzle_diameter[0]==0.8 and printer_notes!~/.*PG.*/ and printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material filament_max_volumetric_speed = 8 ## Filaments 0.8 nozzle MINI @@ -9413,6 +11241,22 @@ material_type = Tough material_vendor = Prusa Polymers material_colour = #EC0000 +[sla_material:Prusament Resin Model Solid Grey @0.025] +inherits = *common 0.025* +exposure_time = 4.5 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #9C9D9D + +[sla_material:Prusament Resin Model Alabaster White @0.025] +inherits = *common 0.025* +exposure_time = 4.5 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #D6D7D8 + [sla_material:Prusament Resin BioBased60 Herbal Green @0.025] inherits = *common 0.025* exposure_time = 7 @@ -10426,6 +12270,22 @@ material_type = Tough material_vendor = Prusa Polymers material_colour = #EC0000 +[sla_material:Prusament Resin Model Solid Grey @0.05] +inherits = *common 0.05* +exposure_time = 5 +initial_exposure_time = 35 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #9C9D9D + +[sla_material:Prusament Resin Model Alabaster White @0.05] +inherits = *common 0.05* +exposure_time = 5 +initial_exposure_time = 30 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #D6D7D8 + [sla_material:Prusament Resin BioBased60 Herbal Green @0.05] inherits = *common 0.05* exposure_time = 8 @@ -10878,6 +12738,22 @@ material_type = Tough material_vendor = Prusa Polymers material_colour = #3AD200 +[sla_material:Prusament Resin Model Solid Grey @0.1] +inherits = *common 0.1* +exposure_time = 13 +initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #9C9D9D + +[sla_material:Prusament Resin Model Alabaster White @0.1] +inherits = *common 0.1* +exposure_time = 13 +initial_exposure_time = 45 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #D6D7D8 + [sla_material:Prusament Resin BioBased60 Magma Red @0.1] inherits = *common 0.1* exposure_time = 13 @@ -11134,6 +13010,22 @@ material_type = Tough material_vendor = Prusa Polymers material_colour = #EC0000 +[sla_material:Prusament Resin Model Solid Grey @0.025 SL1S] +inherits = *0.025_sl1s* +exposure_time = 2 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #9C9D9D + +[sla_material:Prusament Resin Model Alabaster White @0.025 SL1S] +inherits = *0.025_sl1s* +exposure_time = 2 +initial_exposure_time = 20 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #D6D7D8 + [sla_material:Prusament Resin BioBased60 Herbal Green @0.025 SL1S] inherits = *0.025_sl1s* exposure_time = 3.5 @@ -11612,6 +13504,22 @@ material_type = Tough material_vendor = Prusa Polymers material_colour = #EC0000 +[sla_material:Prusament Resin Model Solid Grey @0.05 SL1S] +inherits = *0.05_sl1s* +exposure_time = 2.2 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #9C9D9D + +[sla_material:Prusament Resin Model Alabaster White @0.05 SL1S] +inherits = *0.05_sl1s* +exposure_time = 2.2 +initial_exposure_time = 20 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #D6D7D8 + [sla_material:Prusament Resin BioBased60 Herbal Green @0.05 SL1S] inherits = *0.05_sl1s* exposure_time = 4 @@ -12294,6 +14202,30 @@ material_type = Tough material_vendor = 3DJake material_colour = #007EFD +[sla_material:LOCTITE 3D IND475 @0.05 SL1S] +inherits = *0.05_sl1s* +exposure_time = 4 +initial_exposure_time = 15 +material_type = Flexible +material_vendor = Henkel +material_colour = #FFFFFF + +[sla_material:LOCTITE 3D PRO476 @0.05 SL1S] +inherits = *0.05_sl1s* +exposure_time = 7 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Henkel +material_colour = #595959 + +[sla_material:LOCTITE 3D 3843 HDT60 High Toughness @0.05 SL1S] +inherits = *0.05_sl1s* +exposure_time = 13 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Henkel +material_colour = #595959 + ## 0.1 SL1S ## Prusa Polymers 0.1 @@ -12394,6 +14326,22 @@ material_type = Tough material_vendor = Prusa Polymers material_colour = #EC0000 +[sla_material:Prusament Resin Model Solid Grey @0.1 SL1S] +inherits = *0.1_sl1s* +exposure_time = 2.8 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #9C9D9D + +[sla_material:Prusament Resin Model Alabaster White @0.1 SL1S] +inherits = *0.1_sl1s* +exposure_time = 2.8 +initial_exposure_time = 20 +material_type = Tough +material_vendor = Prusa Polymers +material_colour = #D6D7D8 + [sla_material:Prusament Resin BioBased60 Herbal Green @0.1 SL1S] inherits = *0.1_sl1s* exposure_time = 5 @@ -12754,6 +14702,30 @@ material_type = Tough material_vendor = 3DJake material_colour = #007EFD +[sla_material:LOCTITE 3D IND475 @0.1 SL1S] +inherits = *0.1_sl1s* +exposure_time = 6.5 +initial_exposure_time = 15 +material_type = Flexible +material_vendor = Henkel +material_colour = #FFFFFF + +[sla_material:LOCTITE 3D PRO476 @0.1 SL1S] +inherits = *0.1_sl1s* +exposure_time = 9 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Henkel +material_colour = #595959 + +[sla_material:LOCTITE 3D 3843 HDT60 High Toughness @0.1 SL1S] +inherits = *0.1_sl1s* +exposure_time = 18 +initial_exposure_time = 25 +material_type = Tough +material_vendor = Henkel +material_colour = #595959 + [printer:*common*] printer_technology = FFF bed_shape = 0x0,250x0,250x210,0x210 @@ -13577,7 +15549,7 @@ max_layer_height = 0.25 min_layer_height = 0.07 silent_mode = 0 remaining_times = 1 -printer_notes = PRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_XL\nPG +printer_notes = Do not remove the keywords below.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_XL\nPG retract_lift_below = 359 retract_speed = 35 deretract_speed = 25 @@ -13643,13 +15615,120 @@ machine_max_acceleration_travel = 1500 inherits = *commonXL* printer_variant = 0.8 nozzle_diameter = 0.8 -retract_length = 0.8 +retract_length = 0.6 +retract_before_wipe = 50% retract_lift = 0.25 +retract_speed = 25 +deretract_speed = 15 max_layer_height = 0.6 min_layer_height = 0.2 default_print_profile = 0.40mm QUALITY @XL 0.8 default_filament_profile = "Prusament PLA @PG 0.8" +[printer:*commonMK4*] +inherits = *common* +bed_shape = 0x0,250x0,250x210,0x210 +max_print_height = 220 +printer_variant = 0.4 +printer_model = MK4 +nozzle_diameter = 0.4 +end_gcode = {if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+1, max_print_height)} F720 ; Move print head up{endif}\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X241 Y170 F3600 ; park\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+23, max_print_height)} F300 ; Move print head up{endif}\nG4 ; wait\nM900 K0 ; reset LA\nM142 S36 ; reset heatbreak target temp\nM84 X Y E ; disable motors\n; max_layer_z = [max_layer_z] +machine_limits_usage = emit_to_gcode +machine_max_acceleration_e = 2500 +machine_max_acceleration_extruding = 2000 +machine_max_acceleration_retracting = 1200 +machine_max_acceleration_travel = 2000 +machine_max_acceleration_x = 2500 +machine_max_acceleration_y = 2500 +machine_max_acceleration_z = 200 +machine_max_feedrate_e = 100 +machine_max_feedrate_x = 200 +machine_max_feedrate_y = 200 +machine_max_feedrate_z = 40 +machine_max_jerk_e = 10 +machine_max_jerk_x = 8 +machine_max_jerk_y = 8 +machine_max_jerk_z = 2 +machine_min_extruding_rate = 0 +machine_min_travel_rate = 0 +max_layer_height = 0.25 +min_layer_height = 0.07 +silent_mode = 0 +remaining_times = 1 +printer_notes = Do not remove the keywords below.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK4\nPG +retract_lift_below = 219 +retract_speed = 35 +deretract_speed = 25 +retract_before_travel = 1.5 +retract_before_wipe = 80% +retract_layer_change = 1 +retract_length = 0.8 +start_gcode = M17 ; enable steppers\nM862.3 P "[printer_model]" ; printer model check\nM862.1 P[nozzle_diameter] ; nozzle diameter check\nM555 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} W{((min(print_bed_max[0], max(first_layer_print_min[0] + 32, first_layer_print_max[0])))) - ((min(print_bed_max[0], first_layer_print_min[0] + 32) - 32))} H{((first_layer_print_max[1])) - ((max(0, first_layer_print_min[1]) - 4))}\n\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\n\nM140 S[first_layer_bed_temperature] ; set bed temp\n{if filament_type[initial_tool]=="PC" or filament_type[initial_tool]=="NYLON"}\nM104 S{first_layer_temperature[initial_tool]-25} ; set extruder temp for bed leveling\nM109 R{first_layer_temperature[initial_tool]-25} ; wait for temp\n{elsif filament_type[initial_tool]=="FLEX"}\nM104 S210 ; set extruder temp for bed leveling\nM109 R210 ; wait for temp\n{else}\nM104 S170 ; set extruder temp for bed leveling\nM109 R170 ; wait for temp\n{endif}\n\nM84 E ; turn off E motor\n\nG28 ; home all without mesh bed level\n\n; probe to clean the nozzle\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)+32} Y{((first_layer_print_min[1]) - 4)} Z{5} F4800\n\nM302 S160 ; lower cold extrusion limit to 160C\n\n{if filament_type[initial_tool]=="FLEX"}\nG1 E-4 F2400 ; retraction\n{else}\nG1 E-2 F2400 ; retraction\n{endif}\n\nM84 E ; turn off E motor\n\nG29 P9 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} W{32} H{4}\n\n{if first_layer_bed_temperature[initial_tool]<=60}M106 S100{endif}\n\nG0 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4)} Z{40} F10000\n\nM190 S[first_layer_bed_temperature] ; wait for bed temp\n\nM107\n\n;\n; MBL\n;\nM84 E ; turn off E motor\nG29 ; mesh bed leveling\nM104 S[first_layer_temperature] ; set extruder temp\nG0 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} Y{(max(0, first_layer_print_min[1]) - 4) + 4 - 4.5} Z{30} F4800\n\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.2 F720\nG92 E0\n\nM569 S0 E ; set spreadcycle mode for extruder\n\n;\n; Extrude purge line\n;\n{if filament_type[initial_tool]=="FLEX"}\nG1 E4 F2400 ; deretraction\n{else}\nG1 E2 F2400 ; deretraction\n{endif}\n\n; move right\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32) + 32} E{32 * 0.15} F1000\n; move down\nG1 Y{(max(0, first_layer_print_min[1]) - 4) + 4 - 4.5 - 1.5} E{1.5 * 0.15} F1000\n; move left\nG1 X{(min(print_bed_max[0], first_layer_print_min[0] + 32) - 32)} E{32 * 0.30} F800\n\nG92 E0\nM221 S100 ; set flow to 100% +default_print_profile = 0.20mm QUALITY @MK4 0.4 +default_filament_profile = "Prusament PLA @PG" +thumbnails = 16x16,313x173,440x240 +thumbnails_format = PNG +gcode_flavor = marlin2 +high_current_on_filament_swap = 0 +retract_lift = 0.2 + +[printer:Original Prusa MK4 0.4 nozzle] +inherits = *commonMK4* +max_layer_height = 0.30 + +[printer:Original Prusa MK4 0.6 nozzle] +inherits = *commonMK4* +printer_variant = 0.6 +nozzle_diameter = 0.6 +retract_length = 0.7 +retract_lift = 0.2 +max_layer_height = 0.40 +min_layer_height = 0.15 +default_print_profile = 0.25mm QUALITY @MK4 0.6 + +[printer:Original Prusa MK4 0.5 nozzle] +inherits = *commonMK4* +printer_variant = 0.5 +nozzle_diameter = 0.5 +retract_length = 0.7 +max_layer_height = 0.32 +min_layer_height = 0.07 +default_print_profile = 0.20mm QUALITY @MK4 0.5 + +[printer:Original Prusa MK4 0.3 nozzle] +inherits = *commonMK4* +printer_variant = 0.3 +nozzle_diameter = 0.3 +retract_length = 0.7 +max_layer_height = 0.22 +min_layer_height = 0.05 +default_print_profile = 0.16mm QUALITY @MK4 0.3 + +[printer:Original Prusa MK4 0.25 nozzle] +inherits = *commonMK4* +printer_variant = 0.25 +nozzle_diameter = 0.25 +retract_length = 0.8 +retract_lift = 0.15 +max_layer_height = 0.15 +min_layer_height = 0.05 +default_print_profile = 0.12mm QUALITY @MK4 0.25 +machine_max_acceleration_travel = 1500 + +[printer:Original Prusa MK4 0.8 nozzle] +inherits = *commonMK4* +printer_variant = 0.8 +nozzle_diameter = 0.8 +retract_length = 0.6 +retract_before_wipe = 50% +retract_lift = 0.25 +retract_speed = 25 +deretract_speed = 15 +max_layer_height = 0.6 +min_layer_height = 0.2 +default_print_profile = 0.40mm QUALITY @MK4 0.8 +default_filament_profile = "Prusament PLA @PG 0.8" + [printer:Original Prusa SL1] printer_technology = SLA printer_model = SL1 From dcf5889cfaff31d3a849e5084965c41565cb5f53 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 29 Mar 2023 12:53:09 +0200 Subject: [PATCH 24/32] Fixed a save to 3mf: Added a check if cut information have to be saved to 3mf --- src/libslic3r/Format/3mf.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 5a608cb054..a0d5e1360d 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -2958,6 +2958,8 @@ namespace Slic3r { unsigned int object_cnt = 0; for (const ModelObject* object : model.objects) { + if (!object->is_cut()) + continue; object_cnt++; pt::ptree& obj_tree = tree.add("objects.object", ""); From eb2c121f9475a04042e497bbb24c633bc32df831 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 29 Mar 2023 14:20:31 +0200 Subject: [PATCH 25/32] Follow-up https://github.com/Prusa-Development/PrusaSlicerPrivate/commit/cc5660ad8cf28a134cad5164061d890441655612 - Fixed tooltip texts --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index d1623e41e9..bab6676763 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -3000,8 +3000,8 @@ void GLGizmoEmboss::draw_advanced() } if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", (m_keep_up? - _u8L("Unlock the text's up orientation when moving text along the object's surface."): - _u8L("Lock the text's up orientation when moving text along the object's surface.") + _u8L("Unlock the text's rotation when moving text along the object's surface."): + _u8L("Lock the text's rotation when moving text along the object's surface.") ).c_str()); // when more collection add selector From 9ed97abdb0fe0e168d2a5b6909c34443243e4763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Wed, 29 Mar 2023 14:08:28 +0200 Subject: [PATCH 26/32] Fix of #10034 (SPE-1608): Fixed crash inside Arachne caused by degenerated Voronoi diagram. Boost Voronoi diagram produced degenerated Voronoi diagram. This Voronoi diagram was detected by our method for detection of those types of degeneration. But rotation by PI / 6 wasn't able to fix it. So now, when the Voronoi diagram is still degenerated after the first rotation, then we try another rotation by different angles to fix the degenerated Voronoi diagram. --- .../Arachne/SkeletalTrapezoidation.cpp | 112 ++++++++++-------- tests/libslic3r/test_arachne.cpp | 54 +++++++++ 2 files changed, 116 insertions(+), 50 deletions(-) diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp index cd58f34c6c..381f18b700 100644 --- a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp +++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp @@ -522,44 +522,6 @@ static bool has_missing_twin_edge(const SkeletalTrapezoidationGraph &graph) return false; } -inline static std::unordered_map try_to_fix_degenerated_voronoi_diagram_by_rotation( - Geometry::VoronoiDiagram &voronoi_diagram, - const Polygons &polys, - Polygons &polys_rotated, - std::vector &segments, - const double fix_angle) -{ - std::unordered_map vertex_mapping; - for (Polygon &poly : polys_rotated) - poly.rotate(fix_angle); - - assert(polys_rotated.size() == polys.size()); - for (size_t poly_idx = 0; poly_idx < polys.size(); ++poly_idx) { - assert(polys_rotated[poly_idx].size() == polys[poly_idx].size()); - for (size_t point_idx = 0; point_idx < polys[poly_idx].size(); ++point_idx) - vertex_mapping.insert({polys_rotated[poly_idx][point_idx], polys[poly_idx][point_idx]}); - } - - segments.clear(); - for (size_t poly_idx = 0; poly_idx < polys_rotated.size(); poly_idx++) - for (size_t point_idx = 0; point_idx < polys_rotated[poly_idx].size(); point_idx++) - segments.emplace_back(&polys_rotated, poly_idx, point_idx); - - voronoi_diagram.clear(); - construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram); - -#ifdef ARACHNE_DEBUG_VORONOI - { - static int iRun = 0; - dump_voronoi_to_svg(debug_out_path("arachne_voronoi-diagram-rotated-%d.svg", iRun++).c_str(), voronoi_diagram, to_points(polys), to_lines(polys)); - } -#endif - - assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(voronoi_diagram)); - - return vertex_mapping; -} - inline static void rotate_back_skeletal_trapezoidation_graph_after_fix(SkeletalTrapezoidationGraph &graph, const double fix_angle, const std::unordered_map &vertex_mapping) @@ -626,6 +588,56 @@ VoronoiDiagramStatus detect_voronoi_diagram_known_issues(const Geometry::Voronoi return VoronoiDiagramStatus::NO_ISSUE_DETECTED; } +inline static std::pair, double> try_to_fix_degenerated_voronoi_diagram_by_rotation( + Geometry::VoronoiDiagram &voronoi_diagram, + const Polygons &polys, + Polygons &polys_rotated, + std::vector &segments, + const std::vector &fix_angles) +{ + const Polygons polys_rotated_original = polys_rotated; + double fixed_by_angle = fix_angles.front(); + std::unordered_map vertex_mapping; + + for (const double &fix_angle : fix_angles) { + vertex_mapping.clear(); + polys_rotated = polys_rotated_original; + fixed_by_angle = fix_angle; + + for (Polygon &poly : polys_rotated) + poly.rotate(fix_angle); + + assert(polys_rotated.size() == polys.size()); + for (size_t poly_idx = 0; poly_idx < polys.size(); ++poly_idx) { + assert(polys_rotated[poly_idx].size() == polys[poly_idx].size()); + for (size_t point_idx = 0; point_idx < polys[poly_idx].size(); ++point_idx) + vertex_mapping.insert({polys_rotated[poly_idx][point_idx], polys[poly_idx][point_idx]}); + } + + segments.clear(); + for (size_t poly_idx = 0; poly_idx < polys_rotated.size(); poly_idx++) + for (size_t point_idx = 0; point_idx < polys_rotated[poly_idx].size(); point_idx++) + segments.emplace_back(&polys_rotated, poly_idx, point_idx); + + voronoi_diagram.clear(); + construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram); + +#ifdef ARACHNE_DEBUG_VORONOI + { + static int iRun = 0; + dump_voronoi_to_svg(debug_out_path("arachne_voronoi-diagram-rotated-%d.svg", iRun++).c_str(), voronoi_diagram, to_points(polys), to_lines(polys)); + } +#endif + + if (detect_voronoi_diagram_known_issues(voronoi_diagram, segments) == VoronoiDiagramStatus::NO_ISSUE_DETECTED) + break; + } + + assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(voronoi_diagram)); + + return {vertex_mapping, fixed_by_angle}; +} + void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys) { #ifdef ARACHNE_DEBUG @@ -669,8 +681,9 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys) // When any Voronoi vertex is missing, the Voronoi diagram is not planar, or some voronoi edge is // intersecting input segment, rotate the input polygon and try again. - VoronoiDiagramStatus status = detect_voronoi_diagram_known_issues(voronoi_diagram, segments); - const double fix_angle = PI / 6; + VoronoiDiagramStatus status = detect_voronoi_diagram_known_issues(voronoi_diagram, segments); + const std::vector fix_angles = {PI / 6, PI / 5, PI / 7, PI / 11}; + double fixed_by_angle = fix_angles.front(); std::unordered_map vertex_mapping; // polys_copy is referenced through items stored in the std::vector segments. @@ -683,16 +696,15 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys) else if (status == VoronoiDiagramStatus::VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT) BOOST_LOG_TRIVIAL(warning) << "Detected Voronoi edge intersecting input segment, input polygons will be rotated back and forth."; - vertex_mapping = try_to_fix_degenerated_voronoi_diagram_by_rotation(voronoi_diagram, polys, polys_copy, segments, fix_angle); + std::tie(vertex_mapping, fixed_by_angle) = try_to_fix_degenerated_voronoi_diagram_by_rotation(voronoi_diagram, polys, polys_copy, segments, fix_angles); - assert(!detect_missing_voronoi_vertex(voronoi_diagram, segments)); - assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(voronoi_diagram, segments)); - assert(!detect_voronoi_edge_intersecting_input_segment(voronoi_diagram, segments)); - if (detect_missing_voronoi_vertex(voronoi_diagram, segments)) + VoronoiDiagramStatus status_after_fix = detect_voronoi_diagram_known_issues(voronoi_diagram, segments); + assert(status_after_fix == VoronoiDiagramStatus::NO_ISSUE_DETECTED); + if (status_after_fix == VoronoiDiagramStatus::MISSING_VORONOI_VERTEX) BOOST_LOG_TRIVIAL(error) << "Detected missing Voronoi vertex even after the rotation of input."; - else if (!Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(voronoi_diagram, segments)) + else if (status_after_fix == VoronoiDiagramStatus::NON_PLANAR_VORONOI_DIAGRAM) BOOST_LOG_TRIVIAL(error) << "Detected non-planar Voronoi diagram even after the rotation of input."; - else if (detect_voronoi_edge_intersecting_input_segment(voronoi_diagram, segments)) + else if (status_after_fix == VoronoiDiagramStatus::VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT) BOOST_LOG_TRIVIAL(error) << "Detected Voronoi edge intersecting input segment even after the rotation of input."; } @@ -759,8 +771,8 @@ process_voronoi_diagram: // diagram on slightly rotated input polygons that usually make the Voronoi generator generate a non-degenerated Voronoi diagram. if (status == VoronoiDiagramStatus::NO_ISSUE_DETECTED && has_missing_twin_edge(this->graph)) { BOOST_LOG_TRIVIAL(warning) << "Detected degenerated Voronoi diagram, input polygons will be rotated back and forth."; - status = VoronoiDiagramStatus::OTHER_TYPE_OF_VORONOI_DIAGRAM_DEGENERATION; - vertex_mapping = try_to_fix_degenerated_voronoi_diagram_by_rotation(voronoi_diagram, polys, polys_copy, segments, fix_angle); + status = VoronoiDiagramStatus::OTHER_TYPE_OF_VORONOI_DIAGRAM_DEGENERATION; + std::tie(vertex_mapping, fixed_by_angle) = try_to_fix_degenerated_voronoi_diagram_by_rotation(voronoi_diagram, polys, polys_copy, segments, fix_angles); assert(!detect_missing_voronoi_vertex(voronoi_diagram, segments)); if (detect_missing_voronoi_vertex(voronoi_diagram, segments)) @@ -784,7 +796,7 @@ process_voronoi_diagram: } if (status != VoronoiDiagramStatus::NO_ISSUE_DETECTED) - rotate_back_skeletal_trapezoidation_graph_after_fix(this->graph, fix_angle, vertex_mapping); + rotate_back_skeletal_trapezoidation_graph_after_fix(this->graph, fixed_by_angle, vertex_mapping); #ifdef ARACHNE_DEBUG assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(voronoi_diagram)); diff --git a/tests/libslic3r/test_arachne.cpp b/tests/libslic3r/test_arachne.cpp index c4564f77c5..61792c37f9 100644 --- a/tests/libslic3r/test_arachne.cpp +++ b/tests/libslic3r/test_arachne.cpp @@ -689,4 +689,58 @@ TEST_CASE("Arachne - #8846 - Degenerated Voronoi diagram - Voronoi edges interse // Total extrusion length should be around 500mm when the part is ok and 680mm when it has perimeters in places where they shouldn't be. REQUIRE(total_extrusion_length <= scaled(500.)); +} + +// This test case was distilled from GitHub issue #10034. +// In this test case previous rotation by PI / 6 wasn't able to fix non-planar Voronoi diagram. +TEST_CASE("Arachne - #10034 - Degenerated Voronoi diagram - That wasn't fixed by rotation by PI / 6", "[ArachneDegeneratedDiagram10034RotationNotWorks]") { + Polygon poly_0 = { + Point(43612632, -25179766), Point(58456010, 529710), Point(51074898, 17305660), Point(49390982, 21042355), + Point(48102357, 23840161), Point(46769686, 26629546), Point(45835761, 28472742), Point(45205450, 29623133), + Point(45107431, 29878059), Point(45069846, 30174950), Point(45069846, 50759533), Point(-45069846, 50759533), + Point(-45069852, 29630557), Point(-45105780, 29339980), Point(-45179725, 29130704), Point(-46443313, 26398986), + Point(-52272109, 13471493), Point(-58205450, 95724), Point(-29075091, -50359531), Point(29075086, -50359531), + }; + + Polygon poly_1 = { + Point(-37733905, 45070445), Point(-37813254, 45116257), Point(-39353851, 47784650), Point(-39353851, 47876274), + Point(-38632470, 49125743), Point(-38553121, 49171555), Point(-33833475, 49171555), Point(-33754126, 49125743), + Point(-33032747, 47876277), Point(-33032747, 47784653), Point(-34007855, 46095721), Point(-34573350, 45116257), + Point(-34652699, 45070445), + }; + + Polygon poly_2 = { + Point(-44016799, 40706401), Point(-44116953, 40806555), Point(-44116953, 46126289), Point(-44016799, 46226443), + Point(-42211438, 46226443), Point(-42132089, 46180631), Point(-40591492, 43512233), Point(-40591492, 43420609), + Point(-41800123, 41327194), Point(-42132089, 40752213), Point(-42211438, 40706401), + }; + + Polygon poly_3 = { + Point(6218189, 10966609), Point(6138840, 11012421), Point(4598238, 13680817), Point(4598238, 13772441), Point(6138840, 16440843), + Point(6218189, 16486655), Point(9299389, 16486655), Point(9378738, 16440843), Point(10919340, 13772441), Point(10919340, 13680817), + Point(10149039, 12346618), Point(9378738, 11012421), Point(9299389, 10966609), + }; + + Polygon poly_4 = { + Point(13576879, 6718065), Point(13497530, 6763877), Point(11956926, 9432278), Point(11956926, 9523902), + Point(13497528, 12192302), Point(13576877, 12238114), Point(16658079, 12238112), Point(16737428, 12192300), + Point(18278031, 9523904), Point(18278031, 9432280), Point(17507729, 8098077), Point(16737428, 6763877), + Point(16658079, 6718065), + }; + + Polygons polygons = { + poly_0, poly_1, poly_2, poly_3, poly_4, + }; + + coord_t ext_perimeter_spacing = 407079; + coord_t perimeter_spacing = 407079; + coord_t inset_count = 1; + + Arachne::WallToolPaths wall_tool_paths(polygons, ext_perimeter_spacing, perimeter_spacing, inset_count, 0, 0.2, PrintObjectConfig::defaults(), PrintConfig::defaults()); + wall_tool_paths.generate(); + std::vector perimeters = wall_tool_paths.getToolPaths(); + +#ifdef ARACHNE_DEBUG_OUT + export_perimeters_to_svg(debug_out_path("arachne-degenerated-diagram-10034-rotation-not-works.svg"), polygons, perimeters, union_ex(wall_tool_paths.getInnerContour())); +#endif } \ No newline at end of file From ab1813bdc84753b88f671653215c498c5c7e0c40 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 29 Mar 2023 15:32:33 +0200 Subject: [PATCH 27/32] PlaceholderParser: fixed access to "position" variable Follow-up to 59552a8aee893316a74b9a6e012d164ff7643b44 --- src/libslic3r/GCode.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 22c26b3a55..ab68291110 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -467,6 +467,7 @@ void GCode::PlaceholderParserIntegration::init(const GCodeWriter &writer) // Reserve buffer for current position. this->position.assign(3, 0); this->opt_position = new ConfigOptionFloats(this->position); + this->output_config.set_key_value("position", this->opt_position); // Store zhop variable into the parser itself, it is a read-only variable to the script. this->opt_zhop = new ConfigOptionFloat(writer.get_zhop()); this->parser.set("zhop", this->opt_zhop); From cbd25227c45d489e86121ef75f11d2062685e155 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 29 Mar 2023 16:10:00 +0200 Subject: [PATCH 28/32] More meaningful error message if slicing fails in SLA --- src/libslic3r/SLAPrintSteps.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index b73a8c4fb1..3565f193a0 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -511,8 +511,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) if(slindex_it == po.m_slice_index.end()) //TRN To be shown at the status bar on SLA slicing error. throw Slic3r::RuntimeError( - _u8L("Slicing had to be stopped due to an internal error: " - "Inconsistent slice index.")); + format(_u8L("Model named: %s can not be sliced. Please check if the model is sane."), po.model_object()->name)); po.m_model_height_levels.clear(); po.m_model_height_levels.reserve(po.m_slice_index.size()); From 7a5639f322e2aa03e5d7cb461cebc71e6325dcb0 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Wed, 29 Mar 2023 17:53:23 +0200 Subject: [PATCH 29/32] Fixed crash if toolchange G-code modifies final position, because the extruder was not set yet. --- src/libslic3r/GCode.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ab68291110..4156fe4ee3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3385,10 +3385,12 @@ Vec2d GCode::point_to_gcode_quantized(const Point &point) const // convert a model-space scaled point into G-code coordinates Point GCode::gcode_to_point(const Vec2d &point) const { - Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset); - return Point( - scale_(point(0) - m_origin(0) + extruder_offset(0)), - scale_(point(1) - m_origin(1) + extruder_offset(1))); + Vec2d pt = point - m_origin; + if (const Extruder *extruder = m_writer.extruder(); extruder) + // This function may be called at the very start from toolchange G-code when the extruder is not assigned yet. + pt += m_config.extruder_offset.get_at(extruder->id()); + return scaled(pt); + } } // namespace Slic3r From 89b9f702d6cd59bc64c93687bc086f17a206cd0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Wed, 29 Mar 2023 21:21:22 +0200 Subject: [PATCH 30/32] Fixed asserts and calculations in calculateExtrusionAreaDeviationError. The previous method worked just for near collinear edges. But it was also used for sharp corners, and for those sharp corners, there was an overflow in the computation of weighted width. Also, the computation of deviation error was wrong for those sharp corners. --- src/libslic3r/Arachne/utils/ExtrusionLine.cpp | 34 +++++++------------ src/libslic3r/Arachne/utils/ExtrusionLine.hpp | 3 +- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/libslic3r/Arachne/utils/ExtrusionLine.cpp b/src/libslic3r/Arachne/utils/ExtrusionLine.cpp index de5251639b..8631d9e17b 100644 --- a/src/libslic3r/Arachne/utils/ExtrusionLine.cpp +++ b/src/libslic3r/Arachne/utils/ExtrusionLine.cpp @@ -113,8 +113,7 @@ void ExtrusionLine::simplify(const int64_t smallest_line_segment_squared, const //h^2 = (L / b)^2 [square it] //h^2 = L^2 / b^2 [factor the divisor] const auto height_2 = int64_t(double(area_removed_so_far) * double(area_removed_so_far) / double(base_length_2)); - coord_t weighted_average_width; - const int64_t extrusion_area_error = calculateExtrusionAreaDeviationError(previous, current, next, weighted_average_width); + const int64_t extrusion_area_error = calculateExtrusionAreaDeviationError(previous, current, next); if ((height_2 <= scaled(0.001) //Almost exactly colinear (barring rounding errors). && Line::distance_to_infinite(current.p, previous.p, next.p) <= scaled(0.001)) // Make sure that height_2 is not small because of cancellation of positive and negative areas // We shouldn't remove middle junctions of colinear segments if the area changed for the C-P segment is exceeding the maximum allowed @@ -189,8 +188,7 @@ void ExtrusionLine::simplify(const int64_t smallest_line_segment_squared, const junctions = new_junctions; } -int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C, coord_t& weighted_average_width) -{ +int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C) { /* * A B C A C * --------------- ************** @@ -208,27 +206,19 @@ int64_t ExtrusionLine::calculateExtrusionAreaDeviationError(ExtrusionJunction A, * weighted-average width for the entire extrusion line. * * */ - const int64_t ab_length = (B - A).cast().norm(); - const int64_t bc_length = (C - B).cast().norm(); - const coord_t width_diff = std::max(std::abs(B.w - A.w), std::abs(C.w - B.w)); - if (width_diff > 1) - { + const int64_t ab_length = (B.p - A.p).cast().norm(); + const int64_t bc_length = (C.p - B.p).cast().norm(); + if (const coord_t width_diff = std::max(std::abs(B.w - A.w), std::abs(C.w - B.w)); width_diff > 1) { // Adjust the width only if there is a difference, or else the rounding errors may produce the wrong // weighted average value. - const int64_t ab_weight = (A.w + B.w) / 2; - const int64_t bc_weight = (B.w + C.w) / 2; - assert(((ab_length * ab_weight + bc_length * bc_weight) / (C - A).cast().norm()) <= std::numeric_limits::max()); - weighted_average_width = (ab_length * ab_weight + bc_length * bc_weight) / (C - A).cast().norm(); - assert((int64_t(std::abs(ab_weight - weighted_average_width)) * ab_length + int64_t(std::abs(bc_weight - weighted_average_width)) * bc_length) <= double(std::numeric_limits::max())); - return std::abs(ab_weight - weighted_average_width) * ab_length + std::abs(bc_weight - weighted_average_width) * bc_length; - } - else - { + const int64_t ab_weight = (A.w + B.w) / 2; + const int64_t bc_weight = (B.w + C.w) / 2; + const int64_t weighted_average_width = (ab_length * ab_weight + bc_length * bc_weight) / (ab_length + bc_length); + const int64_t ac_length = (C.p - A.p).cast().norm(); + return std::abs((ab_weight * ab_length + bc_weight * bc_length) - (weighted_average_width * ac_length)); + } else { // If the width difference is very small, then select the width of the segment that is longer - weighted_average_width = ab_length > bc_length ? A.w : B.w; - assert((int64_t(width_diff) * int64_t(bc_length)) <= std::numeric_limits::max()); - assert((int64_t(width_diff) * int64_t(ab_length)) <= std::numeric_limits::max()); - return ab_length > bc_length ? width_diff * bc_length : width_diff * ab_length; + return ab_length > bc_length ? int64_t(width_diff) * bc_length : int64_t(width_diff) * ab_length; } } diff --git a/src/libslic3r/Arachne/utils/ExtrusionLine.hpp b/src/libslic3r/Arachne/utils/ExtrusionLine.hpp index c0c5e7db1b..d39e1e07b9 100644 --- a/src/libslic3r/Arachne/utils/ExtrusionLine.hpp +++ b/src/libslic3r/Arachne/utils/ExtrusionLine.hpp @@ -186,9 +186,8 @@ struct ExtrusionLine * \param A Start point of the 3-point-straight line * \param B Intermediate point of the 3-point-straight line * \param C End point of the 3-point-straight line - * \param weighted_average_width The weighted average of the widths of the two colinear extrusion segments * */ - static int64_t calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C, coord_t& weighted_average_width); + static int64_t calculateExtrusionAreaDeviationError(ExtrusionJunction A, ExtrusionJunction B, ExtrusionJunction C); bool is_contour() const; From 2b7cf2d877b58cb0a1ce42b968e63f89ff469337 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Thu, 30 Mar 2023 10:36:23 +0200 Subject: [PATCH 31/32] GCodeGenerator / custom G-codes: Added new read/only options providing the amount of total extruded material and per extruder extruded material up to the point the value is evaluated: "extruded_volume", "extruded_weight", "extruded_volume_total", "extruded_weight_total" --- src/libslic3r/GCode.cpp | 24 ++++++++++++++++++++++++ src/libslic3r/GCode.hpp | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 4156fe4ee3..bd4101dc9a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -438,6 +438,10 @@ void GCode::PlaceholderParserIntegration::reset() this->opt_e_position = nullptr; this->opt_e_retracted = nullptr; this->opt_e_restart_extra = nullptr; + this->opt_extruded_volume = nullptr; + this->opt_extruded_weight = nullptr; + this->opt_extruded_volume_total = nullptr; + this->opt_extruded_weight_total = nullptr; this->num_extruders = 0; this->position.clear(); this->e_position.clear(); @@ -463,6 +467,14 @@ void GCode::PlaceholderParserIntegration::init(const GCodeWriter &writer) this->output_config.set_key_value("e_position", opt_e_position); } } + this->opt_extruded_volume = new ConfigOptionFloats(this->num_extruders, 0.f); + this->opt_extruded_weight = new ConfigOptionFloats(this->num_extruders, 0.f); + this->opt_extruded_volume_total = new ConfigOptionFloat(0.f); + this->opt_extruded_weight_total = new ConfigOptionFloat(0.f); + this->parser.set("extruded_volume", this->opt_extruded_volume); + this->parser.set("extruded_weight", this->opt_extruded_weight); + this->parser.set("extruded_volume_total", this->opt_extruded_volume_total); + this->parser.set("extruded_weight_total", this->opt_extruded_weight_total); // Reserve buffer for current position. this->position.assign(3, 0); @@ -484,10 +496,22 @@ void GCode::PlaceholderParserIntegration::update_from_gcodewriter(const GCodeWri assert(! extruders.empty() && num_extruders == extruders.back().id() + 1); this->e_retracted.assign(num_extruders, 0); this->e_restart_extra.assign(num_extruders, 0); + this->opt_extruded_volume->values.assign(num_extruders, 0); + this->opt_extruded_weight->values.assign(num_extruders, 0); + double total_volume = 0.; + double total_weight = 0.; for (const Extruder &e : extruders) { this->e_retracted[e.id()] = e.retracted(); this->e_restart_extra[e.id()] = e.restart_extra(); + double v = e.extruded_volume(); + double w = v * e.filament_density() * 0.001; + this->opt_extruded_volume->values[e.id()] = v; + this->opt_extruded_weight->values[e.id()] = w; + total_volume += v; + total_weight += w; } + opt_extruded_volume_total->value = total_volume; + opt_extruded_weight_total->value = total_weight; opt_e_retracted->values = this->e_retracted; opt_e_restart_extra->values = this->e_restart_extra; if (! writer.config.use_relative_e_distances) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 98f49095dc..346ececba7 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -362,6 +362,10 @@ private: ConfigOptionFloats *opt_e_position { nullptr }; ConfigOptionFloats *opt_e_retracted { nullptr }; ConfigOptionFloats *opt_e_restart_extra { nullptr }; + ConfigOptionFloats *opt_extruded_volume { nullptr }; + ConfigOptionFloats *opt_extruded_weight { nullptr }; + ConfigOptionFloat *opt_extruded_volume_total { nullptr }; + ConfigOptionFloat *opt_extruded_weight_total { nullptr }; // Caches of the data passed to the script. size_t num_extruders; std::vector position; From e4c479aba44271632ca282b8c404411cdc9c13a7 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Thu, 30 Mar 2023 12:19:45 +0200 Subject: [PATCH 32/32] Added first layer print times to print statistics written at the end of a G-code export. ; estimated first layer printing time (normal mode) = xxx ; estimated first layer printing time (silent mode) = yyy --- src/libslic3r/GCode/GCodeProcessor.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index a2c8675050..9b371e405e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -3508,6 +3508,17 @@ void GCodeProcessor::post_process() ret += buf; } } + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + const TimeMachine& machine = m_time_processor.machines[i]; + PrintEstimatedStatistics::ETimeMode mode = static_cast(i); + if (mode == PrintEstimatedStatistics::ETimeMode::Normal || machine.enabled) { + char buf[128]; + sprintf(buf, "; estimated first layer printing time (%s mode) = %s\n", + (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent", + get_time_dhms(machine.layers_time.empty() ? 0.f : machine.layers_time.front()).c_str()); + ret += buf; + } + } } }