Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Flow.hpp « libslic3r « src - github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4be0ea8a061fb267d4e17876804388caa039e17f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef slic3r_Flow_hpp_
#define slic3r_Flow_hpp_

#include "libslic3r.h"
#include "Config.hpp"
#include "Exception.hpp"
#include "ExtrusionEntity.hpp"

namespace Slic3r {

class PrintObject;

enum FlowRole {
    frExternalPerimeter,
    frPerimeter,
    frInfill,
    frSolidInfill,
    frTopSolidInfill,
    frSupportMaterial,
    frSupportMaterialInterface,
};

class FlowError : public Slic3r::InvalidArgument
{
public:
	FlowError(const std::string& what_arg) : Slic3r::InvalidArgument(what_arg) {}
	FlowError(const char* what_arg) : Slic3r::InvalidArgument(what_arg) {}
};

class FlowErrorNegativeSpacing : public FlowError
{
public:
    FlowErrorNegativeSpacing();
};

class FlowErrorNegativeFlow : public FlowError
{
public:
    FlowErrorNegativeFlow();
};

class FlowErrorMissingVariable : public FlowError
{
public:
    FlowErrorMissingVariable(const std::string& what_arg) : FlowError(what_arg) {}
};

class Flow
{
public:
    Flow() = default;
    Flow(float width, float height, float nozzle_diameter, float spacing_ratio) :
        m_width(width), m_height(height), m_spacing(rounded_rectangle_extrusion_spacing(width, height)), m_nozzle_diameter(nozzle_diameter), m_spacing_ratio(spacing_ratio), m_bridge(false) {}
        //Flow(width, height, rounded_rectangle_extrusion_spacing(width, height), nozzle_diameter, spacing_ratio, false) {}
    Flow(float width, float height, float spacing, float _nd, float spacing_ratio, bool _bridge) :
        m_width(width), m_height(height), m_spacing(spacing), m_nozzle_diameter(_nd), m_spacing_ratio(spacing_ratio), m_bridge(_bridge) {}

    // Non bridging flow: Maximum width of an extrusion with semicircles at the ends.
    // Bridging flow: Bridge thread diameter.
    float   width()           const { return m_width; }
    coord_t scaled_width()    const { return scale_t(m_width); }
    // Non bridging flow: Layer height.
    // Bridging flow: Bridge thread diameter = layer height.
    float   height()          const { return m_height; }
    // Spacing between the extrusion centerlines.
    float   spacing()         const;// { return m_spacing; } use the compute, as I can't be 100% sure yet that this cachced value is good.
    coord_t scaled_spacing()  const { return scale_t(spacing()); }
    float   spacing_ratio()   const { return m_spacing_ratio; }
    // Nozzle diameter. 
    float   nozzle_diameter() const { return m_nozzle_diameter; }
    // Is it a bridge?
    bool    bridge()          const { return m_bridge; }
    // Cross section area of the extrusion.
    double  mm3_per_mm()      const;

    float overlap(float height) const {
        return (float)(height * (1. - 0.25 * PI)) * m_spacing_ratio;
    }
    // is it still needed?
    float spacing(const Flow& other) const;
    coord_t scaled_spacing(const Flow& other) const { return scale_t(this->spacing(other)); }

    // Elephant foot compensation spacing to be used to detect narrow parts, where the elephant foot compensation cannot be applied.
    // To be used on frExternalPerimeter only.
    // Enable some perimeter squish (see INSET_OVERLAP_TOLERANCE).
    // Here an overlap of 0.2x external perimeter spacing is allowed for by the elephant foot compensation.
    coord_t scaled_elephant_foot_spacing() const { return coord_t(0.5f * float(this->scaled_width() + 0.6f * this->scaled_spacing())); }

    bool operator==(const Flow &rhs) const { 
        return m_width == rhs.m_width 
            && m_height == rhs.m_height
            && m_nozzle_diameter == rhs.m_nozzle_diameter
            && m_spacing_ratio == rhs.m_spacing_ratio
            && m_bridge == rhs.m_bridge; }

    Flow        with_width (float width)  const { 
        assert(! m_bridge);
        return Flow(width, m_height, rounded_rectangle_extrusion_spacing(width, m_height), m_nozzle_diameter, m_spacing_ratio, m_bridge);
    }
    Flow        with_height(float height) const { 
        assert(! m_bridge); 
        return Flow(m_width, height, rounded_rectangle_extrusion_spacing(m_width, height), m_nozzle_diameter, m_spacing_ratio, m_bridge);
    }
    // Adjust extrusion flow for new extrusion line spacing, maintaining the old spacing between extrusions.
    Flow        with_spacing(float spacing) const;
    Flow        with_spacing_ratio(float spacing_ratio) const;
    // Adjust the width / height of a rounded extrusion model to reach the prescribed cross section area while maintaining extrusion spacing.
    Flow        with_cross_section(float area) const;
    Flow        with_flow_ratio(double ratio) const { return this->with_cross_section(this->mm3_per_mm() * ratio); }

    static Flow bridging_flow(float dmr, float nozzle_diameter) { return Flow { dmr, dmr, bridge_extrusion_spacing(dmr), nozzle_diameter, 0, true }; }

    static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent& width, float nozzle_diameter, float height, float spacing_ratio);

    // Spacing of extrusions with rounded extrusion model.
    static float rounded_rectangle_extrusion_spacing(float width, float height);
    // Width of extrusions with rounded extrusion model.
    static float rounded_rectangle_extrusion_width_from_spacing(float spacing, float height);
    // Spacing of round thread extrusions.
    static float bridge_extrusion_spacing(float dmr);

    // Sane extrusion width defautl based on nozzle diameter.
    // The defaults were derived from manual Prusa MK3 profiles.
    static float auto_extrusion_width(FlowRole role, float nozzle_diameter);

    // Extrusion width from full config, taking into account the defaults (when set to zero) and ratios (percentages).
    // Precise value depends on layer index (1st layer vs. other layers vs. variable layer height),
    // on active extruder etc. Therefore the value calculated by this function shall be used as a hint only.
	static double extrusion_width(const std::string &opt_key, const ConfigOptionFloatOrPercent *opt, const ConfigOptionResolver &config, const unsigned int first_printing_extruder = 0);
	static double extrusion_width(const std::string &opt_key, const ConfigOptionResolver &config, const unsigned int first_printing_extruder = 0);
    static const ConfigOptionFloatOrPercent* extrusion_option(const std::string& opt_key, const ConfigOptionResolver& config);


/// old constructors
    static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent& width, float nozzle_diameter, float height, float spacing_ratio, float bridge_flow_ratio);
    // Create a flow from the spacing of extrusion lines.
    // This method is used exclusively to calculate new flow of 100% infill, where the extrusion width was allowed to scale
    // to fit a region with integer number of lines.
    static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, float spacing_ratio, bool bridge);


private:
    //Flow(float width, float height, float spacing, float nozzle_diameter, bool bridge) : 
    //    m_width(width), m_height(height), m_spacing(spacing), m_nozzle_diameter(nozzle_diameter), m_bridge(bridge) 
    //    { 
    //        // Gap fill violates this condition.
    //        //assert(width >= height); 
    //    }

    float       m_width { 0 };
    float       m_height { 0 };
    float       m_spacing { 0 };
    float       m_nozzle_diameter { 0 };
    bool        m_bridge { false };
    // % of spacing taken into account 1=>all/default, 0=> width=spacing
    float       m_spacing_ratio { 1 };
    //note: as there is a relation between {m_width, m_height, m_spacing, m_spacing_ratio} then one of these can be deleted.
};

extern Flow support_material_flow(const PrintObject *object, float layer_height = 0.f);
extern Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height = 0.f);
extern Flow support_material_interface_flow(const PrintObject *object, float layer_height = 0.f);

}

#endif