Merge remote-tracking branch 'remotes/origin/master' into dev

This commit is contained in:
bubnikv 2019-09-09 17:49:07 +02:00
commit 6ba43ebacb
12 changed files with 9391 additions and 8480 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -151,7 +151,7 @@ bool stl_write_binary(stl_file *stl, const char *file, const char *label)
memcpy(buffer, &stl->stats.number_of_facets, 4); memcpy(buffer, &stl->stats.number_of_facets, 4);
stl_internal_reverse_quads(buffer, 4); stl_internal_reverse_quads(buffer, 4);
fwrite(buffer, 4, 1, fp); fwrite(buffer, 4, 1, fp);
for (i = 0; i < stl->stats.number_of_facets; ++ i) { for (size_t i = 0; i < stl->stats.number_of_facets; ++ i) {
memcpy(buffer, stl->facet_start + i, 50); memcpy(buffer, stl->facet_start + i, 50);
// Convert to little endian. // Convert to little endian.
stl_internal_reverse_quads(buffer, 48); stl_internal_reverse_quads(buffer, 48);

View file

@ -159,8 +159,11 @@ static bool obj_parseline(const char *line, ObjData &data)
line = endptr; line = endptr;
EATWS(); EATWS();
} }
if (*line != 0) // the following check is commented out because there may be obj files containing extra data, as those generated by Meshlab,
return false; // see https://dev.prusa3d.com/browse/SPE-1019 for an example,
// and this would lead to a crash because no vertex would be stored
// if (*line != 0)
// return false;
data.coordinates.push_back((float)x); data.coordinates.push_back((float)x);
data.coordinates.push_back((float)y); data.coordinates.push_back((float)y);
data.coordinates.push_back((float)z); data.coordinates.push_back((float)z);
@ -210,15 +213,15 @@ static bool obj_parseline(const char *line, ObjData &data)
} }
} }
if (vertex.coordIdx < 0) if (vertex.coordIdx < 0)
vertex.coordIdx += data.coordinates.size() / 4; vertex.coordIdx += (int)data.coordinates.size() / 4;
else else
-- vertex.coordIdx; -- vertex.coordIdx;
if (vertex.normalIdx < 0) if (vertex.normalIdx < 0)
vertex.normalIdx += data.normals.size() / 3; vertex.normalIdx += (int)data.normals.size() / 3;
else else
-- vertex.normalIdx; -- vertex.normalIdx;
if (vertex.textureCoordIdx < 0) if (vertex.textureCoordIdx < 0)
vertex.textureCoordIdx += data.textureCoordinates.size() / 3; vertex.textureCoordIdx += (int)data.textureCoordinates.size() / 3;
else else
-- vertex.textureCoordIdx; -- vertex.textureCoordIdx;
data.vertices.push_back(vertex); data.vertices.push_back(vertex);
@ -256,7 +259,7 @@ static bool obj_parseline(const char *line, ObjData &data)
// printf("usemtl %s\r\n", line); // printf("usemtl %s\r\n", line);
EATWS(); EATWS();
ObjUseMtl usemtl; ObjUseMtl usemtl;
usemtl.vertexIdxFirst = data.vertices.size(); usemtl.vertexIdxFirst = (int)data.vertices.size();
usemtl.name = line; usemtl.name = line;
data.usemtls.push_back(usemtl); data.usemtls.push_back(usemtl);
break; break;
@ -272,7 +275,7 @@ static bool obj_parseline(const char *line, ObjData &data)
if (*line != 0) if (*line != 0)
return false; return false;
ObjObject object; ObjObject object;
object.vertexIdxFirst = data.vertices.size(); object.vertexIdxFirst = (int)data.vertices.size();
object.name = line; object.name = line;
data.objects.push_back(object); data.objects.push_back(object);
break; break;
@ -282,7 +285,7 @@ static bool obj_parseline(const char *line, ObjData &data)
// g [group name] // g [group name]
// printf("group %s\r\n", line); // printf("group %s\r\n", line);
ObjGroup group; ObjGroup group;
group.vertexIdxFirst = data.vertices.size(); group.vertexIdxFirst = (int)data.vertices.size();
group.name = line; group.name = line;
data.groups.push_back(group); data.groups.push_back(group);
break; break;
@ -303,7 +306,7 @@ static bool obj_parseline(const char *line, ObjData &data)
if (*line != 0) if (*line != 0)
return false; return false;
ObjSmoothingGroup group; ObjSmoothingGroup group;
group.vertexIdxFirst = data.vertices.size(); group.vertexIdxFirst = (int)data.vertices.size();
group.smoothingGroupID = g; group.smoothingGroupID = g;
data.smoothingGroups.push_back(group); data.smoothingGroups.push_back(group);
break; break;
@ -341,7 +344,8 @@ bool objparse(const char *path, ObjData &data)
lenPrev = len - lastLine; lenPrev = len - lastLine;
memmove(buf, buf + lastLine, lenPrev); memmove(buf, buf + lastLine, lenPrev);
} }
} catch (std::bad_alloc &ex) { }
catch (std::bad_alloc&) {
printf("Out of memory\r\n"); printf("Out of memory\r\n");
} }
::fclose(pFile); ::fclose(pFile);

View file

@ -51,6 +51,34 @@ static inline void check_add_eol(std::string &gcode)
gcode += '\n'; 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) void AvoidCrossingPerimeters::init_external_mp(const Print &print)
{ {
m_external_mp = Slic3r::make_unique<MotionPlanner>(union_ex(this->collect_contours_all_layers(print.objects()))); 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; std::string toolchange_command;
if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))) if (tcr.priming || (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)))
toolchange_command = gcodegen.writer().toolchange(new_extruder_id); toolchange_command = gcodegen.writer().toolchange(new_extruder_id);
if (toolchange_gcode.empty()) if (! custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_extruder_id))
toolchange_gcode_str = toolchange_command; toolchange_gcode_str += toolchange_command;
else { else {
// We have informed the m_writer about the current extruder_id, we can ignore the generated G-code. // We have informed the m_writer about the current extruder_id, we can ignore the generated G-code.
} }
@ -2688,11 +2716,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
// PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width // PrusaMultiMaterial::Writer may generate GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines without updating m_last_height and m_last_width
// so, if the last role was erWipeTower we force export of GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines // so, if the last role was erWipeTower we force export of GCodeAnalyzer::Height_Tag and GCodeAnalyzer::Width_Tag lines
bool last_was_wipe_tower = (m_last_analyzer_extrusion_role == erWipeTower); bool last_was_wipe_tower = (m_last_analyzer_extrusion_role == erWipeTower);
char buf[64];
if (path.role() != m_last_analyzer_extrusion_role) if (path.role() != m_last_analyzer_extrusion_role)
{ {
m_last_analyzer_extrusion_role = path.role(); m_last_analyzer_extrusion_role = path.role();
char buf[32];
sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role)); sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role));
gcode += buf; gcode += buf;
} }
@ -2700,8 +2728,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm)) if (last_was_wipe_tower || (m_last_mm3_per_mm != path.mm3_per_mm))
{ {
m_last_mm3_per_mm = path.mm3_per_mm; m_last_mm3_per_mm = path.mm3_per_mm;
char buf[32];
sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm); sprintf(buf, ";%s%f\n", GCodeAnalyzer::Mm3_Per_Mm_Tag.c_str(), m_last_mm3_per_mm);
gcode += buf; gcode += buf;
} }
@ -2709,8 +2735,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (last_was_wipe_tower || (m_last_width != path.width)) if (last_was_wipe_tower || (m_last_width != path.width))
{ {
m_last_width = path.width; m_last_width = path.width;
char buf[32];
sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width); sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), m_last_width);
gcode += buf; gcode += buf;
} }
@ -2718,8 +2742,6 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (last_was_wipe_tower || (m_last_height != path.height)) if (last_was_wipe_tower || (m_last_height != path.height))
{ {
m_last_height = path.height; m_last_height = path.height;
char buf[32];
sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height); sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_last_height);
gcode += buf; gcode += buf;
} }
@ -2902,6 +2924,7 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
gcode += m_ooze_prevention.pre_toolchange(*this); gcode += m_ooze_prevention.pre_toolchange(*this);
const std::string& toolchange_gcode = m_config.toolchange_gcode.value; 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. // Process the custom toolchange_gcode. If it is empty, insert just a Tn command.
if (!toolchange_gcode.empty()) { if (!toolchange_gcode.empty()) {
@ -2910,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("next_extruder", new ConfigOptionInt((int)extruder_id));
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); 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); check_add_eol(gcode);
} }
// We inform the writer about what is happening, but we may not use the resulting 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); 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; gcode += toolchange_command;
else { else {
// user provided his own toolchange gcode, no need to do anything // user provided his own toolchange gcode, no need to do anything

View file

@ -2054,10 +2054,10 @@ void PrintConfigDef::init_fff_params()
def = this->add("toolchange_gcode", coString); def = this->add("toolchange_gcode", coString);
def->label = L("Tool change G-code"); 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 " def->tooltip = L("This custom code is inserted before every toolchange. Placeholder variables for all PrusaSlicer settings "
"expected to take care of the toolchange yourself - PrusaSlicer will not output any other G-code to " "as well as {previous_extruder} and {next_extruder} can be used. When a tool-changing command "
"change the filament. You can use placeholder variables for all Slic3r settings as well as [previous_extruder] " "which changes to the correct extruder is included (such as T{next_extruder}), PrusaSlicer will emit no other such command. "
"and [next_extruder], so e.g. the standard toolchange command can be scripted as T[next_extruder]."); "It is therefore possible to script custom behaviour both before and after the toolchange.");
def->multiline = true; def->multiline = true;
def->full_width = true; def->full_width = true;
def->height = 5; def->height = 5;

View file

@ -893,7 +893,6 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
this->p->fit_no_shrink(); 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_rescan->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { this->p->find_serial_ports(); });
p->btn_flash->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { p->btn_flash->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {

View file

@ -561,9 +561,9 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown()); gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown(), evt.AltDown(), evt.ControlDown());
processed = true; 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; processed = true;
} }
} }

View file

@ -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); 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; return obj_idxs;