mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
		
						commit
						debbca0f14
					
				
					 23 changed files with 219 additions and 109 deletions
				
			
		| 
						 | 
					@ -46,7 +46,18 @@ endif()
 | 
				
			||||||
add_subdirectory(libslic3r)
 | 
					add_subdirectory(libslic3r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (SLIC3R_GUI)
 | 
					if (SLIC3R_GUI)
 | 
				
			||||||
    message(STATUS "WXWIN environment set to: $ENV{WXWIN}")
 | 
					    if(WIN32)
 | 
				
			||||||
 | 
					        message(STATUS "WXWIN environment set to: $ENV{WXWIN}")
 | 
				
			||||||
 | 
					    elseif(UNIX)
 | 
				
			||||||
 | 
					        message(STATUS "wx-config path: ${wxWidgets_CONFIG_EXECUTABLE}")
 | 
				
			||||||
 | 
					        set(wxWidgets_USE_UNICODE ON)
 | 
				
			||||||
 | 
					        if(SLIC3R_STATIC)
 | 
				
			||||||
 | 
					            set(wxWidgets_USE_STATIC ON)
 | 
				
			||||||
 | 
					        else()
 | 
				
			||||||
 | 
					            set(wxWidgets_USE_STATIC OFF)
 | 
				
			||||||
 | 
					        endif()
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    find_package(wxWidgets REQUIRED COMPONENTS base core adv html gl)
 | 
					    find_package(wxWidgets REQUIRED COMPONENTS base core adv html gl)
 | 
				
			||||||
    include(${wxWidgets_USE_FILE})
 | 
					    include(${wxWidgets_USE_FILE})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ if(TBB_FOUND)
 | 
				
			||||||
       target_compile_definitions(libnest2d INTERFACE -D__TBB_NO_IMPLICIT_LINKAGE)
 | 
					       target_compile_definitions(libnest2d INTERFACE -D__TBB_NO_IMPLICIT_LINKAGE)
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
    # The Intel TBB library will use the std::exception_ptr feature of C++11.
 | 
					    # The Intel TBB library will use the std::exception_ptr feature of C++11.
 | 
				
			||||||
    target_compile_definitions(libnest2d INTERFACE -DTBB_USE_CAPTURED_EXCEPTION=1)
 | 
					    target_compile_definitions(libnest2d INTERFACE -DTBB_USE_CAPTURED_EXCEPTION=0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    target_link_libraries(libnest2d INTERFACE tbb)
 | 
					    target_link_libraries(libnest2d INTERFACE tbb)
 | 
				
			||||||
else()
 | 
					else()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -505,8 +505,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
 | 
				
			||||||
		  .speed_override(100);
 | 
							  .speed_override(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	writer.set_initial_position(xy(0.f, 0.f))	// Always move to the starting position
 | 
						writer.set_initial_position(xy(0.f, 0.f))	// Always move to the starting position
 | 
				
			||||||
		.travel(cleaning_box.ld, 7200)
 | 
							.travel(cleaning_box.ld, 7200);
 | 
				
			||||||
		.set_extruder_trimpot(750); 			// Increase the extruder driver current to allow fast ramming.
 | 
						if (m_set_extruder_trimpot)
 | 
				
			||||||
 | 
							writer.set_extruder_trimpot(750); 			// Increase the extruder driver current to allow fast ramming.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
 | 
					    for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
 | 
				
			||||||
        unsigned int tool = tools[idx_tool];
 | 
					        unsigned int tool = tools[idx_tool];
 | 
				
			||||||
| 
						 | 
					@ -533,8 +534,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
 | 
				
			||||||
                            // in the output gcode - we should not remember emitting them (we will output them twice in the worst case)
 | 
					                            // in the output gcode - we should not remember emitting them (we will output them twice in the worst case)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Reset the extruder current to a normal value.
 | 
						// Reset the extruder current to a normal value.
 | 
				
			||||||
	writer.set_extruder_trimpot(550)
 | 
						if (m_set_extruder_trimpot)
 | 
				
			||||||
		  .feedrate(6000)
 | 
							writer.set_extruder_trimpot(550);
 | 
				
			||||||
 | 
						writer.feedrate(6000)
 | 
				
			||||||
		  .flush_planner_queue()
 | 
							  .flush_planner_queue()
 | 
				
			||||||
		  .reset_extruder()
 | 
							  .reset_extruder()
 | 
				
			||||||
		  .append("; CP PRIMING END\n"
 | 
							  .append("; CP PRIMING END\n"
 | 
				
			||||||
| 
						 | 
					@ -607,7 +609,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
 | 
				
			||||||
    writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
 | 
					    writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Increase the extruder driver current to allow fast ramming.
 | 
					    // Increase the extruder driver current to allow fast ramming.
 | 
				
			||||||
    writer.set_extruder_trimpot(750);
 | 
						if (m_set_extruder_trimpot)
 | 
				
			||||||
 | 
							writer.set_extruder_trimpot(550);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
 | 
					    // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
 | 
				
			||||||
    if (tool != (unsigned int)-1){ 			// This is not the last change.
 | 
					    if (tool != (unsigned int)-1){ 			// This is not the last change.
 | 
				
			||||||
| 
						 | 
					@ -635,8 +638,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    writer.set_extruder_trimpot(550)    // Reset the extruder current to a normal value.
 | 
						if (m_set_extruder_trimpot)
 | 
				
			||||||
          .feedrate(6000)
 | 
							writer.set_extruder_trimpot(550);    // Reset the extruder current to a normal value.
 | 
				
			||||||
 | 
					    writer.feedrate(6000)
 | 
				
			||||||
          .flush_planner_queue()
 | 
					          .flush_planner_queue()
 | 
				
			||||||
          .reset_extruder()
 | 
					          .reset_extruder()
 | 
				
			||||||
          .append("; CP TOOLCHANGE END\n"
 | 
					          .append("; CP TOOLCHANGE END\n"
 | 
				
			||||||
| 
						 | 
					@ -916,12 +920,10 @@ void WipeTowerPrusaMM::toolchange_Load(
 | 
				
			||||||
		  .resume_preview();
 | 
							  .resume_preview();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Reset the extruder current to the normal value.
 | 
						// Reset the extruder current to the normal value.
 | 
				
			||||||
	writer.set_extruder_trimpot(550);
 | 
						if (m_set_extruder_trimpot)
 | 
				
			||||||
 | 
							writer.set_extruder_trimpot(550);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Wipe the newly loaded filament until the end of the assigned wipe area.
 | 
					// Wipe the newly loaded filament until the end of the assigned wipe area.
 | 
				
			||||||
void WipeTowerPrusaMM::toolchange_Wipe(
 | 
					void WipeTowerPrusaMM::toolchange_Wipe(
 | 
				
			||||||
	PrusaMultiMaterial::Writer &writer,
 | 
						PrusaMultiMaterial::Writer &writer,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,8 @@ public:
 | 
				
			||||||
	// width		-- width of wipe tower in mm ( default 60 mm - leave as it is )
 | 
						// width		-- width of wipe tower in mm ( default 60 mm - leave as it is )
 | 
				
			||||||
	// wipe_area	-- space available for one toolchange in mm
 | 
						// wipe_area	-- space available for one toolchange in mm
 | 
				
			||||||
	WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
 | 
						WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
 | 
				
			||||||
                     float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, float bridging,
 | 
					                     float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, 
 | 
				
			||||||
 | 
					                     float bridging, bool set_extruder_trimpot,
 | 
				
			||||||
                     const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
 | 
					                     const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
 | 
				
			||||||
    m_wipe_tower_pos(x, y),
 | 
					    m_wipe_tower_pos(x, y),
 | 
				
			||||||
		m_wipe_tower_width(width),
 | 
							m_wipe_tower_width(width),
 | 
				
			||||||
| 
						 | 
					@ -57,6 +58,7 @@ public:
 | 
				
			||||||
        m_parking_pos_retraction(parking_pos_retraction),
 | 
					        m_parking_pos_retraction(parking_pos_retraction),
 | 
				
			||||||
        m_extra_loading_move(extra_loading_move),
 | 
					        m_extra_loading_move(extra_loading_move),
 | 
				
			||||||
		m_bridging(bridging),
 | 
							m_bridging(bridging),
 | 
				
			||||||
 | 
							m_set_extruder_trimpot(set_extruder_trimpot),
 | 
				
			||||||
        m_current_tool(initial_tool),
 | 
					        m_current_tool(initial_tool),
 | 
				
			||||||
        wipe_volumes(wiping_matrix)
 | 
					        wipe_volumes(wiping_matrix)
 | 
				
			||||||
        {}
 | 
					        {}
 | 
				
			||||||
| 
						 | 
					@ -212,6 +214,7 @@ private:
 | 
				
			||||||
    float           m_parking_pos_retraction    = 0.f;
 | 
					    float           m_parking_pos_retraction    = 0.f;
 | 
				
			||||||
    float           m_extra_loading_move        = 0.f;
 | 
					    float           m_extra_loading_move        = 0.f;
 | 
				
			||||||
    float           m_bridging                  = 0.f;
 | 
					    float           m_bridging                  = 0.f;
 | 
				
			||||||
 | 
					    bool            m_set_extruder_trimpot      = false;
 | 
				
			||||||
    bool            m_adhesion                  = true;
 | 
					    bool            m_adhesion                  = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
 | 
						float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,16 @@ Layer::~Layer()
 | 
				
			||||||
    m_regions.clear();
 | 
					    m_regions.clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Test whether whether there are any slices assigned to this layer.
 | 
				
			||||||
 | 
					bool Layer::empty() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (const LayerRegion *layerm : m_regions)
 | 
				
			||||||
 | 
					        if (layerm != nullptr && ! layerm->slices.empty())
 | 
				
			||||||
 | 
					            // Non empty layer.
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LayerRegion* Layer::add_region(PrintRegion* print_region)
 | 
					LayerRegion* Layer::add_region(PrintRegion* print_region)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    m_regions.emplace_back(new LayerRegion(this, print_region));
 | 
					    m_regions.emplace_back(new LayerRegion(this, print_region));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,8 @@ public:
 | 
				
			||||||
    LayerRegion*            get_region(int idx) { return m_regions[idx]; }
 | 
					    LayerRegion*            get_region(int idx) { return m_regions[idx]; }
 | 
				
			||||||
    LayerRegion*            add_region(PrintRegion* print_region);
 | 
					    LayerRegion*            add_region(PrintRegion* print_region);
 | 
				
			||||||
    const LayerRegionPtrs&  regions() const { return m_regions; }
 | 
					    const LayerRegionPtrs&  regions() const { return m_regions; }
 | 
				
			||||||
    
 | 
					    // Test whether whether there are any slices assigned to this layer.
 | 
				
			||||||
 | 
					    bool                    empty() const;    
 | 
				
			||||||
    void                    make_slices();
 | 
					    void                    make_slices();
 | 
				
			||||||
    void                    merge_slices();
 | 
					    void                    merge_slices();
 | 
				
			||||||
    template <class T> bool any_internal_region_slice_contains(const T &item) const {
 | 
					    template <class T> bool any_internal_region_slice_contains(const T &item) const {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,23 +34,22 @@ bool Line::intersection_infinite(const Line &other, Point* point) const
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* distance to the closest point of line */
 | 
					// Distance to the closest point of line.
 | 
				
			||||||
double Line::distance_to(const Point &point) const
 | 
					double Line::distance_to_squared(const Point &point, const Point &a, const Point &b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const Line   &line = *this;
 | 
					    const Vec2d   v  = (b - a).cast<double>();
 | 
				
			||||||
    const Vec2d   v  = (line.b - line.a).cast<double>();
 | 
					    const Vec2d   va = (point  - a).cast<double>();
 | 
				
			||||||
    const Vec2d   va = (point  - line.a).cast<double>();
 | 
					 | 
				
			||||||
    const double  l2 = v.squaredNorm();  // avoid a sqrt
 | 
					    const double  l2 = v.squaredNorm();  // avoid a sqrt
 | 
				
			||||||
    if (l2 == 0.0) 
 | 
					    if (l2 == 0.0) 
 | 
				
			||||||
        // line.a == line.b case
 | 
					        // a == b case
 | 
				
			||||||
        return va.norm();
 | 
					        return va.squaredNorm();
 | 
				
			||||||
    // Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
 | 
					    // Consider the line extending the segment, parameterized as a + t (b - a).
 | 
				
			||||||
    // We find projection of this point onto the line. 
 | 
					    // We find projection of this point onto the line. 
 | 
				
			||||||
    // It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
 | 
					    // It falls where t = [(this-a) . (b-a)] / |b-a|^2
 | 
				
			||||||
    const double t = va.dot(v) / l2;
 | 
					    const double t = va.dot(v) / l2;
 | 
				
			||||||
    if (t < 0.0)      return va.norm();  // beyond the 'a' end of the segment
 | 
					    if (t < 0.0)      return va.squaredNorm();  // beyond the 'a' end of the segment
 | 
				
			||||||
    else if (t > 1.0) return (point - line.b).cast<double>().norm();  // beyond the 'b' end of the segment
 | 
					    else if (t > 1.0) return (point - b).cast<double>().squaredNorm();  // beyond the 'b' end of the segment
 | 
				
			||||||
    return (t * v - va).norm();
 | 
					    return (t * v - va).squaredNorm();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double Line::perp_distance_to(const Point &point) const
 | 
					double Line::perp_distance_to(const Point &point) const
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,8 @@ public:
 | 
				
			||||||
    Point  midpoint() const { return (this->a + this->b) / 2; }
 | 
					    Point  midpoint() const { return (this->a + this->b) / 2; }
 | 
				
			||||||
    bool   intersection_infinite(const Line &other, Point* point) const;
 | 
					    bool   intersection_infinite(const Line &other, Point* point) const;
 | 
				
			||||||
    bool   operator==(const Line &rhs) const { return this->a == rhs.a && this->b == rhs.b; }
 | 
					    bool   operator==(const Line &rhs) const { return this->a == rhs.a && this->b == rhs.b; }
 | 
				
			||||||
    double distance_to(const Point &point) const;
 | 
					    double distance_to_squared(const Point &point) const { return distance_to_squared(point, this->a, this->b); }
 | 
				
			||||||
 | 
					    double distance_to(const Point &point) const { return distance_to(point, this->a, this->b); }
 | 
				
			||||||
    double perp_distance_to(const Point &point) const;
 | 
					    double perp_distance_to(const Point &point) const;
 | 
				
			||||||
    bool   parallel_to(double angle) const;
 | 
					    bool   parallel_to(double angle) const;
 | 
				
			||||||
    bool   parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
 | 
					    bool   parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
 | 
				
			||||||
| 
						 | 
					@ -43,6 +44,9 @@ public:
 | 
				
			||||||
    bool   intersection(const Line& line, Point* intersection) const;
 | 
					    bool   intersection(const Line& line, Point* intersection) const;
 | 
				
			||||||
    double ccw(const Point& point) const { return point.ccw(*this); }
 | 
					    double ccw(const Point& point) const { return point.ccw(*this); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static double distance_to_squared(const Point &point, const Point &a, const Point &b);
 | 
				
			||||||
 | 
					    static double distance_to(const Point &point, const Point &a, const Point &b) { return sqrt(distance_to_squared(point, a, b)); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Point a;
 | 
					    Point a;
 | 
				
			||||||
    Point b;
 | 
					    Point b;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,45 +162,51 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
 | 
				
			||||||
    return found;
 | 
					    return found;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//FIXME This is very inefficient in term of memory use.
 | 
					std::vector<Point> MultiPoint::_douglas_peucker(const std::vector<Point>& pts, const double tolerance)
 | 
				
			||||||
// The recursive algorithm shall run in place, not allocating temporary data in each recursion.
 | 
					 | 
				
			||||||
Points
 | 
					 | 
				
			||||||
MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(points.size() >= 2);
 | 
					    std::vector<Point> result_pts;
 | 
				
			||||||
    Points results;
 | 
					    if (! pts.empty()) {
 | 
				
			||||||
    double dmax = 0;
 | 
					        const Point  *anchor      = &pts.front();
 | 
				
			||||||
    size_t index = 0;
 | 
					        size_t        anchor_idx  = 0;
 | 
				
			||||||
    Line full(points.front(), points.back());
 | 
					        const Point  *floater     = &pts.back();
 | 
				
			||||||
    for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
 | 
					        size_t        floater_idx = pts.size() - 1;
 | 
				
			||||||
        // we use shortest distance, not perpendicular distance
 | 
					        result_pts.reserve(pts.size());
 | 
				
			||||||
        double d = full.distance_to(*it);
 | 
					        result_pts.emplace_back(*anchor);
 | 
				
			||||||
        if (d > dmax) {
 | 
					        if (anchor_idx != floater_idx) {
 | 
				
			||||||
            index = it - points.begin();
 | 
					            assert(pts.size() > 1);
 | 
				
			||||||
            dmax = d;
 | 
					            std::vector<size_t> dpStack;
 | 
				
			||||||
 | 
					            dpStack.reserve(pts.size());
 | 
				
			||||||
 | 
					            dpStack.emplace_back(floater_idx);
 | 
				
			||||||
 | 
					            for (;;) {
 | 
				
			||||||
 | 
					                double max_distSq   = 0.0;
 | 
				
			||||||
 | 
					                size_t furthest_idx = anchor_idx;
 | 
				
			||||||
 | 
					                // find point furthest from line seg created by (anchor, floater) and note it
 | 
				
			||||||
 | 
					                for (size_t i = anchor_idx + 1; i < floater_idx; ++ i) {
 | 
				
			||||||
 | 
					                    double dist = Line::distance_to_squared(pts[i], *anchor, *floater);
 | 
				
			||||||
 | 
					                    if (dist > max_distSq) {
 | 
				
			||||||
 | 
					                        max_distSq   = dist;
 | 
				
			||||||
 | 
					                        furthest_idx = i;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // remove point if less than tolerance
 | 
				
			||||||
 | 
					                if (max_distSq <= tolerance) {
 | 
				
			||||||
 | 
					                    result_pts.emplace_back(*floater);
 | 
				
			||||||
 | 
					                    anchor_idx = floater_idx;
 | 
				
			||||||
 | 
					                    anchor     = floater;
 | 
				
			||||||
 | 
					                    assert(dpStack.back() == floater_idx);
 | 
				
			||||||
 | 
					                    dpStack.pop_back();
 | 
				
			||||||
 | 
					                    if (dpStack.empty())
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    floater_idx = dpStack.back();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    floater_idx = furthest_idx;
 | 
				
			||||||
 | 
					                    dpStack.emplace_back(floater_idx);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                floater = &pts[floater_idx];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (dmax >= tolerance) {
 | 
					    return result_pts;
 | 
				
			||||||
        Points dp0;
 | 
					 | 
				
			||||||
        dp0.reserve(index + 1);
 | 
					 | 
				
			||||||
        dp0.insert(dp0.end(), points.begin(), points.begin() + index + 1);
 | 
					 | 
				
			||||||
        // Recursive call.
 | 
					 | 
				
			||||||
        Points dp1 = MultiPoint::_douglas_peucker(dp0, tolerance);
 | 
					 | 
				
			||||||
        results.reserve(results.size() + dp1.size() - 1);
 | 
					 | 
				
			||||||
        results.insert(results.end(), dp1.begin(), dp1.end() - 1);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        dp0.clear();
 | 
					 | 
				
			||||||
        dp0.reserve(points.size() - index);
 | 
					 | 
				
			||||||
        dp0.insert(dp0.end(), points.begin() + index, points.end());
 | 
					 | 
				
			||||||
        // Recursive call.
 | 
					 | 
				
			||||||
        dp1 = MultiPoint::_douglas_peucker(dp0, tolerance);
 | 
					 | 
				
			||||||
        results.reserve(results.size() + dp1.size());
 | 
					 | 
				
			||||||
        results.insert(results.end(), dp1.begin(), dp1.end());
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        results.push_back(points.front());
 | 
					 | 
				
			||||||
        results.push_back(points.back());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return results;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Visivalingam simplification algorithm https://github.com/slic3r/Slic3r/pull/3825
 | 
					// Visivalingam simplification algorithm https://github.com/slic3r/Slic3r/pull/3825
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,6 +213,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
 | 
				
			||||||
            || opt_key == "filament_cooling_final_speed"
 | 
					            || opt_key == "filament_cooling_final_speed"
 | 
				
			||||||
            || opt_key == "filament_ramming_parameters"
 | 
					            || opt_key == "filament_ramming_parameters"
 | 
				
			||||||
            || opt_key == "gcode_flavor"
 | 
					            || opt_key == "gcode_flavor"
 | 
				
			||||||
 | 
					            || opt_key == "high_current_on_filament_swap"
 | 
				
			||||||
            || opt_key == "infill_first"
 | 
					            || opt_key == "infill_first"
 | 
				
			||||||
            || opt_key == "single_extruder_multi_material"
 | 
					            || opt_key == "single_extruder_multi_material"
 | 
				
			||||||
            || opt_key == "spiral_vase"
 | 
					            || opt_key == "spiral_vase"
 | 
				
			||||||
| 
						 | 
					@ -1768,7 +1769,8 @@ void Print::_make_wipe_tower()
 | 
				
			||||||
        float(m_config.wipe_tower_width.value),
 | 
					        float(m_config.wipe_tower_width.value),
 | 
				
			||||||
        float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value),
 | 
					        float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value),
 | 
				
			||||||
        float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
 | 
					        float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
 | 
				
			||||||
        float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging), wipe_volumes,
 | 
					        float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging), 
 | 
				
			||||||
 | 
					        m_config.high_current_on_filament_swap.value, wipe_volumes,
 | 
				
			||||||
        m_wipe_tower_data.tool_ordering.first_extruder());
 | 
					        m_wipe_tower_data.tool_ordering.first_extruder());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //wipe_tower.set_retract();
 | 
					    //wipe_tower.set_retract();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -925,6 +925,15 @@ void PrintConfigDef::init_fff_params()
 | 
				
			||||||
    def->mode = comExpert;
 | 
					    def->mode = comExpert;
 | 
				
			||||||
    def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
 | 
					    def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def = this->add("high_current_on_filament_swap", coBool);
 | 
				
			||||||
 | 
					    def->label = L("High extruder current on filament swap");
 | 
				
			||||||
 | 
					    def->tooltip = L("It may be beneficial to increase the extruder motor current during the filament exchange"
 | 
				
			||||||
 | 
					                   " sequence to allow for rapid ramming feed rates and to overcome resistance when loading"
 | 
				
			||||||
 | 
					                   " a filament with an ugly shaped tip.");
 | 
				
			||||||
 | 
					    def->cli = "high-current-on-filament-swap!";
 | 
				
			||||||
 | 
					    def->mode = comExpert;
 | 
				
			||||||
 | 
					    def->default_value = new ConfigOptionBool(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def = this->add("infill_acceleration", coFloat);
 | 
					    def = this->add("infill_acceleration", coFloat);
 | 
				
			||||||
    def->label = L("Infill");
 | 
					    def->label = L("Infill");
 | 
				
			||||||
    def->tooltip = L("This is the acceleration your printer will use for infill. Set zero to disable "
 | 
					    def->tooltip = L("This is the acceleration your printer will use for infill. Set zero to disable "
 | 
				
			||||||
| 
						 | 
					@ -2394,8 +2403,10 @@ void PrintConfigDef::init_sla_params()
 | 
				
			||||||
    def->tooltip = L("Display orientation");
 | 
					    def->tooltip = L("Display orientation");
 | 
				
			||||||
    def->cli = "display-orientation=s";
 | 
					    def->cli = "display-orientation=s";
 | 
				
			||||||
    def->enum_keys_map = &ConfigOptionEnum<SLADisplayOrientation>::get_enum_values();
 | 
					    def->enum_keys_map = &ConfigOptionEnum<SLADisplayOrientation>::get_enum_values();
 | 
				
			||||||
    def->enum_values.push_back("Landscape");
 | 
					    def->enum_values.push_back("landscape");
 | 
				
			||||||
    def->enum_values.push_back("Portrait");
 | 
					    def->enum_values.push_back("portrait");
 | 
				
			||||||
 | 
					    def->enum_labels.push_back(L("Landscape"));
 | 
				
			||||||
 | 
					    def->enum_labels.push_back(L("Portrait"));
 | 
				
			||||||
    def->default_value = new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait);
 | 
					    def->default_value = new ConfigOptionEnum<SLADisplayOrientation>(sladoPortrait);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def = this->add("printer_correction", coFloats);
 | 
					    def = this->add("printer_correction", coFloats);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,8 +155,8 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<FilamentType>::ge
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<> inline const t_config_enum_values& ConfigOptionEnum<SLADisplayOrientation>::get_enum_values() {
 | 
					template<> inline const t_config_enum_values& ConfigOptionEnum<SLADisplayOrientation>::get_enum_values() {
 | 
				
			||||||
    static const t_config_enum_values keys_map = {
 | 
					    static const t_config_enum_values keys_map = {
 | 
				
			||||||
        { "Landscape", sladoLandscape},
 | 
					        { "landscape", sladoLandscape},
 | 
				
			||||||
        { "Portrait",  sladoPortrait}
 | 
					        { "portrait",  sladoPortrait}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return keys_map;
 | 
					    return keys_map;
 | 
				
			||||||
| 
						 | 
					@ -627,6 +627,7 @@ public:
 | 
				
			||||||
    ConfigOptionBool                variable_layer_height;
 | 
					    ConfigOptionBool                variable_layer_height;
 | 
				
			||||||
    ConfigOptionFloat               cooling_tube_retraction;
 | 
					    ConfigOptionFloat               cooling_tube_retraction;
 | 
				
			||||||
    ConfigOptionFloat               cooling_tube_length;
 | 
					    ConfigOptionFloat               cooling_tube_length;
 | 
				
			||||||
 | 
					    ConfigOptionBool                high_current_on_filament_swap;
 | 
				
			||||||
    ConfigOptionFloat               parking_pos_retraction;
 | 
					    ConfigOptionFloat               parking_pos_retraction;
 | 
				
			||||||
    ConfigOptionBool                remaining_times;
 | 
					    ConfigOptionBool                remaining_times;
 | 
				
			||||||
    ConfigOptionBool                silent_mode;
 | 
					    ConfigOptionBool                silent_mode;
 | 
				
			||||||
| 
						 | 
					@ -695,6 +696,7 @@ protected:
 | 
				
			||||||
        OPT_PTR(variable_layer_height);
 | 
					        OPT_PTR(variable_layer_height);
 | 
				
			||||||
        OPT_PTR(cooling_tube_retraction);
 | 
					        OPT_PTR(cooling_tube_retraction);
 | 
				
			||||||
        OPT_PTR(cooling_tube_length);
 | 
					        OPT_PTR(cooling_tube_length);
 | 
				
			||||||
 | 
					        OPT_PTR(high_current_on_filament_swap);
 | 
				
			||||||
        OPT_PTR(parking_pos_retraction);
 | 
					        OPT_PTR(parking_pos_retraction);
 | 
				
			||||||
        OPT_PTR(remaining_times);
 | 
					        OPT_PTR(remaining_times);
 | 
				
			||||||
        OPT_PTR(silent_mode);
 | 
					        OPT_PTR(silent_mode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -384,6 +384,14 @@ void PrintObject::generate_support_material()
 | 
				
			||||||
            m_print->set_status(85, "Generating support material");    
 | 
					            m_print->set_status(85, "Generating support material");    
 | 
				
			||||||
            this->_generate_support_material();
 | 
					            this->_generate_support_material();
 | 
				
			||||||
            m_print->throw_if_canceled();
 | 
					            m_print->throw_if_canceled();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					            // Printing without supports. Empty layer means some objects or object parts are levitating,
 | 
				
			||||||
 | 
					            // therefore they cannot be printed without supports.
 | 
				
			||||||
 | 
					            for (const Layer *layer : m_layers)
 | 
				
			||||||
 | 
					                if (layer->empty())
 | 
				
			||||||
 | 
					                    throw std::runtime_error("Levitating objects cannot be printed without supports.");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this->set_done(posSupportMaterial);
 | 
					        this->set_done(posSupportMaterial);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -522,11 +530,13 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
 | 
				
			||||||
            || opt_key == "perimeter_speed"
 | 
					            || opt_key == "perimeter_speed"
 | 
				
			||||||
            || opt_key == "small_perimeter_speed"
 | 
					            || opt_key == "small_perimeter_speed"
 | 
				
			||||||
            || opt_key == "solid_infill_speed"
 | 
					            || opt_key == "solid_infill_speed"
 | 
				
			||||||
            || opt_key == "top_solid_infill_speed"
 | 
					            || opt_key == "top_solid_infill_speed") {
 | 
				
			||||||
            || opt_key == "wipe_into_infill"    // when these these two are changed, we only need to invalidate the wipe tower,
 | 
					            invalidated |= m_print->invalidate_step(psGCodeExport);
 | 
				
			||||||
            || opt_key == "wipe_into_objects"   // which we already did at the very beginning - nothing more to be done
 | 
					        } else if (
 | 
				
			||||||
            ) {
 | 
					               opt_key == "wipe_into_infill"
 | 
				
			||||||
            // these options only affect G-code export, so nothing to invalidate
 | 
					            || opt_key == "wipe_into_objects") {
 | 
				
			||||||
 | 
					            invalidated |= m_print->invalidate_step(psWipeTower);
 | 
				
			||||||
 | 
					            invalidated |= m_print->invalidate_step(psGCodeExport);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // for legacy, if we can't handle this option let's invalidate all steps
 | 
					            // for legacy, if we can't handle this option let's invalidate all steps
 | 
				
			||||||
            this->invalidate_all_steps();
 | 
					            this->invalidate_all_steps();
 | 
				
			||||||
| 
						 | 
					@ -1463,10 +1473,8 @@ void PrintObject::_slice()
 | 
				
			||||||
    BOOST_LOG_TRIVIAL(debug) << "Slicing objects - removing top empty layers";
 | 
					    BOOST_LOG_TRIVIAL(debug) << "Slicing objects - removing top empty layers";
 | 
				
			||||||
    while (! m_layers.empty()) {
 | 
					    while (! m_layers.empty()) {
 | 
				
			||||||
        const Layer *layer = m_layers.back();
 | 
					        const Layer *layer = m_layers.back();
 | 
				
			||||||
        for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
 | 
					        if (! layer->empty())
 | 
				
			||||||
            if (layer->m_regions[region_id] != nullptr && ! layer->m_regions[region_id]->slices.empty())
 | 
					            goto end;
 | 
				
			||||||
                // Non empty layer.
 | 
					 | 
				
			||||||
                goto end;
 | 
					 | 
				
			||||||
        delete layer;
 | 
					        delete layer;
 | 
				
			||||||
        m_layers.pop_back();
 | 
					        m_layers.pop_back();
 | 
				
			||||||
		if (! m_layers.empty())
 | 
							if (! m_layers.empty())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -420,6 +420,12 @@ void swapXY(ExPolygon& expoly) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class...Args>
 | 
				
			||||||
 | 
					void report_status(SLAPrint& p, int st, const std::string& msg, Args&&...args) {
 | 
				
			||||||
 | 
					    BOOST_LOG_TRIVIAL(info) << st << "% " << msg;
 | 
				
			||||||
 | 
					    p.set_status(st, msg, std::forward<Args>(args)...);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SLAPrint::process()
 | 
					void SLAPrint::process()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using namespace sla;
 | 
					    using namespace sla;
 | 
				
			||||||
| 
						 | 
					@ -525,9 +531,11 @@ void SLAPrint::process()
 | 
				
			||||||
            // scaling for the sub operations
 | 
					            // scaling for the sub operations
 | 
				
			||||||
            double d = *stthis / (objcount * 100.0);
 | 
					            double d = *stthis / (objcount * 100.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ctl.statuscb = [this, init, d](unsigned st, const std::string& msg){
 | 
					            ctl.statuscb = [this, init, d](unsigned st, const std::string& msg)
 | 
				
			||||||
                set_status(int(init + st*d), msg);
 | 
					            {
 | 
				
			||||||
 | 
					                report_status(*this, int(init + st*d), msg);
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ctl.stopcondition = [this](){ return canceled(); };
 | 
					            ctl.stopcondition = [this](){ return canceled(); };
 | 
				
			||||||
            ctl.cancelfn = [this]() { throw_if_canceled(); };
 | 
					            ctl.cancelfn = [this]() { throw_if_canceled(); };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -537,9 +545,9 @@ void SLAPrint::process()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Create the unified mesh
 | 
					            // Create the unified mesh
 | 
				
			||||||
            auto rc = SlicingStatus::RELOAD_SCENE;
 | 
					            auto rc = SlicingStatus::RELOAD_SCENE;
 | 
				
			||||||
            set_status(-1, L("Visualizing supports"));
 | 
					            report_status(*this, -1, L("Visualizing supports"));
 | 
				
			||||||
            po.m_supportdata->support_tree_ptr->merged_mesh();
 | 
					            po.m_supportdata->support_tree_ptr->merged_mesh();
 | 
				
			||||||
            set_status(-1, L("Visualizing supports"), rc);
 | 
					            report_status(*this, -1, L("Visualizing supports"), rc);
 | 
				
			||||||
        } catch(sla::SLASupportsStoppedException&) {
 | 
					        } catch(sla::SLASupportsStoppedException&) {
 | 
				
			||||||
            // no need to rethrow
 | 
					            // no need to rethrow
 | 
				
			||||||
            // throw_if_canceled();
 | 
					            // throw_if_canceled();
 | 
				
			||||||
| 
						 | 
					@ -582,7 +590,7 @@ void SLAPrint::process()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        po.throw_if_canceled();
 | 
					        po.throw_if_canceled();
 | 
				
			||||||
        auto rc = SlicingStatus::RELOAD_SCENE;
 | 
					        auto rc = SlicingStatus::RELOAD_SCENE;
 | 
				
			||||||
        set_status(-1, L("Visualizing supports"), rc);
 | 
					        report_status(*this, -1, L("Visualizing supports"), rc);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Slicing the support geometries similarly to the model slicing procedure.
 | 
					    // Slicing the support geometries similarly to the model slicing procedure.
 | 
				
			||||||
| 
						 | 
					@ -741,8 +749,12 @@ void SLAPrint::process()
 | 
				
			||||||
        auto lvlcnt = unsigned(m_printer_input.size());
 | 
					        auto lvlcnt = unsigned(m_printer_input.size());
 | 
				
			||||||
        printer.layers(lvlcnt);
 | 
					        printer.layers(lvlcnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // slot is the portion of 100% that is realted to rasterization
 | 
				
			||||||
        unsigned slot = PRINT_STEP_LEVELS[slapsRasterize];
 | 
					        unsigned slot = PRINT_STEP_LEVELS[slapsRasterize];
 | 
				
			||||||
 | 
					        // ist: initial state; pst: previous state
 | 
				
			||||||
        unsigned ist = max_objstatus, pst = ist;
 | 
					        unsigned ist = max_objstatus, pst = ist;
 | 
				
			||||||
 | 
					        // coefficient to map the rasterization state (0-99) to the allocated
 | 
				
			||||||
 | 
					        // portion (slot) of the process state
 | 
				
			||||||
        double sd = (100 - ist) / 100.0;
 | 
					        double sd = (100 - ist) / 100.0;
 | 
				
			||||||
        SpinMutex slck;
 | 
					        SpinMutex slck;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -779,11 +791,11 @@ void SLAPrint::process()
 | 
				
			||||||
            // Finish the layer for later saving it.
 | 
					            // Finish the layer for later saving it.
 | 
				
			||||||
            printer.finish_layer(level_id);
 | 
					            printer.finish_layer(level_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Status indication
 | 
					            // Status indication guarded with the spinlock
 | 
				
			||||||
            auto st = ist + unsigned(sd*level_id*slot/m_printer_input.size());
 | 
					            auto st = ist + unsigned(sd*level_id*slot/m_printer_input.size());
 | 
				
			||||||
            { std::lock_guard<SpinMutex> lck(slck);
 | 
					            { std::lock_guard<SpinMutex> lck(slck);
 | 
				
			||||||
            if( st > pst) {
 | 
					            if( st > pst) {
 | 
				
			||||||
                set_status(int(st), PRINT_STEP_LABELS[slapsRasterize]);
 | 
					                report_status(*this, int(st), PRINT_STEP_LABELS[slapsRasterize]);
 | 
				
			||||||
                pst = st;
 | 
					                pst = st;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -833,9 +845,14 @@ void SLAPrint::process()
 | 
				
			||||||
    unsigned st = min_objstatus;
 | 
					    unsigned st = min_objstatus;
 | 
				
			||||||
    unsigned incr = 0;
 | 
					    unsigned incr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BOOST_LOG_TRIVIAL(info) << "Start slicing process.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: this loop could run in parallel but should not exhaust all the CPU
 | 
					    // TODO: this loop could run in parallel but should not exhaust all the CPU
 | 
				
			||||||
    // power available
 | 
					    // power available
 | 
				
			||||||
    for(SLAPrintObject * po : m_objects) {
 | 
					    for(SLAPrintObject * po : m_objects) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        BOOST_LOG_TRIVIAL(info) << "Slicing object " << po->model_object()->name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(size_t s = 0; s < objectsteps.size(); ++s) {
 | 
					        for(size_t s = 0; s < objectsteps.size(); ++s) {
 | 
				
			||||||
            auto currentstep = objectsteps[s];
 | 
					            auto currentstep = objectsteps[s];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -847,8 +864,7 @@ void SLAPrint::process()
 | 
				
			||||||
            st += unsigned(incr * ostepd);
 | 
					            st += unsigned(incr * ostepd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(po->m_stepmask[currentstep] && po->set_started(currentstep)) {
 | 
					            if(po->m_stepmask[currentstep] && po->set_started(currentstep)) {
 | 
				
			||||||
 | 
					                report_status(*this, int(st), OBJ_STEP_LABELS[currentstep]);
 | 
				
			||||||
                set_status(int(st), OBJ_STEP_LABELS[currentstep]);
 | 
					 | 
				
			||||||
                pobj_program[currentstep](*po);
 | 
					                pobj_program[currentstep](*po);
 | 
				
			||||||
                po->set_done(currentstep);
 | 
					                po->set_done(currentstep);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -873,7 +889,7 @@ void SLAPrint::process()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(m_stepmask[currentstep] && set_started(currentstep))
 | 
					        if(m_stepmask[currentstep] && set_started(currentstep))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            set_status(int(st), PRINT_STEP_LABELS[currentstep]);
 | 
					            report_status(*this, int(st), PRINT_STEP_LABELS[currentstep]);
 | 
				
			||||||
            print_program[currentstep]();
 | 
					            print_program[currentstep]();
 | 
				
			||||||
            set_done(currentstep);
 | 
					            set_done(currentstep);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -882,7 +898,7 @@ void SLAPrint::process()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If everything vent well
 | 
					    // If everything vent well
 | 
				
			||||||
    set_status(100, L("Slicing done"));
 | 
					    report_status(*this, 100, L("Slicing done"));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys)
 | 
					bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -638,6 +638,8 @@ boost::any& Choice::get_value()
 | 
				
			||||||
			m_value = static_cast<SeamPosition>(ret_enum);
 | 
								m_value = static_cast<SeamPosition>(ret_enum);
 | 
				
			||||||
		else if (m_opt_id.compare("host_type") == 0)
 | 
							else if (m_opt_id.compare("host_type") == 0)
 | 
				
			||||||
			m_value = static_cast<PrintHostType>(ret_enum);
 | 
								m_value = static_cast<PrintHostType>(ret_enum);
 | 
				
			||||||
 | 
							else if (m_opt_id.compare("display_orientation") == 0)
 | 
				
			||||||
 | 
								m_value = static_cast<SLADisplayOrientation>(ret_enum);
 | 
				
			||||||
	}	
 | 
						}	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return m_value;
 | 
						return m_value;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +195,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
 | 
				
			||||||
				config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
 | 
									config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
 | 
				
			||||||
			else if (opt_key.compare("host_type") == 0)
 | 
								else if (opt_key.compare("host_type") == 0)
 | 
				
			||||||
				config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
 | 
									config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
 | 
				
			||||||
 | 
								else if (opt_key.compare("display_orientation") == 0)
 | 
				
			||||||
 | 
									config.set_key_value(opt_key, new ConfigOptionEnum<SLADisplayOrientation>(boost::any_cast<SLADisplayOrientation>(value)));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case coPoints:{
 | 
							case coPoints:{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1459,13 +1459,14 @@ void ObjectList::update_selections()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    select_items(sels);
 | 
					    select_items(sels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __WXMSW__
 | 
					 | 
				
			||||||
    if (GetSelection()) {
 | 
					    if (GetSelection()) {
 | 
				
			||||||
        const int sel_item_row = GetRowByItem(GetSelection());
 | 
					        const wxRect& sel_rc = GetItemRect(GetSelection());
 | 
				
			||||||
        ScrollLines(sel_item_row - m_selected_row);
 | 
					        if (!sel_rc.IsEmpty()) {
 | 
				
			||||||
        m_selected_row = sel_item_row;
 | 
					            const int rc_h = sel_rc.height;
 | 
				
			||||||
 | 
					            const int displ = GetMainWindow()->GetClientRect().GetHeight()/(2*rc_h)+1;
 | 
				
			||||||
 | 
					            ScrollLines(int(sel_rc.y / rc_h - displ));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif //__WXMSW__
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ObjectList::update_selections_on_canvas()
 | 
					void ObjectList::update_selections_on_canvas()
 | 
				
			||||||
| 
						 | 
					@ -1656,7 +1657,9 @@ void ObjectList::change_part_type()
 | 
				
			||||||
void ObjectList::last_volume_is_deleted(const int obj_idx)
 | 
					void ObjectList::last_volume_is_deleted(const int obj_idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (obj_idx < 0 || (*m_objects).empty() || (*m_objects)[obj_idx]->volumes.empty())
 | 
					    if (obj_idx < 0 || m_objects->empty() ||
 | 
				
			||||||
 | 
					        obj_idx <= m_objects->size() ||
 | 
				
			||||||
 | 
					        (*m_objects)[obj_idx]->volumes.empty())
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    auto volume = (*m_objects)[obj_idx]->volumes[0];
 | 
					    auto volume = (*m_objects)[obj_idx]->volumes[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,8 +108,6 @@ class ObjectList : public wxDataViewCtrl
 | 
				
			||||||
    bool        m_parts_changed = false;
 | 
					    bool        m_parts_changed = false;
 | 
				
			||||||
    bool        m_part_settings_changed = false;
 | 
					    bool        m_part_settings_changed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int         m_selected_row = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    ObjectList(wxWindow* parent);
 | 
					    ObjectList(wxWindow* parent);
 | 
				
			||||||
    ~ObjectList();
 | 
					    ~ObjectList();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,7 +213,7 @@ void SlicedInfo::SetTextAndShow(SlisedInfoIdx idx, const wxString& text, const w
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
 | 
					PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
 | 
				
			||||||
    wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY),
 | 
					    wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1), 0, nullptr, wxCB_READONLY),
 | 
				
			||||||
    preset_type(preset_type),
 | 
					    preset_type(preset_type),
 | 
				
			||||||
    last_selected(wxNOT_FOUND)
 | 
					    last_selected(wxNOT_FOUND)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -366,7 +366,8 @@ const std::vector<std::string>& Preset::printer_options()
 | 
				
			||||||
            "host_type", "print_host", "printhost_apikey", "printhost_cafile",
 | 
					            "host_type", "print_host", "printhost_apikey", "printhost_cafile",
 | 
				
			||||||
            "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
 | 
					            "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
 | 
				
			||||||
            "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
 | 
					            "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
 | 
				
			||||||
            "cooling_tube_length", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits",
 | 
					            "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height", 
 | 
				
			||||||
 | 
					            "default_print_profile", "inherits",
 | 
				
			||||||
            "remaining_times", "silent_mode", "machine_max_acceleration_extruding", "machine_max_acceleration_retracting",
 | 
					            "remaining_times", "silent_mode", "machine_max_acceleration_extruding", "machine_max_acceleration_retracting",
 | 
				
			||||||
			"machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
 | 
								"machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
 | 
				
			||||||
        	"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
 | 
					        	"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2041,6 +2041,7 @@ void TabPrinter::build_extruder_pages()
 | 
				
			||||||
		optgroup->append_single_option_line("cooling_tube_length");
 | 
							optgroup->append_single_option_line("cooling_tube_length");
 | 
				
			||||||
		optgroup->append_single_option_line("parking_pos_retraction");
 | 
							optgroup->append_single_option_line("parking_pos_retraction");
 | 
				
			||||||
        optgroup->append_single_option_line("extra_loading_move");
 | 
					        optgroup->append_single_option_line("extra_loading_move");
 | 
				
			||||||
 | 
					        optgroup->append_single_option_line("high_current_on_filament_swap");
 | 
				
			||||||
		m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page);
 | 
							m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page);
 | 
				
			||||||
		m_has_single_extruder_MM_page = true;
 | 
							m_has_single_extruder_MM_page = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1228,6 +1228,14 @@ void PrusaObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const i
 | 
				
			||||||
    ItemChanged(item);
 | 
					    ItemChanged(item);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PrusaBitmapTextRenderer::PrusaBitmapTextRenderer(wxDataViewCellMode mode /*= wxDATAVIEW_CELL_EDITABLE*/, 
 | 
				
			||||||
 | 
					                                                 int align /*= wxDVR_DEFAULT_ALIGNMENT*/): 
 | 
				
			||||||
 | 
					wxDataViewRenderer(wxT("PrusaDataViewBitmapText"), mode, align)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SetMode(mode);
 | 
				
			||||||
 | 
					    SetAlignment(align);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
// PrusaDataViewBitmapText
 | 
					// PrusaDataViewBitmapText
 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					@ -1251,6 +1259,13 @@ bool PrusaBitmapTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if wxUSE_ACCESSIBILITY
 | 
				
			||||||
 | 
					wxString PrusaBitmapTextRenderer::GetAccessibleDescription() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return m_value.GetText();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif // wxUSE_ACCESSIBILITY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state)
 | 
					bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int xoffset = 0;
 | 
					    int xoffset = 0;
 | 
				
			||||||
| 
						 | 
					@ -1291,12 +1306,12 @@ wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect lab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PrusaDataViewBitmapText data;
 | 
					    PrusaDataViewBitmapText data;
 | 
				
			||||||
    data << value;
 | 
					    data << value;
 | 
				
			||||||
    m_bmp_from_editing_item = data.GetBitmap();
 | 
					
 | 
				
			||||||
    m_was_unusable_symbol = false;
 | 
					    m_was_unusable_symbol = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    wxPoint position = labelRect.GetPosition();
 | 
					    wxPoint position = labelRect.GetPosition();
 | 
				
			||||||
    if (m_bmp_from_editing_item.IsOk()) {
 | 
					    if (data.GetBitmap().IsOk()) {
 | 
				
			||||||
        const int bmp_width = m_bmp_from_editing_item.GetWidth();
 | 
					        const int bmp_width = data.GetBitmap().GetWidth();
 | 
				
			||||||
        position.x += bmp_width;
 | 
					        position.x += bmp_width;
 | 
				
			||||||
        labelRect.SetWidth(labelRect.GetWidth() - bmp_width);
 | 
					        labelRect.SetWidth(labelRect.GetWidth() - bmp_width);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -1304,6 +1319,7 @@ wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect lab
 | 
				
			||||||
    wxTextCtrl* text_editor = new wxTextCtrl(parent, wxID_ANY, data.GetText(),
 | 
					    wxTextCtrl* text_editor = new wxTextCtrl(parent, wxID_ANY, data.GetText(),
 | 
				
			||||||
                                             position, labelRect.GetSize(), wxTE_PROCESS_ENTER);
 | 
					                                             position, labelRect.GetSize(), wxTE_PROCESS_ENTER);
 | 
				
			||||||
    text_editor->SetInsertionPointEnd();
 | 
					    text_editor->SetInsertionPointEnd();
 | 
				
			||||||
 | 
					    text_editor->SelectAll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return text_editor;
 | 
					    return text_editor;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1323,7 +1339,17 @@ bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant&
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    value << PrusaDataViewBitmapText(text_editor->GetValue(), m_bmp_from_editing_item);
 | 
					    // The icon can't be edited so get its old value and reuse it.
 | 
				
			||||||
 | 
					    wxVariant valueOld;
 | 
				
			||||||
 | 
					    GetView()->GetModel()->GetValue(valueOld, m_item, 0); 
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    PrusaDataViewBitmapText bmpText;
 | 
				
			||||||
 | 
					    bmpText << valueOld;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // But replace the text with the value entered by user.
 | 
				
			||||||
 | 
					    bmpText.SetText(text_editor->GetValue());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value << bmpText;
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -519,15 +519,18 @@ public:
 | 
				
			||||||
// PrusaBitmapTextRenderer
 | 
					// PrusaBitmapTextRenderer
 | 
				
			||||||
// ----------------------------------------------------------------------------
 | 
					// ----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer
 | 
					class PrusaBitmapTextRenderer : public wxDataViewRenderer//CustomRenderer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    PrusaBitmapTextRenderer(  wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE,
 | 
					    PrusaBitmapTextRenderer(wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE,
 | 
				
			||||||
                            int align = wxDVR_DEFAULT_ALIGNMENT): 
 | 
					                            int align = wxDVR_DEFAULT_ALIGNMENT);//: 
 | 
				
			||||||
                            wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {}
 | 
					//                             wxDataViewRenderer/*CustomRenderer*/(wxT("PrusaDataViewBitmapText"), mode, align) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool SetValue(const wxVariant &value);
 | 
					    bool SetValue(const wxVariant &value);
 | 
				
			||||||
    bool GetValue(wxVariant &value) const;
 | 
					    bool GetValue(wxVariant &value) const;
 | 
				
			||||||
 | 
					#if wxUSE_ACCESSIBILITY
 | 
				
			||||||
 | 
					    virtual wxString GetAccessibleDescription() const override;
 | 
				
			||||||
 | 
					#endif // wxUSE_ACCESSIBILITY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual bool Render(wxRect cell, wxDC *dc, int state);
 | 
					    virtual bool Render(wxRect cell, wxDC *dc, int state);
 | 
				
			||||||
    virtual wxSize GetSize() const;
 | 
					    virtual wxSize GetSize() const;
 | 
				
			||||||
| 
						 | 
					@ -542,8 +545,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    PrusaDataViewBitmapText m_value;
 | 
					    PrusaDataViewBitmapText m_value;
 | 
				
			||||||
    wxBitmap                m_bmp_from_editing_item;
 | 
					    bool                    m_was_unusable_symbol {false};
 | 
				
			||||||
    bool                    m_was_unusable_symbol;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue