From 65772958b75ad062e9208ee5d0ef93f5d81df8d7 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 13 Dec 2019 13:43:16 +0100 Subject: [PATCH 01/10] Improved adaptive layer height metrics: Using the area of a triangle delimited by the extrusion stepping and the sloping surface. This leads to a yet different metric from Cura or upstream Slic3r. --- src/libslic3r/Slicing.cpp | 98 +++++------- src/libslic3r/Slicing.hpp | 14 +- src/libslic3r/SlicingAdaptive.cpp | 246 ++++++++++++++++++------------ src/libslic3r/SlicingAdaptive.hpp | 48 +++--- src/slic3r/GUI/GLCanvas3D.cpp | 25 ++- src/slic3r/GUI/GLCanvas3D.hpp | 8 +- 6 files changed, 218 insertions(+), 221 deletions(-) diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 9af6048ab..8199bde03 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -224,38 +224,14 @@ std::vector layer_height_profile_from_ranges( // Based on the work of @platsch // Fill layer_height_profile by heights ensuring a prescribed maximum cusp height. -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -std::vector layer_height_profile_adaptive(const SlicingParameters& slicing_params, - const ModelObject& object, float cusp_value) -#else -std::vector layer_height_profile_adaptive( - const SlicingParameters &slicing_params, - const t_layer_config_ranges & /* layer_config_ranges */, - const ModelVolumePtrs &volumes) -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE +std::vector layer_height_profile_adaptive(const SlicingParameters& slicing_params, const ModelObject& object, float quality_factor) { -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 1) Initialize the SlicingAdaptive class with the object meshes. SlicingAdaptive as; as.set_slicing_parameters(slicing_params); - as.set_object(object); -#else - // 1) Initialize the SlicingAdaptive class with the object meshes. - SlicingAdaptive as; - as.set_slicing_parameters(slicing_params); - for (const ModelVolume* volume : volumes) - if (volume->is_model_part()) - as.add_mesh(&volume->mesh()); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - - as.prepare(); + as.prepare(object); // 2) Generate layers using the algorithm of @platsch - // loop until we have at least one layer and the max slice_z reaches the object height -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - double cusp_value = 0.2; -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - std::vector layer_height_profile; layer_height_profile.push_back(0.0); layer_height_profile.push_back(slicing_params.first_object_layer_height); @@ -263,39 +239,41 @@ std::vector layer_height_profile_adaptive( layer_height_profile.push_back(slicing_params.first_object_layer_height); layer_height_profile.push_back(slicing_params.first_object_layer_height); } - double slice_z = slicing_params.first_object_layer_height; - int current_facet = 0; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - while (slice_z <= slicing_params.object_print_z_height()) { - double height = slicing_params.max_layer_height; -#else - double height = slicing_params.first_object_layer_height; - while ((slice_z - height) <= slicing_params.object_print_z_height()) { - height = 999.0; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + double print_z = slicing_params.first_object_layer_height; + // last facet visited by the as.next_layer_height() function, where the facets are sorted by their increasing Z span. + size_t current_facet = 0; + // loop until we have at least one layer and the max slice_z reaches the object height + while (print_z + EPSILON < slicing_params.object_print_z_height()) { + float height = slicing_params.max_layer_height; // Slic3r::debugf "\n Slice layer: %d\n", $id; // determine next layer height - double cusp_height = as.cusp_height((float)slice_z, cusp_value, current_facet); + float cusp_height = as.next_layer_height(float(print_z), quality_factor, current_facet); +#if 0 // check for horizontal features and object size - /* - if($self->config->get_value('match_horizontal_surfaces')) { - my $horizontal_dist = $adaptive_slicing[$region_id]->horizontal_facet_distance(scale $slice_z+$cusp_height, $min_height); - if(($horizontal_dist < $min_height) && ($horizontal_dist > 0)) { - Slic3r::debugf "Horizontal feature ahead, distance: %f\n", $horizontal_dist; - # can we shrink the current layer a bit? - if($cusp_height-($min_height-$horizontal_dist) > $min_height) { - # yes we can - $cusp_height = $cusp_height-($min_height-$horizontal_dist); - Slic3r::debugf "Shrink layer height to %f\n", $cusp_height; - }else{ - # no, current layer would become too thin - $cusp_height = $cusp_height+$horizontal_dist; - Slic3r::debugf "Widen layer height to %f\n", $cusp_height; + if (this->config.match_horizontal_surfaces.value) { + coordf_t horizontal_dist = as.horizontal_facet_distance(print_z + height, min_layer_height); + if ((horizontal_dist < min_layer_height) && (horizontal_dist > 0)) { + #ifdef SLIC3R_DEBUG + std::cout << "Horizontal feature ahead, distance: " << horizontal_dist << std::endl; + #endif + // can we shrink the current layer a bit? + if (height-(min_layer_height - horizontal_dist) > min_layer_height) { + // yes we can + height -= (min_layer_height - horizontal_dist); + #ifdef SLIC3R_DEBUG + std::cout << "Shrink layer height to " << height << std::endl; + #endif + } else { + // no, current layer would become too thin + height += horizontal_dist; + #ifdef SLIC3R_DEBUG + std::cout << "Widen layer height to " << height << std::endl; + #endif } } } - */ +#endif height = std::min(cusp_height, height); // apply z-gradation @@ -308,22 +286,22 @@ std::vector layer_height_profile_adaptive( // look for an applicable custom range /* - if (my $range = first { $_->[0] <= $slice_z && $_->[1] > $slice_z } @{$self->layer_height_ranges}) { + if (my $range = first { $_->[0] <= $print_z && $_->[1] > $print_z } @{$self->layer_height_ranges}) { $height = $range->[2]; # if user set custom height to zero we should just skip the range and resume slicing over it if ($height == 0) { - $slice_z += $range->[1] - $range->[0]; + $print_z += $range->[1] - $range->[0]; next; } } */ - layer_height_profile.push_back(slice_z); + layer_height_profile.push_back(print_z); layer_height_profile.push_back(height); - slice_z += height; + print_z += height; #if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - layer_height_profile.push_back(slice_z); + layer_height_profile.push_back(print_z); layer_height_profile.push_back(height); #endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } @@ -722,11 +700,7 @@ int generate_layer_height_texture( const Vec3crd &color1 = palette_raw[idx1]; const Vec3crd &color2 = palette_raw[idx2]; coordf_t z = cell_to_z * coordf_t(cell); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - assert((lo - EPSILON <= z) && (z <= hi + EPSILON)); -#else - assert(z >= lo && z <= hi); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + assert(lo - EPSILON <= z && z <= hi + EPSILON); // Intensity profile to visualize the layers. coordf_t intensity = cos(M_PI * 0.7 * (mid - z) / h); // Color mapping from layer height to RGB. diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 03ef7e67d..036344b22 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -18,12 +18,7 @@ namespace Slic3r class PrintConfig; class PrintObjectConfig; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class ModelObject; -#else -class ModelVolume; -typedef std::vector ModelVolumePtrs; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Parameters to guide object slicing and support generation. // The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow @@ -142,10 +137,9 @@ extern std::vector layer_height_profile_from_ranges( const SlicingParameters &slicing_params, const t_layer_config_ranges &layer_config_ranges); -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE extern std::vector layer_height_profile_adaptive( const SlicingParameters& slicing_params, - const ModelObject& object, float cusp_value); + const ModelObject& object, float quality_factor); struct HeightProfileSmoothingParams { @@ -159,12 +153,6 @@ struct HeightProfileSmoothingParams extern std::vector smooth_height_profile( const std::vector& profile, const SlicingParameters& slicing_params, const HeightProfileSmoothingParams& smoothing_params); -#else -extern std::vector layer_height_profile_adaptive( - const SlicingParameters &slicing_params, - const t_layer_config_ranges &layer_config_ranges, - const ModelVolumePtrs &volumes); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE enum LayerHeightEditActionType : unsigned int { LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0, diff --git a/src/libslic3r/SlicingAdaptive.cpp b/src/libslic3r/SlicingAdaptive.cpp index b6ebf1ac0..7ab0c47b2 100644 --- a/src/libslic3r/SlicingAdaptive.cpp +++ b/src/libslic3r/SlicingAdaptive.cpp @@ -1,156 +1,211 @@ #include "libslic3r.h" -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #include "Model.hpp" -#else #include "TriangleMesh.hpp" -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE #include "SlicingAdaptive.hpp" +#include + +// Based on the work of Florens Waserfall (@platch on github) +// and his paper +// Florens Wasserfall, Norman Hendrich, Jianwei Zhang: +// Adaptive Slicing for the FDM Process Revisited +// 13th IEEE Conference on Automation Science and Engineering (CASE-2017), August 20-23, Xi'an, China. DOI: 10.1109/COASE.2017.8256074 +// https://tams.informatik.uni-hamburg.de/publications/2017/Adaptive%20Slicing%20for%20the%20FDM%20Process%20Revisited.pdf + +// Vojtech believes that there is a bug in @platch's derivation of the triangle area error metric. +// Following Octave code paints graphs of recommended layer height versus surface slope angle. +#if 0 +adeg=0:1:85; +a=adeg*pi/180; +t=tan(a); +tsqr=sqrt(tan(a)); +lerr=1./cos(a); +lerr2=1./(0.3+cos(a)); +plot(adeg, t, 'b', adeg, sqrt(t), 'g', adeg, 0.5 * lerr, 'm', adeg, 0.5 * lerr2, 'r') +xlabel("angle(deg), 0 - horizontal wall, 90 - vertical wall"); +ylabel("layer height"); +legend("tan(a) as cura - topographic lines distance limit", "sqrt(tan(a)) as PrusaSlicer - error triangle area limit", "old slic3r - max distance metric", "new slic3r - Waserfall paper"); +#endif + +#ifndef NDEBUG + #define ADAPTIVE_LAYER_HEIGHT_DEBUG +#endif /* NDEBUG */ + namespace Slic3r { -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -void SlicingAdaptive::clear() -{ - m_meshes.clear(); - m_faces.clear(); - m_face_normal_z.clear(); -} -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - -std::pair face_z_span(const stl_facet *f) +static inline std::pair face_z_span(const stl_facet &f) { return std::pair( - std::min(std::min(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)), - std::max(std::max(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2))); + std::min(std::min(f.vertex[0](2), f.vertex[1](2)), f.vertex[2](2)), + std::max(std::max(f.vertex[0](2), f.vertex[1](2)), f.vertex[2](2))); } -void SlicingAdaptive::prepare() +// By Florens Waserfall aka @platch: +// This constant essentially describes the volumetric error at the surface which is induced +// by stacking "elliptic" extrusion threads. It is empirically determined by +// 1. measuring the surface profile of printed parts to find +// the ratio between layer height and profile height and then +// 2. computing the geometric difference between the model-surface and the elliptic profile. +// +// The definition of the roughness formula is in +// https://tams.informatik.uni-hamburg.de/publications/2017/Adaptive%20Slicing%20for%20the%20FDM%20Process%20Revisited.pdf +// (page 51, formula (8)) +// Currenty @platch's error metric formula is not used. +static constexpr double SURFACE_CONST = 0.18403; + +// for a given facet, compute maximum height within the allowed surface roughness / stairstepping deviation +static inline float layer_height_from_slope(const SlicingAdaptive::FaceZ &face, float max_surface_deviation) { -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - if (m_object == nullptr) - return; +// @platch's formula, see his paper "Adaptive Slicing for the FDM Process Revisited". +// return float(max_surface_deviation / (SURFACE_CONST + 0.5 * std::abs(normal_z))); + +// Constant stepping in horizontal direction, as used by Cura. +// return (face.n_cos > 1e-5) ? float(max_surface_deviation * face.n_sin / face.n_cos) : FLT_MAX; - m_faces.clear(); - m_face_normal_z.clear(); +// Constant error measured as an area of the surface error triangle, Vojtech's formula. +// return (face.n_cos > 1e-5) ? float(1.44 * max_surface_deviation * sqrt(face.n_sin / face.n_cos)) : FLT_MAX; - m_mesh = m_object->raw_mesh(); - const ModelInstance* first_instance = m_object->instances.front(); - m_mesh.transform(first_instance->get_matrix(), first_instance->is_left_handed()); +// Constant error measured as an area of the surface error triangle, Vojtech's formula with clamping to roughness at 90 degrees. + return std::min(max_surface_deviation / 0.184f, (face.n_cos > 1e-5) ? float(1.44 * max_surface_deviation * sqrt(face.n_sin / face.n_cos)) : FLT_MAX); + +// Constant stepping along the surface, equivalent to the "surface roughness" metric by Perez and later Pandey et all, see @platch's paper for references. +// return float(max_surface_deviation * face.n_sin); +} + +void SlicingAdaptive::clear() +{ + m_faces.clear(); +} + +void SlicingAdaptive::prepare(const ModelObject &object) +{ + this->clear(); + + TriangleMesh mesh = object.raw_mesh(); + const ModelInstance &first_instance = *object.instances.front(); + mesh.transform(first_instance.get_matrix(), first_instance.is_left_handed()); // 1) Collect faces from mesh. - m_faces.reserve(m_mesh.stl.stats.number_of_facets); - for (stl_facet& face : m_mesh.stl.facet_start) - { - face.normal.normalize(); - m_faces.emplace_back(&face); + m_faces.reserve(mesh.stl.stats.number_of_facets); + for (const stl_facet &face : mesh.stl.facet_start) { + Vec3f n = face.normal.normalized(); + m_faces.emplace_back(FaceZ({ face_z_span(face), std::abs(n.z()), std::sqrt(n.x() * n.x() + n.y() * n.y()) })); } -#else - // 1) Collect faces of all meshes. - int nfaces_total = 0; - for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) - nfaces_total += (*it_mesh)->stl.stats.number_of_facets; - m_faces.reserve(nfaces_total); - for (std::vector::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) - for (const stl_facet& face : (*it_mesh)->stl.facet_start) - m_faces.emplace_back(&face); -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // 2) Sort faces lexicographically by their Z span. - std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) { return face_z_span(f1) < face_z_span(f2); }); - - // 3) Generate Z components of the facet normals. - m_face_normal_z.assign(m_faces.size(), 0.0f); - for (size_t iface = 0; iface < m_faces.size(); ++ iface) - m_face_normal_z[iface] = m_faces[iface]->normal(2); + std::sort(m_faces.begin(), m_faces.end(), [](const FaceZ &f1, const FaceZ &f2) { return f1.z_span < f2.z_span; }); } -float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet) +// current_facet is in/out parameter, rememebers the index of the last face of m_faces visited, +// where this function will start from. +// print_z - the top print surface of the previous layer. +// returns height of the next layer. +float SlicingAdaptive::next_layer_height(const float print_z, float quality_factor, size_t ¤t_facet) { - float height = (float)m_slicing_params.max_layer_height; - bool first_hit = false; + float height = (float)m_slicing_params.max_layer_height; + + float max_surface_deviation; + + { +#if 0 +// @platch's formula for quality: + double delta_min = SURFACE_CONST * m_slicing_params.min_layer_height; + double delta_mid = (SURFACE_CONST + 0.5) * m_slicing_params.layer_height; + double delta_max = (SURFACE_CONST + 0.5) * m_slicing_params.max_layer_height; +#else +// Vojtech's formula for triangle area error metric. + double delta_min = m_slicing_params.min_layer_height; + double delta_mid = m_slicing_params.layer_height; + double delta_max = m_slicing_params.max_layer_height; +#endif + max_surface_deviation = (quality_factor < 0.5f) ? + lerp(delta_min, delta_mid, 2. * quality_factor) : + lerp(delta_max, delta_mid, 2. * (1. - quality_factor)); + } // find all facets intersecting the slice-layer - int ordered_id = current_facet; - for (; ordered_id < int(m_faces.size()); ++ ordered_id) { - std::pair zspan = face_z_span(m_faces[ordered_id]); - // facet's minimum is higher than slice_z -> end loop - if (zspan.first >= z) - break; - // facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point - if (zspan.second > z) { - // first event? - if (! first_hit) { - first_hit = true; - current_facet = ordered_id; - } - // skip touching facets which could otherwise cause small cusp values - if (zspan.second <= z + EPSILON) - continue; - // compute cusp-height for this facet and store minimum of all heights - float normal_z = m_face_normal_z[ordered_id]; - height = std::min(height, (normal_z == 0.0f) ? (float)m_slicing_params.max_layer_height : std::abs(cusp_value / normal_z)); - } + size_t ordered_id = current_facet; + { + bool first_hit = false; + for (; ordered_id < m_faces.size(); ++ ordered_id) { + const std::pair &zspan = m_faces[ordered_id].z_span; + // facet's minimum is higher than slice_z -> end loop + if (zspan.first >= print_z) + break; + // facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point + if (zspan.second > print_z) { + // first event? + if (! first_hit) { + first_hit = true; + current_facet = ordered_id; + } + // skip touching facets which could otherwise cause small cusp values + if (zspan.second < print_z + EPSILON) + continue; + // compute cusp-height for this facet and store minimum of all heights + height = std::min(height, layer_height_from_slope(m_faces[ordered_id], max_surface_deviation)); + } + } } // lower height limit due to printer capabilities height = std::max(height, float(m_slicing_params.min_layer_height)); // check for sloped facets inside the determined layer and correct height if necessary - if (height > m_slicing_params.min_layer_height) { - for (; ordered_id < int(m_faces.size()); ++ ordered_id) { - std::pair zspan = face_z_span(m_faces[ordered_id]); + if (height > float(m_slicing_params.min_layer_height)) { + for (; ordered_id < m_faces.size(); ++ ordered_id) { + const std::pair &zspan = m_faces[ordered_id].z_span; // facet's minimum is higher than slice_z + height -> end loop - if (zspan.first >= z + height) + if (zspan.first >= print_z + height) break; // skip touching facets which could otherwise cause small cusp values - if (zspan.second <= z + EPSILON) + if (zspan.second < print_z + EPSILON) continue; // Compute cusp-height for this facet and check against height. - float normal_z = m_face_normal_z[ordered_id]; - float cusp = (normal_z == 0.0f) ? (float)m_slicing_params.max_layer_height : std::abs(cusp_value / normal_z); + float reduced_height = layer_height_from_slope(m_faces[ordered_id], max_surface_deviation); - float z_diff = zspan.first - z; - - // handle horizontal facets - if (normal_z > 0.999f) { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; + float z_diff = zspan.first - print_z; + if (reduced_height < z_diff) { + assert(z_diff < height + EPSILON); + // The currently visited triangle's slope limits the next layer height so much, that + // the lowest point of the currently visible triangle is already above the newly proposed layer height. + // This means, that we need to limit the layer height so that the offending newly visited triangle + // is just above of the new layer. +#ifdef ADAPTIVE_LAYER_HEIGHT_DEBUG + BOOST_LOG_TRIVIAL(trace) << "cusp computation, height is reduced from " << height << "to " << z_diff << " due to z-diff"; +#endif /* ADAPTIVE_LAYER_HEIGHT_DEBUG */ height = z_diff; - // Slic3r::debugf "to %f due to near horizontal facet\n", $height; - } else if (cusp > z_diff) { - if (cusp < height) { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; - height = cusp; - // Slic3r::debugf "to %f due to new cusp height\n", $height; - } - } else { - // Slic3r::debugf "cusp computation, height is reduced from %f", $height; - height = z_diff; - // Slic3r::debugf "to z-diff: %f\n", $height; + } else if (reduced_height < height) { +#ifdef ADAPTIVE_LAYER_HEIGHT_DEBUG + BOOST_LOG_TRIVIAL(trace) << "adaptive layer computation: height is reduced from " << height << "to " << reduced_height << " due to higher facet"; +#endif /* ADAPTIVE_LAYER_HEIGHT_DEBUG */ + height = reduced_height; } } // lower height limit due to printer capabilities again height = std::max(height, float(m_slicing_params.min_layer_height)); } -// Slic3r::debugf "cusp computation, layer-bottom at z:%f, cusp_value:%f, resulting layer height:%f\n", unscale $z, $cusp_value, $height; +#ifdef ADAPTIVE_LAYER_HEIGHT_DEBUG + BOOST_LOG_TRIVIAL(trace) << "adaptive layer computation, layer-bottom at z:" << print_z << ", quality_factor:" << quality_factor << ", resulting layer height:" << height; +#endif /* ADAPTIVE_LAYER_HEIGHT_DEBUG */ return height; } -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE // Returns the distance to the next horizontal facet in Z-dir // to consider horizontal object features in slice thickness float SlicingAdaptive::horizontal_facet_distance(float z) { for (size_t i = 0; i < m_faces.size(); ++ i) { - std::pair zspan = face_z_span(m_faces[i]); + std::pair zspan = m_faces[i].z_span; // facet's minimum is higher than max forward distance -> end loop if (zspan.first > z + m_slicing_params.max_layer_height) break; // min_z == max_z -> horizontal facet - if ((zspan.first > z) && (zspan.first == zspan.second)) + if (zspan.first > z && zspan.first == zspan.second) return zspan.first - z; } @@ -158,6 +213,5 @@ float SlicingAdaptive::horizontal_facet_distance(float z) return (z + (float)m_slicing_params.max_layer_height > (float)m_slicing_params.object_print_z_height()) ? std::max((float)m_slicing_params.object_print_z_height() - z, 0.f) : (float)m_slicing_params.max_layer_height; } -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE }; // namespace Slic3r diff --git a/src/libslic3r/SlicingAdaptive.hpp b/src/libslic3r/SlicingAdaptive.hpp index 1d2996986..a296553d6 100644 --- a/src/libslic3r/SlicingAdaptive.hpp +++ b/src/libslic3r/SlicingAdaptive.hpp @@ -5,50 +5,36 @@ #include "Slicing.hpp" #include "admesh/stl.h" -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -#include "TriangleMesh.hpp" -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE namespace Slic3r { -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class ModelVolume; -#else -class TriangleMesh; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE class SlicingAdaptive { public: -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void clear(); -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void set_object(const ModelObject& object) { m_object = &object; } -#else - void add_mesh(const TriangleMesh* mesh) { m_meshes.push_back(mesh); } -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void prepare(); - float cusp_height(float z, float cusp_value, int ¤t_facet); -#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + void clear(); + void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; } + void prepare(const ModelObject &object); + // Return next layer height starting from the last print_z, using a quality measure + // (quality in range from 0 to 1, 0 - highest quality at low layer heights, 1 - lowest print quality at high layer heights). + // The layer height curve shall be centered roughly around the default profile's layer height for quality 0.5. + float next_layer_height(const float print_z, float quality, size_t ¤t_facet); float horizontal_facet_distance(float z); -#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE + + struct FaceZ { + std::pair z_span; + // Cosine of the normal vector towards the Z axis. + float n_cos; + // Sine of the normal vector towards the Z axis. + float n_sin; + }; protected: - SlicingParameters m_slicing_params; + SlicingParameters m_slicing_params; -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - const ModelObject* m_object; - TriangleMesh m_mesh; -#else - std::vector m_meshes; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - // Collected faces of all meshes, sorted by raising Z of the bottom most face. - std::vector m_faces; - // Z component of face normals, normalized. - std::vector m_face_normal_z; + std::vector m_faces; }; }; // namespace Slic3r diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 71ce173df..012127aed 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -133,7 +133,7 @@ GLCanvas3D::LayersEditing::LayersEditing() , m_slicing_parameters(nullptr) , m_layer_height_profile_modified(false) #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - , m_adaptive_cusp(0.0f) + , m_adaptive_quality(0.5f) #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE , state(Unknown) , band_width(2.0f) @@ -268,24 +268,24 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const ImGui::Separator(); if (imgui.button(_(L("Adaptive")))) - wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_cusp)); + wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), Event(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, m_adaptive_quality)); ImGui::SameLine(); float text_align = ImGui::GetCursorPosX(); ImGui::AlignTextToFramePadding(); - imgui.text(_(L("Cusp (mm)"))); + imgui.text(_(L("Quality / Speed"))); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - ImGui::TextUnformatted(_(L("I am a tooltip"))); + ImGui::TextUnformatted(_(L("Higher print quality versus higher print speed."))); ImGui::EndTooltip(); } ImGui::SameLine(); float widget_align = ImGui::GetCursorPosX(); ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f); - m_adaptive_cusp = clamp(0.0f, 0.5f * (float)m_slicing_parameters->layer_height, m_adaptive_cusp); - ImGui::SliderFloat("", &m_adaptive_cusp, 0.0f, 0.5f * (float)m_slicing_parameters->layer_height, "%.3f"); + m_adaptive_quality = clamp(0.0f, 1.f, m_adaptive_quality); + ImGui::SliderFloat("", &m_adaptive_quality, 0.0f, 1.f, "%.2f"); ImGui::Separator(); if (imgui.button(_(L("Smooth")))) @@ -645,10 +645,10 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas) } #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp) +void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor) { this->update_slicing_parameters(); - m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object, cusp); + m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object, quality_factor); const_cast(m_model_object)->layer_height_profile = m_layer_height_profile; m_layers_texture.valid = false; canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); @@ -712,11 +712,6 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters() m_slicing_parameters = new SlicingParameters(); *m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z); } - -#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - if (m_adaptive_cusp == 0.0f) - m_adaptive_cusp = 0.25f * m_slicing_parameters->layer_height; -#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE } float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D &canvas) @@ -1690,10 +1685,10 @@ void GLCanvas3D::reset_layer_height_profile() m_dirty = true; } -void GLCanvas3D::adaptive_layer_height_profile(float cusp) +void GLCanvas3D::adaptive_layer_height_profile(float quality_factor) { wxGetApp().plater()->take_snapshot(_(L("Variable layer height - Adaptive"))); - m_layers_editing.adaptive_layer_height_profile(*this, cusp); + m_layers_editing.adaptive_layer_height_profile(*this, quality_factor); m_layers_editing.state = LayersEditing::Completed; m_dirty = true; } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2ff65052a..547a9d885 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -185,7 +185,7 @@ private: bool m_layer_height_profile_modified; #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - mutable float m_adaptive_cusp; + mutable float m_adaptive_quality; mutable HeightProfileSmoothingParams m_smooth_params; #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE @@ -236,8 +236,8 @@ private: void accept_changes(GLCanvas3D& canvas); void reset_layer_height_profile(GLCanvas3D& canvas); #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE - void adaptive_layer_height_profile(GLCanvas3D& canvas, float cusp); - void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_paramsn); + void adaptive_layer_height_profile(GLCanvas3D& canvas, float quality_factor); + void smooth_layer_height_profile(GLCanvas3D& canvas, const HeightProfileSmoothingParams& smoothing_params); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE static float get_cursor_z_relative(const GLCanvas3D& canvas); @@ -539,7 +539,7 @@ public: #if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE void reset_layer_height_profile(); - void adaptive_layer_height_profile(float cusp); + void adaptive_layer_height_profile(float quality_factor); void smooth_layer_height_profile(const HeightProfileSmoothingParams& smoothing_params); #endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE From 34b6f7362a9de43c706b5e4c7689f3035950312a Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 8 Dec 2019 16:08:39 +0100 Subject: [PATCH 02/10] Add dependency on -ldl to hidapi (for dlclose) on linux --- src/hidapi/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hidapi/CMakeLists.txt b/src/hidapi/CMakeLists.txt index 1f53c9b69..f3045466e 100644 --- a/src/hidapi/CMakeLists.txt +++ b/src/hidapi/CMakeLists.txt @@ -15,5 +15,5 @@ add_library(hidapi STATIC ${HIDAPI_IMPL}) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") # Don't link the udev library, as there are two versions out there (libudev.so.0, libudev.so.1), so they are linked explicitely. # target_link_libraries(hidapi udev) - target_link_libraries(hidapi) + target_link_libraries(hidapi dl) endif() From b061904ad8d4c136c5aa1f7a78d98a74dc31bab2 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 13 Dec 2019 15:40:42 +0100 Subject: [PATCH 03/10] Fixes by @supermerill from pull request "ShortestPath fix" #3306 --- src/libslic3r/ShortestPath.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index 8b5cbf483..39b82f4ce 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -43,6 +43,7 @@ std::vector> chain_segments_closest_point(std::vector> chain_segments_greedy_constrained_reversals else if (num_segments == 1) { // Just sort the end points so that the first point visited is closest to start_near. - out.emplace_back(0, start_near != nullptr && + out.emplace_back(0, could_reverse_func(0) && start_near != nullptr && (end_point_func(0, true) - *start_near).template cast().squaredNorm() < (end_point_func(0, false) - *start_near).template cast().squaredNorm()); } else From 06c9d3ad560146ec6d3de19683c6a8b6075b148b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 13 Dec 2019 17:46:35 +0100 Subject: [PATCH 04/10] Added readme.md file for hidapi --- src/hidapi/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/hidapi/README.md diff --git a/src/hidapi/README.md b/src/hidapi/README.md new file mode 100644 index 000000000..4f66b3274 --- /dev/null +++ b/src/hidapi/README.md @@ -0,0 +1,5 @@ +** hidapi is a c++ library for communicating with USB and Bluetooth HID devices on Linux, Mac and Windows.** + +For more information go to https://github.com/libusb/hidapi + +THIS DIRECTORY CONTAINS THE hidapi-0.9.0 7da5cc9 SOURCE DISTRIBUTION. From ca518c003f9aa60fa62b5f5770266fa9ee9d7d43 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 16 Dec 2019 10:24:08 +0100 Subject: [PATCH 05/10] Added message dialog informing the user that it is not allowed to change the filename when using reload from disk command --- src/slic3r/GUI/Plater.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c8267331d..861ff47da 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3245,22 +3245,30 @@ void Plater::priv::reload_from_disk() input_paths.push_back(sel_filename_path); missing_input_paths.pop_back(); - std::string sel_path = fs::path(sel_filename_path).remove_filename().string(); + fs::path sel_path = fs::path(sel_filename_path).remove_filename().string(); std::vector::iterator it = missing_input_paths.begin(); while (it != missing_input_paths.end()) { // try to use the path of the selected file with all remaining missing files - std::string repathed_filename = sel_path + "/" + it->filename().string(); + fs::path repathed_filename = sel_path; + repathed_filename /= it->filename(); if (fs::exists(repathed_filename)) { - input_paths.push_back(repathed_filename); + input_paths.push_back(repathed_filename.string()); it = missing_input_paths.erase(it); } else ++it; } } + else + { + wxString message = _(L("It is not allowed to change the file to reload")) + " (" + from_u8(fs::path(search).filename().string())+ ").\n" + _(L("Do you want to retry")) + " ?"; + wxMessageDialog dlg(q, message, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION); + if (dlg.ShowModal() != wxID_YES) + return; + } } #endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION From 09e15939acb239975362eb64216c91c262c0c471 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 16 Dec 2019 10:34:51 +0100 Subject: [PATCH 06/10] Bumped up version number of Slicer --- version.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/version.inc b/version.inc index 0a62ff6f3..c96a304ab 100644 --- a/version.inc +++ b/version.inc @@ -3,7 +3,7 @@ set(SLIC3R_APP_NAME "PrusaSlicer") set(SLIC3R_APP_KEY "PrusaSlicer") -set(SLIC3R_VERSION "2.1.0") +set(SLIC3R_VERSION "2.2.0-alpha0") set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN") -set(SLIC3R_RC_VERSION "2,1,0,0") -set(SLIC3R_RC_VERSION_DOTS "2.1.0.0") +set(SLIC3R_RC_VERSION "2,2,0,0") +set(SLIC3R_RC_VERSION_DOTS "2.2.0.0") From 43213b95480a085f1e9bd75ec439b69d6a7e1a97 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 16 Dec 2019 13:35:45 +0100 Subject: [PATCH 07/10] Added [X] and [Close] buttons to close 3Dconnexion setting imgui dialog by clicking on them --- src/libslic3r/Technologies.hpp | 3 + src/slic3r/GUI/GLCanvas3D.cpp | 6 +- src/slic3r/GUI/ImGuiWrapper.cpp | 10 ++ src/slic3r/GUI/ImGuiWrapper.hpp | 2 + src/slic3r/GUI/Mouse3DController.cpp | 219 +++++++++++++++++---------- src/slic3r/GUI/Mouse3DController.hpp | 19 ++- 6 files changed, 178 insertions(+), 81 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 0ec8b36ee..d503f0c64 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -53,4 +53,7 @@ // Enable selection for missing files in reload from disk command #define ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION (1 && ENABLE_2_2_0_ALPHA1) +// Enable closing 3Dconnextion imgui settings dialog by clicking on [X] and [Close] buttons +#define ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG (1 && ENABLE_2_2_0_ALPHA1) + #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8e922398a..5a0092f8b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1920,7 +1920,11 @@ void GLCanvas3D::render() m_camera.debug_render(); #endif // ENABLE_CAMERA_STATISTICS +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog(*this); +#else wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG wxGetApp().imgui()->render(); @@ -2628,8 +2632,8 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) if (m_extra_frame_requested || mouse3d_controller_applied) { m_dirty = true; - evt.RequestMore(); m_extra_frame_requested = false; + evt.RequestMore(); } else m_dirty = false; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 33e526083..90ef017fc 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -254,6 +254,16 @@ bool ImGuiWrapper::begin(const wxString &name, int flags) return begin(into_u8(name), flags); } +bool ImGuiWrapper::begin(const std::string& name, bool* close, int flags) +{ + return ImGui::Begin(name.c_str(), close, (ImGuiWindowFlags)flags); +} + +bool ImGuiWrapper::begin(const wxString& name, bool* close, int flags) +{ + return begin(into_u8(name), close, flags); +} + void ImGuiWrapper::end() { ImGui::End(); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 7cce60367..5118af036 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -56,6 +56,8 @@ public: bool begin(const std::string &name, int flags = 0); bool begin(const wxString &name, int flags = 0); + bool begin(const std::string& name, bool* close, int flags = 0); + bool begin(const wxString& name, bool* close, int flags = 0); void end(); bool button(const wxString &label); diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index b3d7c0e4f..ad5be88d8 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -5,6 +5,9 @@ #include "GUI_App.hpp" #include "PresetBundle.hpp" #include "AppConfig.hpp" +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG +#include "GLCanvas3D.hpp" +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG #include @@ -184,7 +187,10 @@ Mouse3DController::Mouse3DController() , m_device(nullptr) , m_device_str("") , m_running(false) - , m_settings_dialog(false) + , m_show_settings_dialog(false) +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + , m_settings_dialog_closed_by_user(false) +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG { m_last_time = std::chrono::high_resolution_clock::now(); } @@ -229,8 +235,11 @@ bool Mouse3DController::apply(Camera& camera) if (!m_running && is_device_connected()) { disconnect_device(); - // hides the settings dialog if the user re-plug the device - m_settings_dialog = false; + // hides the settings dialog if the user un-plug the device + m_show_settings_dialog = false; +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + m_settings_dialog_closed_by_user = false; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG } // check if the user plugged the device @@ -240,88 +249,144 @@ bool Mouse3DController::apply(Camera& camera) return is_device_connected() ? m_state.apply(camera) : false; } +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG +void Mouse3DController::render_settings_dialog(GLCanvas3D& canvas) const +#else void Mouse3DController::render_settings_dialog(unsigned int canvas_width, unsigned int canvas_height) const +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG { - if (!m_running || !m_settings_dialog) + if (!m_running || !m_show_settings_dialog) return; - ImGuiWrapper& imgui = *wxGetApp().imgui(); - - imgui.set_next_window_pos(0.5f * (float)canvas_width, 0.5f * (float)canvas_height, ImGuiCond_Always, 0.5f, 0.5f); - - imgui.begin(_(L("3Dconnexion settings")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); - - const ImVec4& color = ImGui::GetStyleColorVec4(ImGuiCol_Separator); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text(_(L("Device:"))); - ImGui::PopStyleColor(); - ImGui::SameLine(); - imgui.text(m_device_str); - - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text(_(L("Speed:"))); - ImGui::PopStyleColor(); - - float translation_scale = (float)m_state.get_translation_scale() / State::DefaultTranslationScale; - if (imgui.slider_float(_(L("Translation")) + "##1", &translation_scale, 0.5f, 2.0f, "%.1f")) - m_state.set_translation_scale(State::DefaultTranslationScale * (double)translation_scale); - - float rotation_scale = m_state.get_rotation_scale() / State::DefaultRotationScale; - if (imgui.slider_float(_(L("Rotation")) + "##1", &rotation_scale, 0.5f, 2.0f, "%.1f")) - m_state.set_rotation_scale(State::DefaultRotationScale * rotation_scale); - - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text(_(L("Deadzone:"))); - ImGui::PopStyleColor(); - - float translation_deadzone = (float)m_state.get_translation_deadzone(); - if (imgui.slider_float(_(L("Translation")) + "##2", &translation_deadzone, 0.0f, (float)State::MaxTranslationDeadzone, "%.2f")) - m_state.set_translation_deadzone((double)translation_deadzone); - - float rotation_deadzone = m_state.get_rotation_deadzone(); - if (imgui.slider_float(_(L("Rotation")) + "##2", &rotation_deadzone, 0.0f, State::MaxRotationDeadzone, "%.2f")) - m_state.set_rotation_deadzone(rotation_deadzone); - -#if ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT - ImGui::Separator(); - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text("DEBUG:"); - imgui.text("Vectors:"); - ImGui::PopStyleColor(); - Vec3f translation = m_state.get_translation().cast(); - Vec3f rotation = m_state.get_rotation(); - ImGui::InputFloat3("Translation##3", translation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); - ImGui::InputFloat3("Rotation##3", rotation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); - - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text("Queue size:"); - ImGui::PopStyleColor(); - - int translation_size[2] = { (int)m_state.get_translation_queue_size(), (int)m_state.get_translation_queue_max_size() }; - int rotation_size[2] = { (int)m_state.get_rotation_queue_size(), (int)m_state.get_rotation_queue_max_size() }; - int buttons_size[2] = { (int)m_state.get_buttons_queue_size(), (int)m_state.get_buttons_queue_max_size() }; - - ImGui::InputInt2("Translation##4", translation_size, ImGuiInputTextFlags_ReadOnly); - ImGui::InputInt2("Rotation##4", rotation_size, ImGuiInputTextFlags_ReadOnly); - ImGui::InputInt2("Buttons", buttons_size, ImGuiInputTextFlags_ReadOnly); - - int queue_size = (int)m_state.get_queues_max_size(); - if (ImGui::InputInt("Max size", &queue_size, 1, 1, ImGuiInputTextFlags_ReadOnly)) +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + // when the user clicks on [X] or [Close] button we need to trigger + // an extra frame to let the dialog disappear + if (m_settings_dialog_closed_by_user) { - if (queue_size > 0) - m_state.set_queues_max_size(queue_size); + m_show_settings_dialog = false; + m_settings_dialog_closed_by_user = false; + canvas.request_extra_frame(); + return; } - ImGui::Separator(); - ImGui::PushStyleColor(ImGuiCol_Text, color); - imgui.text("Camera:"); - ImGui::PopStyleColor(); - Vec3f target = wxGetApp().plater()->get_camera().get_target().cast(); - ImGui::InputFloat3("Target", target.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); + Size cnv_size = canvas.get_canvas_size(); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + + ImGuiWrapper& imgui = *wxGetApp().imgui(); +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + imgui.set_next_window_pos(0.5f * (float)cnv_size.get_width(), 0.5f * (float)cnv_size.get_height(), ImGuiCond_Always, 0.5f, 0.5f); +#else + imgui.set_next_window_pos(0.5f * (float)canvas_width, 0.5f * (float)canvas_height, ImGuiCond_Always, 0.5f, 0.5f); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + static ImVec2 last_win_size(0.0f, 0.0f); + bool shown = true; + if (imgui.begin(_(L("3Dconnexion settings")), &shown, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse)) + { + if (shown) + { + ImVec2 win_size = ImGui::GetWindowSize(); + if ((last_win_size.x != win_size.x) || (last_win_size.y != win_size.y)) + { + // when the user clicks on [X] button, the next time the dialog is shown + // has a dummy size, so we trigger an extra frame to let it have the correct size + last_win_size = win_size; + canvas.request_extra_frame(); + } +#else + imgui.begin(_(L("3Dconnexion settings")), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + + const ImVec4& color = ImGui::GetStyleColorVec4(ImGuiCol_Separator); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text(_(L("Device:"))); + ImGui::PopStyleColor(); + ImGui::SameLine(); + imgui.text(m_device_str); + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text(_(L("Speed:"))); + ImGui::PopStyleColor(); + + float translation_scale = (float)m_state.get_translation_scale() / State::DefaultTranslationScale; + if (imgui.slider_float(_(L("Translation")) + "##1", &translation_scale, 0.5f, 2.0f, "%.1f")) + m_state.set_translation_scale(State::DefaultTranslationScale * (double)translation_scale); + + float rotation_scale = m_state.get_rotation_scale() / State::DefaultRotationScale; + if (imgui.slider_float(_(L("Rotation")) + "##1", &rotation_scale, 0.5f, 2.0f, "%.1f")) + m_state.set_rotation_scale(State::DefaultRotationScale * rotation_scale); + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text(_(L("Deadzone:"))); + ImGui::PopStyleColor(); + + float translation_deadzone = (float)m_state.get_translation_deadzone(); + if (imgui.slider_float(_(L("Translation")) + "##2", &translation_deadzone, 0.0f, (float)State::MaxTranslationDeadzone, "%.2f")) + m_state.set_translation_deadzone((double)translation_deadzone); + + float rotation_deadzone = m_state.get_rotation_deadzone(); + if (imgui.slider_float(_(L("Rotation")) + "##2", &rotation_deadzone, 0.0f, State::MaxRotationDeadzone, "%.2f")) + m_state.set_rotation_deadzone(rotation_deadzone); + +#if ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT + ImGui::Separator(); + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text("DEBUG:"); + imgui.text("Vectors:"); + ImGui::PopStyleColor(); + Vec3f translation = m_state.get_translation().cast(); + Vec3f rotation = m_state.get_rotation(); + ImGui::InputFloat3("Translation##3", translation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); + ImGui::InputFloat3("Rotation##3", rotation.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); + + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text("Queue size:"); + ImGui::PopStyleColor(); + + int translation_size[2] = { (int)m_state.get_translation_queue_size(), (int)m_state.get_translation_queue_max_size() }; + int rotation_size[2] = { (int)m_state.get_rotation_queue_size(), (int)m_state.get_rotation_queue_max_size() }; + int buttons_size[2] = { (int)m_state.get_buttons_queue_size(), (int)m_state.get_buttons_queue_max_size() }; + + ImGui::InputInt2("Translation##4", translation_size, ImGuiInputTextFlags_ReadOnly); + ImGui::InputInt2("Rotation##4", rotation_size, ImGuiInputTextFlags_ReadOnly); + ImGui::InputInt2("Buttons", buttons_size, ImGuiInputTextFlags_ReadOnly); + + int queue_size = (int)m_state.get_queues_max_size(); + if (ImGui::InputInt("Max size", &queue_size, 1, 1, ImGuiInputTextFlags_ReadOnly)) + { + if (queue_size > 0) + m_state.set_queues_max_size(queue_size); + } + + ImGui::Separator(); + ImGui::PushStyleColor(ImGuiCol_Text, color); + imgui.text("Camera:"); + ImGui::PopStyleColor(); + Vec3f target = wxGetApp().plater()->get_camera().get_target().cast(); + ImGui::InputFloat3("Target", target.data(), "%.3f", ImGuiInputTextFlags_ReadOnly); #endif // ENABLE_3DCONNEXION_DEVICES_DEBUG_OUTPUT +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + + ImGui::Separator(); + if (imgui.button(_(L("Close")))) + { + // the user clicked on the [Close] button + m_settings_dialog_closed_by_user = true; + canvas.set_as_dirty(); + } + } + else + { + // the user clicked on the [X] button + m_settings_dialog_closed_by_user = true; + canvas.set_as_dirty(); + } + } +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG imgui.end(); } diff --git a/src/slic3r/GUI/Mouse3DController.hpp b/src/slic3r/GUI/Mouse3DController.hpp index cc03d4a24..543c44e77 100644 --- a/src/slic3r/GUI/Mouse3DController.hpp +++ b/src/slic3r/GUI/Mouse3DController.hpp @@ -18,6 +18,9 @@ namespace Slic3r { namespace GUI { struct Camera; +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG +class GLCanvas3D; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG class Mouse3DController { @@ -130,7 +133,13 @@ class Mouse3DController hid_device* m_device; std::string m_device_str; bool m_running; - bool m_settings_dialog; +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + mutable bool m_show_settings_dialog; + // set to true when ther user closes the dialog by clicking on [X] or [Close] buttons + mutable bool m_settings_dialog_closed_by_user; +#else + bool m_show_settings_dialog; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG std::chrono::time_point m_last_time; public: @@ -146,9 +155,13 @@ public: bool apply(Camera& camera); - bool is_settings_dialog_shown() const { return m_settings_dialog; } - void show_settings_dialog(bool show) { m_settings_dialog = show && is_running(); } + bool is_settings_dialog_shown() const { return m_show_settings_dialog; } + void show_settings_dialog(bool show) { m_show_settings_dialog = show && is_running(); } +#if ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG + void render_settings_dialog(GLCanvas3D& canvas) const; +#else void render_settings_dialog(unsigned int canvas_width, unsigned int canvas_height) const; +#endif // ENABLE_3DCONNEXION_DEVICES_CLOSE_SETTING_DIALOG private: bool connect_device(); From 20e59cb0c78835355494c61223a437f20fbbf452 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 10:51:18 +0100 Subject: [PATCH 08/10] Fix missing gmpxx from dep_GMP --- deps/GMP/GMP.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/GMP/GMP.cmake b/deps/GMP/GMP.cmake index 6c93107c4..8bcf94859 100644 --- a/deps/GMP/GMP.cmake +++ b/deps/GMP/GMP.cmake @@ -20,7 +20,7 @@ else () ExternalProject_Add(dep_GMP URL https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2 BUILD_IN_SOURCE ON - CONFIGURE_COMMAND ./configure --enable-shared=no --enable-static=yes "--prefix=${DESTDIR}/usr/local" --with-pic + CONFIGURE_COMMAND ./configure --enable-shared=no --enable-cxx=yes --enable-static=yes "--prefix=${DESTDIR}/usr/local" --with-pic BUILD_COMMAND make -j INSTALL_COMMAND make install ) From aff5adaaa06dbbb2d6b0f9641a3ae54e275a2124 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 17 Dec 2019 10:55:08 +0100 Subject: [PATCH 09/10] Fixed a typo in extrusion ordering, pointed by @supermerill --- src/libslic3r/ShortestPath.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index 39b82f4ce..e9df4c5b5 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -1000,13 +1000,13 @@ std::vector> chain_extrusion_entities(std::vector const Point& { return first_point ? entities[idx]->first_point() : entities[idx]->last_point(); }; auto could_reverse = [&entities](size_t idx) { const ExtrusionEntity *ee = entities[idx]; return ee->is_loop() || ee->can_reverse(); }; std::vector> out = chain_segments_greedy_constrained_reversals(segment_end_point, could_reverse, entities.size(), start_near); - for (size_t i = 0; i < entities.size(); ++ i) { - ExtrusionEntity *ee = entities[i]; + for (std::pair &segment : out) { + ExtrusionEntity *ee = entities[segment.first]; if (ee->is_loop()) // Ignore reversals for loops, as the start point equals the end point. - out[i].second = false; + segment.second = false; // Is can_reverse() respected by the reversals? - assert(entities[i]->can_reverse() || ! out[i].second); + assert(ee->can_reverse() || ! segment.second); } return out; } From c3214e9f8656bf4e1cc4ab53b04a75352b2bf78c Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Dec 2019 13:05:18 +0100 Subject: [PATCH 10/10] Fix CGAL config script being non-relocatable --- deps/CGAL/CGAL.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/deps/CGAL/CGAL.cmake b/deps/CGAL/CGAL.cmake index 4b127cd51..96a629258 100644 --- a/deps/CGAL/CGAL.cmake +++ b/deps/CGAL/CGAL.cmake @@ -6,4 +6,10 @@ prusaslicer_add_cmake_project( # URL https://github.com/CGAL/cgal/archive/releases/CGAL-5.0.zip # URL_HASH SHA256=bd9327be903ab7ee379a8a7a0609eba0962f5078d2497cf8e13e8e1598584154 DEPENDS dep_boost dep_GMP dep_MPFR +) + +ExternalProject_Add_Step(dep_CGAL dep_CGAL_relocation_fix + DEPENDEES install + COMMAND ${CMAKE_COMMAND} -E remove CGALConfig-installation-dirs.cmake + WORKING_DIRECTORY "${DESTDIR}/usr/local/lib/cmake/CGAL" ) \ No newline at end of file