Merge branch 'dev' of https://github.com/prusa3d/PrusaSlicer into et_reload_from_disk
This commit is contained in:
commit
0387401d8e
File diff suppressed because it is too large
Load Diff
@ -198,8 +198,9 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
||||
{
|
||||
Polygons all_polygons;
|
||||
for (SurfaceFill &fill : surface_fills)
|
||||
if (! fill.expolygons.empty() && (fill.expolygons.size() > 1 || ! all_polygons.empty())) {
|
||||
if (! fill.expolygons.empty()) {
|
||||
Polygons polys = to_polygons(std::move(fill.expolygons));
|
||||
if (fill.expolygons.size() > 1 || ! all_polygons.empty())
|
||||
// Make a union of polygons, use a safety offset, subtract the preceding polygons.
|
||||
// Bridges are processed first (see SurfaceFill::operator<())
|
||||
fill.expolygons = all_polygons.empty() ? union_ex(polys, true) : diff_ex(polys, all_polygons, true);
|
||||
@ -309,7 +310,6 @@ void Layer::make_fills()
|
||||
f->layer_id = this->id();
|
||||
f->z = this->print_z;
|
||||
f->angle = surface_fill.params.angle;
|
||||
f->spacing = surface_fill.params.spacing;
|
||||
|
||||
// calculate flow spacing for infill pattern generation
|
||||
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.flow.bridge;
|
||||
@ -335,6 +335,8 @@ void Layer::make_fills()
|
||||
params.dont_adjust = surface_fill.params.dont_adjust; // false
|
||||
|
||||
for (ExPolygon &expoly : surface_fill.expolygons) {
|
||||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||
f->spacing = surface_fill.params.spacing;
|
||||
surface_fill.surface.expolygon = std::move(expoly);
|
||||
Polylines polylines = f->fill_surface(&surface_fill.surface, params);
|
||||
if (! polylines.empty()) {
|
||||
|
@ -51,6 +51,34 @@ static inline void check_add_eol(std::string &gcode)
|
||||
gcode += '\n';
|
||||
}
|
||||
|
||||
|
||||
// Return true if tch_prefix is found in custom_gcode
|
||||
static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std::string& tch_prefix, unsigned next_extruder)
|
||||
{
|
||||
bool ok = false;
|
||||
size_t from_pos = 0;
|
||||
size_t pos = 0;
|
||||
while ((pos = custom_gcode.find(tch_prefix, from_pos)) != std::string::npos) {
|
||||
if (pos+1 == custom_gcode.size())
|
||||
break;
|
||||
from_pos = pos+1;
|
||||
// only whitespace is allowed before the command
|
||||
while (--pos < custom_gcode.size() && custom_gcode[pos] != '\n') {
|
||||
if (! std::isspace(custom_gcode[pos]))
|
||||
goto NEXT;
|
||||
}
|
||||
{
|
||||
// we should also check that the extruder changes to what was expected
|
||||
std::istringstream ss(custom_gcode.substr(from_pos, std::string::npos));
|
||||
unsigned num = 0;
|
||||
if (ss >> num)
|
||||
ok = (num == next_extruder);
|
||||
}
|
||||
NEXT: ;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void AvoidCrossingPerimeters::init_external_mp(const Print &print)
|
||||
{
|
||||
m_external_mp = Slic3r::make_unique<MotionPlanner>(union_ex(this->collect_contours_all_layers(print.objects())));
|
||||
@ -314,8 +342,8 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
||||
std::string toolchange_command;
|
||||
if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)))
|
||||
toolchange_command = gcodegen.writer().toolchange(new_extruder_id);
|
||||
if (toolchange_gcode.empty())
|
||||
toolchange_gcode_str = toolchange_command;
|
||||
if (! custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_extruder_id))
|
||||
toolchange_gcode_str += toolchange_command;
|
||||
else {
|
||||
// We have informed the m_writer about the current extruder_id, we can ignore the generated G-code.
|
||||
}
|
||||
@ -2896,6 +2924,7 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
|
||||
gcode += m_ooze_prevention.pre_toolchange(*this);
|
||||
|
||||
const std::string& toolchange_gcode = m_config.toolchange_gcode.value;
|
||||
std::string toolchange_gcode_parsed;
|
||||
|
||||
// Process the custom toolchange_gcode. If it is empty, insert just a Tn command.
|
||||
if (!toolchange_gcode.empty()) {
|
||||
@ -2904,13 +2933,14 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
|
||||
config.set_key_value("next_extruder", new ConfigOptionInt((int)extruder_id));
|
||||
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
|
||||
config.set_key_value("layer_z", new ConfigOptionFloat(print_z));
|
||||
gcode += placeholder_parser_process("toolchange_gcode", toolchange_gcode, extruder_id, &config);
|
||||
toolchange_gcode_parsed = placeholder_parser_process("toolchange_gcode", toolchange_gcode, extruder_id, &config);
|
||||
gcode += toolchange_gcode_parsed;
|
||||
check_add_eol(gcode);
|
||||
}
|
||||
|
||||
// We inform the writer about what is happening, but we may not use the resulting gcode.
|
||||
std::string toolchange_command = m_writer.toolchange(extruder_id);
|
||||
if (toolchange_gcode.empty())
|
||||
if (! custom_gcode_changes_tool(toolchange_gcode_parsed, m_writer.toolchange_prefix(), extruder_id))
|
||||
gcode += toolchange_command;
|
||||
else {
|
||||
// user provided his own toolchange gcode, no need to do anything
|
||||
|
@ -2054,10 +2054,10 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("toolchange_gcode", coString);
|
||||
def->label = L("Tool change G-code");
|
||||
def->tooltip = L("This custom code is inserted at every extruder change. If you don't leave this empty, you are "
|
||||
"expected to take care of the toolchange yourself - PrusaSlicer will not output any other G-code to "
|
||||
"change the filament. You can use placeholder variables for all Slic3r settings as well as [previous_extruder] "
|
||||
"and [next_extruder], so e.g. the standard toolchange command can be scripted as T[next_extruder].");
|
||||
def->tooltip = L("This custom code is inserted before every toolchange. Placeholder variables for all PrusaSlicer settings "
|
||||
"as well as {previous_extruder} and {next_extruder} can be used. When a tool-changing command "
|
||||
"which changes to the correct extruder is included (such as T{next_extruder}), PrusaSlicer will emit no other such command. "
|
||||
"It is therefore possible to script custom behaviour both before and after the toolchange.");
|
||||
def->multiline = true;
|
||||
def->full_width = true;
|
||||
def->height = 5;
|
||||
|
@ -258,8 +258,8 @@ void PrintObject::prepare_infill()
|
||||
m_print->throw_if_canceled();
|
||||
|
||||
// Decide what surfaces are to be filled.
|
||||
// Here the S_TYPE_TOP / S_TYPE_BOTTOMBRIDGE / S_TYPE_BOTTOM infill is turned to just S_TYPE_INTERNAL if zero top / bottom infill layers are configured.
|
||||
// Also tiny S_TYPE_INTERNAL surfaces are turned to S_TYPE_INTERNAL_SOLID.
|
||||
// Here the stTop / stBottomBridge / stBottom infill is turned to just stInternal if zero top / bottom infill layers are configured.
|
||||
// Also tiny stInternal surfaces are turned to stInternalSolid.
|
||||
BOOST_LOG_TRIVIAL(info) << "Preparing fill surfaces..." << log_memory_info();
|
||||
for (auto *layer : m_layers)
|
||||
for (auto *region : layer->m_regions) {
|
||||
@ -271,8 +271,8 @@ void PrintObject::prepare_infill()
|
||||
// and rearrange top/bottom/internal surfaces
|
||||
// It produces enlarged overlapping bridging areas.
|
||||
//
|
||||
// 1) S_TYPE_BOTTOMBRIDGE / S_TYPE_BOTTOM infill is grown by 3mm and clipped by the total infill area. Bridges are detected. The areas may overlap.
|
||||
// 2) S_TYPE_TOP is grown by 3mm and clipped by the grown bottom areas. The areas may overlap.
|
||||
// 1) stBottomBridge / stBottom infill is grown by 3mm and clipped by the total infill area. Bridges are detected. The areas may overlap.
|
||||
// 2) stTop is grown by 3mm and clipped by the grown bottom areas. The areas may overlap.
|
||||
// 3) Clip the internal surfaces by the grown top/bottom surfaces.
|
||||
// 4) Merge surfaces with the same style. This will mostly get rid of the overlaps.
|
||||
//FIXME This does not likely merge surfaces, which are supported by a material with different colors, but same properties.
|
||||
@ -468,9 +468,17 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
|| opt_key == "support_material_contact_distance"
|
||||
|| opt_key == "xy_size_compensation") {
|
||||
steps.emplace_back(posSlice);
|
||||
} else if (opt_key == "support_material") {
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
if (m_config.support_material_contact_distance == 0.) {
|
||||
// Enabling / disabling supports while soluble support interface is enabled.
|
||||
// This changes the bridging logic (bridging enabled without supports, disabled with supports).
|
||||
// Reset everything.
|
||||
// See GH #1482 for details.
|
||||
steps.emplace_back(posSlice);
|
||||
}
|
||||
} else if (
|
||||
opt_key == "support_material"
|
||||
|| opt_key == "support_material_auto"
|
||||
opt_key == "support_material_auto"
|
||||
|| opt_key == "support_material_angle"
|
||||
|| opt_key == "support_material_buildplate_only"
|
||||
|| opt_key == "support_material_enforce_layers"
|
||||
@ -524,8 +532,13 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
steps.emplace_back(posPerimeters);
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
} else if (opt_key == "bridge_flow_ratio") {
|
||||
if (m_config.support_material_contact_distance > 0.) {
|
||||
// Only invalidate due to bridging if bridging is enabled.
|
||||
// If later "support_material_contact_distance" is modified, the complete PrintObject is invalidated anyway.
|
||||
steps.emplace_back(posPerimeters);
|
||||
steps.emplace_back(posInfill);
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
}
|
||||
} else if (
|
||||
opt_key == "seam_position"
|
||||
|| opt_key == "seam_preferred_direction"
|
||||
@ -1372,7 +1385,7 @@ void PrintObject::bridge_over_infill()
|
||||
)};
|
||||
push @new_surfaces, map Slic3r::Surface->new(
|
||||
expolygon => $_,
|
||||
surface_type => S_TYPE_INTERNALVOID,
|
||||
surface_type => stInternalVoid,
|
||||
), @{intersection_ex(
|
||||
[ map $_->p, @$group ],
|
||||
[ map @$_, @$to_bridge ],
|
||||
@ -2293,8 +2306,7 @@ void PrintObject::clip_fill_surfaces()
|
||||
// Detect things that we need to support.
|
||||
// Cummulative slices.
|
||||
Polygons slices;
|
||||
for (const ExPolygon &expoly : layer->slices.expolygons)
|
||||
polygons_append(slices, to_polygons(expoly));
|
||||
polygons_append(slices, layer->slices.expolygons);
|
||||
// Cummulative fill surfaces.
|
||||
Polygons fill_surfaces;
|
||||
// Solid surfaces to be supported.
|
||||
@ -2403,7 +2415,7 @@ void PrintObject::discover_horizontal_shells()
|
||||
polygons_append(solid, to_polygons(surface.expolygon));
|
||||
if (solid.empty())
|
||||
continue;
|
||||
// Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == S_TYPE_TOP) ? 'top' : 'bottom';
|
||||
// Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == stTop) ? 'top' : 'bottom';
|
||||
|
||||
size_t solid_layers = (type == stTop) ? region_config.top_solid_layers.value : region_config.bottom_solid_layers.value;
|
||||
for (int n = (type == stTop) ? i-1 : i+1; std::abs(n - (int)i) < solid_layers; (type == stTop) ? -- n : ++ n) {
|
||||
@ -2422,7 +2434,7 @@ void PrintObject::discover_horizontal_shells()
|
||||
// shells to be generated in the base but not in the walls (where there are many
|
||||
// narrow bottom surfaces): reassigning $solid will consider the 'shadow' of the
|
||||
// upper perimeter as an obstacle and shell will not be propagated to more upper layers
|
||||
//FIXME How does it work for S_TYPE_INTERNALBRIDGE? This is set for sparse infill. Likely this does not work.
|
||||
//FIXME How does it work for stInternalBRIDGE? This is set for sparse infill. Likely this does not work.
|
||||
Polygons new_internal_solid;
|
||||
{
|
||||
Polygons internal;
|
||||
@ -2615,7 +2627,7 @@ void PrintObject::combine_infill()
|
||||
continue;
|
||||
// Slic3r::debugf " combining %d %s regions from layers %d-%d\n",
|
||||
// scalar(@$intersection),
|
||||
// ($type == S_TYPE_INTERNAL ? 'internal' : 'internal-solid'),
|
||||
// ($type == stInternal ? 'internal' : 'internal-solid'),
|
||||
// $layer_idx-($every-1), $layer_idx;
|
||||
// intersection now contains the regions that can be combined across the full amount of layers,
|
||||
// so let's remove those areas from all layers.
|
||||
|
@ -893,7 +893,6 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
|
||||
this->p->fit_no_shrink();
|
||||
});
|
||||
|
||||
p->btn_close->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { this->Close(); });
|
||||
p->btn_rescan->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { this->p->find_serial_ports(); });
|
||||
|
||||
p->btn_flash->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
||||
|
@ -561,9 +561,9 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
|
||||
processed = true;
|
||||
}
|
||||
else if (evt.LeftUp() && (m_current == Flatten) && ((m_parent.get_first_hover_volume_idx() != -1) || grabber_contains_mouse()))
|
||||
else if (evt.LeftUp() && (m_current == Flatten) && (m_gizmos[m_current]->get_hover_id() != -1))
|
||||
{
|
||||
// to avoid to loose the selection when user clicks an object while the Flatten gizmo is active
|
||||
// to avoid to loose the selection when user clicks an the white faces of a different object while the Flatten gizmo is active
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
|
@ -2369,6 +2369,10 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
{
|
||||
selection.add_object((unsigned int)idx, false);
|
||||
}
|
||||
|
||||
if (view3D->get_canvas3d()->get_gizmos_manager().is_running())
|
||||
// this is required because the selected object changed and the flatten on face an sla support gizmos need to be updated accordingly
|
||||
view3D->get_canvas3d()->update_gizmos_on_off_state();
|
||||
}
|
||||
|
||||
return obj_idxs;
|
||||
|
Loading…
Reference in New Issue
Block a user