Merge branch 'master' of https://github.com/prusa3d/Slic3r into objects_centering

This commit is contained in:
Enrico Turri 2019-01-23 15:56:46 +01:00
commit c2c7a3ad8f
13 changed files with 105 additions and 72 deletions

Binary file not shown.

View file

@ -1125,7 +1125,7 @@ std::string Print::validate() const
// Check horizontal clearance.
{
Polygons convex_hulls_other;
for (PrintObject *object : m_objects) {
for (const PrintObject *object : m_objects) {
// Get convex hull of all meshes assigned to this print object.
Polygon convex_hull;
{
@ -1186,15 +1186,24 @@ std::string Print::validate() const
return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter and Repetier G-code flavors.");
if (! m_config.use_relative_e_distances)
return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
if (m_objects.size() > 1) {
bool has_custom_layering = false;
std::vector<std::vector<coordf_t>> layer_height_profiles;
for (const PrintObject *object : m_objects) {
has_custom_layering = ! object->model_object()->layer_height_ranges.empty() || ! object->model_object()->layer_height_profile.empty();
if (has_custom_layering) {
layer_height_profiles.assign(m_objects.size(), std::vector<coordf_t>());
break;
}
}
SlicingParameters slicing_params0 = m_objects.front()->slicing_parameters();
const PrintObject* tallest_object = m_objects.front(); // let's find the tallest object
for (const auto* object : m_objects)
if (*(object->layer_height_profile.end()-2) > *(tallest_object->layer_height_profile.end()-2) )
tallest_object = object;
for (PrintObject *object : m_objects) {
SlicingParameters slicing_params = object->slicing_parameters();
size_t tallest_object_idx = 0;
if (has_custom_layering)
PrintObject::update_layer_height_profile(*m_objects.front()->model_object(), slicing_params0, layer_height_profiles.front());
for (size_t i = 1; i < m_objects.size(); ++ i) {
const PrintObject *object = m_objects[i];
const SlicingParameters slicing_params = object->slicing_parameters();
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths");
@ -1204,31 +1213,39 @@ std::string Print::validate() const
return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance");
if (! equal_layering(slicing_params, slicing_params0))
return L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
if (has_custom_layering) {
PrintObject::update_layer_height_profile(*object->model_object(), slicing_params, layer_height_profiles[i]);
if (*(layer_height_profiles[i].end()-2) > *(layer_height_profiles[tallest_object_idx].end()-2))
tallest_object_idx = i;
}
}
if (m_config.variable_layer_height) { // comparing layer height profiles
if (has_custom_layering) {
const std::vector<coordf_t> &layer_height_profile_tallest = layer_height_profiles[tallest_object_idx];
for (size_t idx_object = 0; idx_object < m_objects.size(); ++ idx_object) {
const PrintObject *object = m_objects[idx_object];
const std::vector<coordf_t> &layer_height_profile = layer_height_profiles[idx_object];
bool failed = false;
// layer_height_profile should be set by Print::apply().
if (tallest_object->layer_height_profile.size() >= object->layer_height_profile.size()) {
if (layer_height_profile_tallest.size() >= layer_height_profile.size()) {
int i = 0;
while (i < object->layer_height_profile.size() && i < tallest_object->layer_height_profile.size()) {
if (std::abs(tallest_object->layer_height_profile[i] - object->layer_height_profile[i])) {
while (i < layer_height_profile.size() && i < layer_height_profile_tallest.size()) {
if (std::abs(layer_height_profile_tallest[i] - layer_height_profile[i])) {
failed = true;
break;
}
++i;
if (i == object->layer_height_profile.size()-2) // this element contains this objects max z
if (tallest_object->layer_height_profile[i] > object->layer_height_profile[i]) // the difference does not matter in this case
++i;
++ i;
if (i == layer_height_profile.size() - 2) // this element contains this objects max z
if (layer_height_profile_tallest[i] > layer_height_profile[i]) // the difference does not matter in this case
++ i;
}
}
else
} else
failed = true;
if (failed)
return L("The Wipe tower is only supported if all objects have the same layer height profile");
}
}
}
}
{
// find the smallest nozzle diameter

View file

@ -83,10 +83,6 @@ public:
// vector of (vectors of volume ids), indexed by region_id
std::vector<std::vector<int>> region_volumes;
// Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers.
// The pairs of <z, layer_height> are packed into a 1D array.
std::vector<coordf_t> layer_height_profile;
// this is set to true when LayerRegion->slices is split in top/internal/bottom
// so that next call to make_perimeters() performs a union() before computing loops
bool typed_slices;
@ -175,7 +171,7 @@ private:
void infill();
void generate_support_material();
void _slice();
void _slice(const std::vector<coordf_t> &layer_height_profile);
std::string _fix_slicing_errors();
void _simplify_slices(double distance);
void _make_perimeters();

View file

@ -64,8 +64,6 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, bool add_insta
}
this->set_copies(copies);
}
this->layer_height_profile = model_object->layer_height_profile;
}
PrintBase::ApplyStatus PrintObject::set_copies(const Points &points)
@ -105,9 +103,10 @@ void PrintObject::slice()
if (! this->set_started(posSlice))
return;
m_print->set_status(10, "Processing triangulated mesh");
this->update_layer_height_profile(*this->model_object(), this->slicing_parameters(), this->layer_height_profile);
std::vector<coordf_t> layer_height_profile;
this->update_layer_height_profile(*this->model_object(), this->slicing_parameters(), layer_height_profile);
m_print->throw_if_canceled();
this->_slice();
this->_slice(layer_height_profile);
m_print->throw_if_canceled();
// Fix the model.
//FIXME is this the right place to do? It is done repeateadly at the UI and now here at the backend.
@ -1438,7 +1437,7 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c
// Resulting expolygons of layer regions are marked as Internal.
//
// this should be idempotent
void PrintObject::_slice()
void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
{
BOOST_LOG_TRIVIAL(info) << "Slicing objects..." << log_memory_info();
@ -1457,7 +1456,7 @@ void PrintObject::_slice()
{
this->clear_layers();
// Object layers (pairs of bottom/top Z coordinate), without the raft.
std::vector<coordf_t> object_layers = generate_object_layers(slicing_params, this->layer_height_profile);
std::vector<coordf_t> object_layers = generate_object_layers(slicing_params, layer_height_profile);
// Reserve object layers for the raft. Last layer of the raft is the contact layer.
int id = int(slicing_params.raft_layers());
slice_zs.reserve(object_layers.size());

View file

@ -738,45 +738,46 @@ public:
const TriangleMesh& merged_mesh() const {
if(meshcache_valid) return meshcache;
meshcache = TriangleMesh();
Contour3D merged;
for(auto& head : heads()) {
if(m_ctl.stopcondition()) break;
if(head.is_valid()) {
auto&& m = mesh(head.mesh);
meshcache.merge(m);
}
if(head.is_valid())
merged.merge(head.mesh);
}
for(auto& stick : pillars()) {
if(m_ctl.stopcondition()) break;
meshcache.merge(mesh(stick.mesh));
meshcache.merge(mesh(stick.base));
merged.merge(stick.mesh);
merged.merge(stick.base);
}
for(auto& j : junctions()) {
if(m_ctl.stopcondition()) break;
meshcache.merge(mesh(j.mesh));
merged.merge(j.mesh);
}
for(auto& cb : compact_bridges()) {
if(m_ctl.stopcondition()) break;
meshcache.merge(mesh(cb.mesh));
merged.merge(cb.mesh);
}
for(auto& bs : bridges()) {
if(m_ctl.stopcondition()) break;
meshcache.merge(mesh(bs.mesh));
merged.merge(bs.mesh);
}
if(m_ctl.stopcondition()) {
// In case of failure we have to return an empty mesh
meshcache = TriangleMesh();
return meshcache;
}
meshcache = mesh(merged);
// TODO: Is this necessary?
meshcache.repair();
//meshcache.repair();
BoundingBoxf3&& bb = meshcache.bounding_box();
model_height = bb.max(Z) - bb.min(Z);

View file

@ -35,7 +35,7 @@
// Improves navigation between sidebar fields
#define ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION (1 && ENABLE_1_42_0_ALPHA2)
// Adds print bed models to 3D scene
#define ENABLE_PRINT_BED_MODELS (0 && ENABLE_1_42_0_ALPHA2)
#define ENABLE_PRINT_BED_MODELS (1 && ENABLE_1_42_0_ALPHA2)
#endif // _technologies_h_

View file

@ -99,6 +99,8 @@ TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
return *this;
}
// #define SLIC3R_TRACE_REPAIR
void TriangleMesh::repair()
{
if (this->repaired) return;
@ -109,7 +111,9 @@ void TriangleMesh::repair()
BOOST_LOG_TRIVIAL(debug) << "TriangleMesh::repair() started";
// checking exact
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_check_faces_exact";
#endif /* SLIC3R_TRACE_REPAIR */
stl_check_facets_exact(&stl);
stl.stats.facets_w_1_bad_edge = (stl.stats.connected_facets_2_edge - stl.stats.connected_facets_3_edge);
stl.stats.facets_w_2_bad_edge = (stl.stats.connected_facets_1_edge - stl.stats.connected_facets_2_edge);
@ -124,7 +128,9 @@ void TriangleMesh::repair()
for (int i = 0; i < iterations; i++) {
if (stl.stats.connected_facets_3_edge < stl.stats.number_of_facets) {
//printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations);
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_check_faces_nearby";
#endif /* SLIC3R_TRACE_REPAIR */
stl_check_facets_nearby(&stl, tolerance);
//printf(" Fixed %d edges.\n", stl.stats.edges_fixed - last_edges_fixed);
//last_edges_fixed = stl.stats.edges_fixed;
@ -137,7 +143,9 @@ void TriangleMesh::repair()
// remove_unconnected
if (stl.stats.connected_facets_3_edge < stl.stats.number_of_facets) {
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_remove_unconnected_facets";
#endif /* SLIC3R_TRACE_REPAIR */
stl_remove_unconnected_facets(&stl);
}
@ -146,26 +154,36 @@ void TriangleMesh::repair()
// Don't fill holes, the current algorithm does more harm than good on complex holes.
// Rather let the slicing algorithm close gaps in 2D slices.
if (stl.stats.connected_facets_3_edge < stl.stats.number_of_facets) {
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_fill_holes";
#endif /* SLIC3R_TRACE_REPAIR */
stl_fill_holes(&stl);
stl_clear_error(&stl);
}
#endif
// normal_directions
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_fix_normal_directions";
#endif /* SLIC3R_TRACE_REPAIR */
stl_fix_normal_directions(&stl);
// normal_values
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_fix_normal_values";
#endif /* SLIC3R_TRACE_REPAIR */
stl_fix_normal_values(&stl);
// always calculate the volume and reverse all normals if volume is negative
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_calculate_volume";
#endif /* SLIC3R_TRACE_REPAIR */
stl_calculate_volume(&stl);
// neighbors
#ifdef SLIC3R_TRACE_REPAIR
BOOST_LOG_TRIVIAL(trace) << "\tstl_verify_neighbors";
#endif /* SLIC3R_TRACE_REPAIR */
stl_verify_neighbors(&stl);
this->repaired = true;

View file

@ -588,7 +588,7 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const
{
filename = model_path + "_bed.stl";
if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs))
m_model.center_around(m_bounding_box.center() - Vec3d(0.0, 0.0, 1.0 + 0.5 * m_model.get_bounding_box().size()(2)));
m_model.center_around(m_bounding_box.center() - Vec3d(0.0, 0.0, 0.1 + 0.5 * m_model.get_bounding_box().size()(2)));
if (!m_model.get_filename().empty())
{
@ -1197,11 +1197,12 @@ void GLCanvas3D::LayersEditing::adjust_layer_height_profile()
m_layers_texture.valid = false;
}
void GLCanvas3D::LayersEditing::reset_layer_height_profile()
void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas)
{
const_cast<ModelObject*>(m_model_object)->layer_height_profile.clear();
m_layer_height_profile.clear();
m_layers_texture.valid = false;
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}
void GLCanvas3D::LayersEditing::generate_layer_height_texture()
@ -5061,7 +5062,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.LeftDown())
{
// A volume is selected and the mouse is inside the reset button. Reset the ModelObject's layer height profile.
m_layers_editing.reset_layer_height_profile();
m_layers_editing.reset_layer_height_profile(*this);
// Index 2 means no editing, just wait for mouse up event.
m_layers_editing.state = LayersEditing::Completed;

View file

@ -360,7 +360,7 @@ class GLCanvas3D
void adjust_layer_height_profile();
void accept_changes(GLCanvas3D& canvas);
void reset_layer_height_profile();
void reset_layer_height_profile(GLCanvas3D& canvas);
static float get_cursor_z_relative(const GLCanvas3D& canvas);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);

View file

@ -1574,15 +1574,17 @@ void GLGizmoFlatten::update_planes()
m_planes.pop_back();
}
// Let's prepare transformation of the normal vector from mesh to instance coordinates.
Geometry::Transformation t(inst_matrix);
Vec3d scaling = t.get_scaling_factor();
t.set_scaling_factor(Vec3d(1./scaling(0), 1./scaling(1), 1./scaling(2)));
// Now we'll go through all the polygons, transform the points into xy plane to process them:
for (unsigned int polygon_id=0; polygon_id < m_planes.size(); ++polygon_id) {
Pointf3s& polygon = m_planes[polygon_id].vertices;
const Vec3d& normal = m_planes[polygon_id].normal;
// let's transform the normal accodring to the instance matrix:
Geometry::Transformation t(inst_matrix);
Vec3d scaling = t.get_scaling_factor();
t.set_scaling_factor(Vec3d(1./(scaling(0)*scaling(0)), 1./(scaling(0)*scaling(0)), 1./(scaling(0)*scaling(0))));
// transform the normal according to the instance matrix:
Vec3d normal_transformed = t.get_matrix() * normal;
// We are going to rotate about z and y to flatten the plane

View file

@ -194,6 +194,8 @@ bool GUI_App::OnInit()
preset_updater->slic3r_update_notify();
}
preset_updater->sync(preset_bundle);
load_current_presets();
});

View file

@ -155,7 +155,6 @@ void MainFrame::create_preset_tabs()
add_created_tab(new TabSLAPrint(m_tabpanel));
add_created_tab(new TabSLAMaterial(m_tabpanel));
add_created_tab(new TabPrinter(m_tabpanel));
GUI::wxGetApp().load_current_presets();
}
void MainFrame::add_created_tab(Tab* panel)

View file

@ -49,8 +49,6 @@ _constant()
Ref<StaticPrintConfig> config()
%code%{ RETVAL = &THIS->config(); %};
Points copies();
std::vector<double> layer_height_profile()
%code%{ RETVAL = THIS->layer_height_profile; %};
Clone<BoundingBox> bounding_box();
Points _shifted_copies()