mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Ported Flow to XS
This commit is contained in:
		
							parent
							
								
									87342d324c
								
							
						
					
					
						commit
						036badf932
					
				
					 16 changed files with 360 additions and 201 deletions
				
			
		| 
						 | 
				
			
			@ -22,6 +22,8 @@ src/ExtrusionEntity.cpp
 | 
			
		|||
src/ExtrusionEntity.hpp
 | 
			
		||||
src/ExtrusionEntityCollection.cpp
 | 
			
		||||
src/ExtrusionEntityCollection.hpp
 | 
			
		||||
src/Flow.cpp
 | 
			
		||||
src/Flow.hpp
 | 
			
		||||
src/Geometry.cpp
 | 
			
		||||
src/Geometry.hpp
 | 
			
		||||
src/Line.cpp
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +67,7 @@ t/12_extrusionpathcollection.t
 | 
			
		|||
t/13_polylinecollection.t
 | 
			
		||||
t/14_geometry.t
 | 
			
		||||
t/15_config.t
 | 
			
		||||
t/16_flow.t
 | 
			
		||||
xsp/Clipper.xsp
 | 
			
		||||
xsp/Config.xsp
 | 
			
		||||
xsp/ExPolygon.xsp
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +75,7 @@ xsp/ExPolygonCollection.xsp
 | 
			
		|||
xsp/ExtrusionEntityCollection.xsp
 | 
			
		||||
xsp/ExtrusionLoop.xsp
 | 
			
		||||
xsp/ExtrusionPath.xsp
 | 
			
		||||
xsp/Flow.xsp
 | 
			
		||||
xsp/Geometry.xsp
 | 
			
		||||
xsp/Line.xsp
 | 
			
		||||
xsp/my.map
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,6 +146,34 @@ our @ISA = 'Slic3r::ExtrusionPath';
 | 
			
		|||
 | 
			
		||||
sub DESTROY {}
 | 
			
		||||
 | 
			
		||||
package Slic3r::Flow;
 | 
			
		||||
 | 
			
		||||
sub new {
 | 
			
		||||
    my ($class, %args) = @_;
 | 
			
		||||
    
 | 
			
		||||
    my $self = $class->_new(
 | 
			
		||||
        @args{qw(width spacing nozzle_diameter)},
 | 
			
		||||
    );
 | 
			
		||||
    $self->set_bridge($args{bridge} // 0);
 | 
			
		||||
    return $self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub new_from_width {
 | 
			
		||||
    my ($class, %args) = @_;
 | 
			
		||||
    
 | 
			
		||||
    return $class->_new_from_width(
 | 
			
		||||
        @args{qw(role width nozzle_diameter layer_height bridge_flow_ratio)},
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub new_from_spacing {
 | 
			
		||||
    my ($class, %args) = @_;
 | 
			
		||||
    
 | 
			
		||||
    return $class->_new_from_spacing(
 | 
			
		||||
        @args{qw(spacing nozzle_diameter layer_height bridge)},
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
package Slic3r::Surface;
 | 
			
		||||
 | 
			
		||||
sub new {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,22 +50,18 @@ ConfigBase::set_deserialize(const t_config_option_key opt_key, std::string str)
 | 
			
		|||
 | 
			
		||||
double
 | 
			
		||||
ConfigBase::get_abs_value(const t_config_option_key opt_key) {
 | 
			
		||||
    // get option definition
 | 
			
		||||
    assert(this->def->count(opt_key) != 0);
 | 
			
		||||
    ConfigOptionDef* def = &(*this->def)[opt_key];
 | 
			
		||||
    assert(def->type == coFloatOrPercent);
 | 
			
		||||
    
 | 
			
		||||
    // get stored option value
 | 
			
		||||
    ConfigOptionFloatOrPercent* opt = dynamic_cast<ConfigOptionFloatOrPercent*>(this->option(opt_key));
 | 
			
		||||
    assert(opt != NULL);
 | 
			
		||||
    
 | 
			
		||||
    // compute absolute value
 | 
			
		||||
    if (opt->percent) {
 | 
			
		||||
        ConfigOptionFloat* optbase = dynamic_cast<ConfigOptionFloat*>(this->option(def->ratio_over));
 | 
			
		||||
        if (optbase == NULL) throw "ratio_over option not found";
 | 
			
		||||
        return optbase->value * opt->value / 100;
 | 
			
		||||
    ConfigOption* opt = this->option(opt_key, false);
 | 
			
		||||
    if (ConfigOptionFloatOrPercent* optv = dynamic_cast<ConfigOptionFloatOrPercent*>(opt)) {
 | 
			
		||||
        // get option definition
 | 
			
		||||
        assert(this->def->count(opt_key) != 0);
 | 
			
		||||
        ConfigOptionDef* def = &(*this->def)[opt_key];
 | 
			
		||||
        
 | 
			
		||||
        // compute absolute value over the absolute value of the base option
 | 
			
		||||
        return optv->get_abs_value(this->get_abs_value(def->ratio_over));
 | 
			
		||||
    } else if (ConfigOptionFloat* optv = dynamic_cast<ConfigOptionFloat*>(opt)) {
 | 
			
		||||
        return optv->value;
 | 
			
		||||
    } else {
 | 
			
		||||
        return opt->value;
 | 
			
		||||
        throw "Not a valid option type for get_abs_value()";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -76,11 +72,7 @@ ConfigBase::get_abs_value(const t_config_option_key opt_key, double ratio_over)
 | 
			
		|||
    assert(opt != NULL);
 | 
			
		||||
    
 | 
			
		||||
    // compute absolute value
 | 
			
		||||
    if (opt->percent) {
 | 
			
		||||
        return ratio_over * opt->value / 100;
 | 
			
		||||
    } else {
 | 
			
		||||
        return opt->value;
 | 
			
		||||
    }
 | 
			
		||||
    return opt->get_abs_value(ratio_over);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef SLIC3RXS
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ typedef std::vector<std::string> t_config_option_keys;
 | 
			
		|||
class ConfigOption {
 | 
			
		||||
    public:
 | 
			
		||||
    virtual ~ConfigOption() {};
 | 
			
		||||
    virtual std::string serialize() = 0;
 | 
			
		||||
    virtual std::string serialize() const = 0;
 | 
			
		||||
    virtual void deserialize(std::string str) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ class ConfigOptionFloat : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator double() const { return this->value; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        ss << this->value;
 | 
			
		||||
        return ss.str();
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ class ConfigOptionFloats : public ConfigOption, public ConfigOptionVector<double
 | 
			
		|||
{
 | 
			
		||||
    public:
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        for (std::vector<double>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
 | 
			
		||||
            if (it - this->values.begin() != 0) ss << ",";
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ class ConfigOptionInt : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator int() const { return this->value; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        ss << this->value;
 | 
			
		||||
        return ss.str();
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ class ConfigOptionInts : public ConfigOption, public ConfigOptionVector<int>
 | 
			
		|||
{
 | 
			
		||||
    public:
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        for (std::vector<int>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
 | 
			
		||||
            if (it - this->values.begin() != 0) ss << ",";
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ class ConfigOptionString : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator std::string() const { return this->value; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::string str = this->value;
 | 
			
		||||
        
 | 
			
		||||
        // s/\R/\\n/g
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ class ConfigOptionStrings : public ConfigOption, public ConfigOptionVector<std::
 | 
			
		|||
{
 | 
			
		||||
    public:
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        for (std::vector<std::string>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
 | 
			
		||||
            if (it - this->values.begin() != 0) ss << ";";
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +189,15 @@ class ConfigOptionFloatOrPercent : public ConfigOption
 | 
			
		|||
    bool percent;
 | 
			
		||||
    ConfigOptionFloatOrPercent() : value(0), percent(false) {};
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    double get_abs_value(double ratio_over) const {
 | 
			
		||||
        if (this->percent) {
 | 
			
		||||
            return ratio_over * this->value / 100;
 | 
			
		||||
        } else {
 | 
			
		||||
            return this->value;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        ss << this->value;
 | 
			
		||||
        std::string s(ss.str());
 | 
			
		||||
| 
						 | 
				
			
			@ -216,7 +224,7 @@ class ConfigOptionPoint : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator Pointf() const { return this->point; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        ss << this->point.x;
 | 
			
		||||
        ss << ",";
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +241,7 @@ class ConfigOptionPoints : public ConfigOption, public ConfigOptionVector<Pointf
 | 
			
		|||
{
 | 
			
		||||
    public:
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        for (Pointfs::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
 | 
			
		||||
            if (it - this->values.begin() != 0) ss << ",";
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +272,7 @@ class ConfigOptionBool : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator bool() const { return this->value; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        return std::string(this->value ? "1" : "0");
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -277,7 +285,7 @@ class ConfigOptionBools : public ConfigOption, public ConfigOptionVector<bool>
 | 
			
		|||
{
 | 
			
		||||
    public:
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        for (std::vector<bool>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
 | 
			
		||||
            if (it - this->values.begin() != 0) ss << ",";
 | 
			
		||||
| 
						 | 
				
			
			@ -306,7 +314,7 @@ class ConfigOptionEnum : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator T() const { return this->value; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        t_config_enum_values enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
 | 
			
		||||
        for (t_config_enum_values::iterator it = enum_keys_map.begin(); it != enum_keys_map.end(); ++it) {
 | 
			
		||||
            if (it->second == static_cast<int>(this->value)) return it->first;
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +341,7 @@ class ConfigOptionEnumGeneric : public ConfigOption
 | 
			
		|||
    
 | 
			
		||||
    operator int() const { return this->value; };
 | 
			
		||||
    
 | 
			
		||||
    std::string serialize() {
 | 
			
		||||
    std::string serialize() const {
 | 
			
		||||
        for (t_config_enum_values::iterator it = this->keys_map->begin(); it != this->keys_map->end(); ++it) {
 | 
			
		||||
            if (it->second == this->value) return it->first;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										109
									
								
								xs/src/Flow.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								xs/src/Flow.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
#include "Flow.hpp"
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
Flow
 | 
			
		||||
Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio) {
 | 
			
		||||
    float w;
 | 
			
		||||
    if (!width.percent && width.value == 0) {
 | 
			
		||||
        w = Flow::_width(role, nozzle_diameter, height, bridge_flow_ratio);
 | 
			
		||||
    } else {
 | 
			
		||||
        w = width.get_abs_value(height);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Flow flow(w, Flow::_spacing(w, nozzle_diameter, height, bridge_flow_ratio), nozzle_diameter);
 | 
			
		||||
    if (bridge_flow_ratio > 0) flow.bridge = true;
 | 
			
		||||
    return flow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Flow
 | 
			
		||||
Flow::new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge) {
 | 
			
		||||
    float w = Flow::_width_from_spacing(spacing, nozzle_diameter, height, bridge);
 | 
			
		||||
    Flow flow(w, spacing, nozzle_diameter);
 | 
			
		||||
    flow.bridge = bridge;
 | 
			
		||||
    return flow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double
 | 
			
		||||
Flow::mm3_per_mm(float h) {
 | 
			
		||||
    if (this->bridge) {
 | 
			
		||||
        return (this->width * this->width) * PI/4.0;
 | 
			
		||||
    } else if (this->width >= (this->nozzle_diameter + h)) {
 | 
			
		||||
        // rectangle with semicircles at the ends
 | 
			
		||||
        return this->width * h + (h*h) / 4.0 * (PI-4.0);
 | 
			
		||||
    } else {
 | 
			
		||||
        // rectangle with shrunk semicircles at the ends
 | 
			
		||||
        return this->nozzle_diameter * h * (1 - PI/4.0) + h * this->width * PI/4.0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
Flow::_width(FlowRole role, float nozzle_diameter, float height, float bridge_flow_ratio) {
 | 
			
		||||
    if (bridge_flow_ratio > 0) {
 | 
			
		||||
        return sqrt(bridge_flow_ratio * (nozzle_diameter*nozzle_diameter));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // here we calculate a sane default by matching the flow speed (at the nozzle) and the feed rate
 | 
			
		||||
    float volume = (nozzle_diameter*nozzle_diameter) * PI/4.0;
 | 
			
		||||
    float shape_threshold = nozzle_diameter * height + (height*height) * PI/4.0;
 | 
			
		||||
    float width;
 | 
			
		||||
    if (volume >= shape_threshold) {
 | 
			
		||||
        // rectangle with semicircles at the ends
 | 
			
		||||
        width = ((nozzle_diameter*nozzle_diameter) * PI + (height*height) * (4.0 - PI)) / (4.0 * height);
 | 
			
		||||
    } else {
 | 
			
		||||
        // rectangle with squished semicircles at the ends
 | 
			
		||||
        width = nozzle_diameter * (nozzle_diameter/height - 4.0/PI + 1);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    float min = nozzle_diameter * 1.05;
 | 
			
		||||
    float max = -1;
 | 
			
		||||
    if (role == frPerimeter || role == frSupportMaterial) {
 | 
			
		||||
        min = max = nozzle_diameter;
 | 
			
		||||
    } else if (role != frInfill) {
 | 
			
		||||
        // do not limit width for sparse infill so that we use full native flow for it
 | 
			
		||||
        max = nozzle_diameter * 1.7;
 | 
			
		||||
    }
 | 
			
		||||
    if (max != -1 && width > max) width = max;
 | 
			
		||||
    if (width < min) width = min;
 | 
			
		||||
    
 | 
			
		||||
    return width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
Flow::_width_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge) {
 | 
			
		||||
    if (bridge) {
 | 
			
		||||
        return spacing - BRIDGE_EXTRA_SPACING;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    float w_threshold = height + nozzle_diameter;
 | 
			
		||||
    float s_threshold = w_threshold - OVERLAP_FACTOR * (w_threshold - (w_threshold - height * (1 - PI/4.0)));
 | 
			
		||||
    
 | 
			
		||||
    if (spacing >= s_threshold) {
 | 
			
		||||
        // rectangle with semicircles at the ends
 | 
			
		||||
        return spacing + OVERLAP_FACTOR * height * (1 - PI/4.0);
 | 
			
		||||
    } else {
 | 
			
		||||
        // rectangle with shrunk semicircles at the ends
 | 
			
		||||
        return (spacing + nozzle_diameter * OVERLAP_FACTOR * (PI/4.0 - 1)) / (1 + OVERLAP_FACTOR * (PI/4.0 - 1));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
Flow::_spacing(float width, float nozzle_diameter, float height, float bridge_flow_ratio) {
 | 
			
		||||
    if (bridge_flow_ratio > 0) {
 | 
			
		||||
        return width + BRIDGE_EXTRA_SPACING;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    float min_flow_spacing;
 | 
			
		||||
    if (width >= (nozzle_diameter + height)) {
 | 
			
		||||
        // rectangle with semicircles at the ends
 | 
			
		||||
        min_flow_spacing = width - height * (1 - PI/4.0);
 | 
			
		||||
    } else {
 | 
			
		||||
        // rectangle with shrunk semicircles at the ends
 | 
			
		||||
        min_flow_spacing = nozzle_diameter * (1 - PI/4.0) + width * PI/4.0;
 | 
			
		||||
    }
 | 
			
		||||
    return width - OVERLAP_FACTOR * (width - min_flow_spacing);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								xs/src/Flow.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								xs/src/Flow.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
#ifndef slic3r_Flow_hpp_
 | 
			
		||||
#define slic3r_Flow_hpp_
 | 
			
		||||
 | 
			
		||||
#include <myinit.h>
 | 
			
		||||
#include "Config.hpp"
 | 
			
		||||
#include "ExtrusionEntity.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
#define BRIDGE_EXTRA_SPACING 0.05
 | 
			
		||||
#define OVERLAP_FACTOR 1.0
 | 
			
		||||
 | 
			
		||||
enum FlowRole {
 | 
			
		||||
    frPerimeter,
 | 
			
		||||
    frInfill,
 | 
			
		||||
    frSolidInfill,
 | 
			
		||||
    frTopSolidInfill,
 | 
			
		||||
    frSupportMaterial,
 | 
			
		||||
    frSupportMaterialInterface,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Flow
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
    float width;
 | 
			
		||||
    float spacing;
 | 
			
		||||
    float nozzle_diameter;
 | 
			
		||||
    bool bridge;
 | 
			
		||||
    coord_t scaled_width;
 | 
			
		||||
    coord_t scaled_spacing;
 | 
			
		||||
    
 | 
			
		||||
    Flow(float _w, float _s, float _nd): width(_w), spacing(_s), nozzle_diameter(_nd), bridge(false) {
 | 
			
		||||
        this->scaled_width   = scale_(this->width);
 | 
			
		||||
        this->scaled_spacing = scale_(this->spacing);
 | 
			
		||||
    };
 | 
			
		||||
    double mm3_per_mm(float h);
 | 
			
		||||
    static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio);
 | 
			
		||||
    static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
 | 
			
		||||
    
 | 
			
		||||
    private:
 | 
			
		||||
    static float _width(FlowRole role, float nozzle_diameter, float height, float bridge_flow_ratio);
 | 
			
		||||
    static float _width_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
 | 
			
		||||
    static float _spacing(float width, float nozzle_diameter, float height, float bridge_flow_ratio);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -23,8 +23,8 @@ Point::rotate(double angle, Point* center)
 | 
			
		|||
{
 | 
			
		||||
    double cur_x = (double)this->x;
 | 
			
		||||
    double cur_y = (double)this->y;
 | 
			
		||||
    this->x = (long)round( (double)center->x + cos(angle) * (cur_x - (double)center->x) - sin(angle) * (cur_y - (double)center->y) );
 | 
			
		||||
    this->y = (long)round( (double)center->y + cos(angle) * (cur_y - (double)center->y) + sin(angle) * (cur_x - (double)center->x) );
 | 
			
		||||
    this->x = (coord_t)round( (double)center->x + cos(angle) * (cur_x - (double)center->x) - sin(angle) * (cur_y - (double)center->y) );
 | 
			
		||||
    this->y = (coord_t)round( (double)center->y + cos(angle) * (cur_y - (double)center->y) + sin(angle) * (cur_x - (double)center->x) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,9 +17,9 @@ typedef std::vector<Pointf> Pointfs;
 | 
			
		|||
class Point
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
    long x;
 | 
			
		||||
    long y;
 | 
			
		||||
    explicit Point(long _x = 0, long _y = 0): x(_x), y(_y) {};
 | 
			
		||||
    coord_t x;
 | 
			
		||||
    coord_t y;
 | 
			
		||||
    explicit Point(coord_t _x = 0, coord_t _y = 0): x(_x), y(_y) {};
 | 
			
		||||
    void scale(double factor);
 | 
			
		||||
    void translate(double x, double y);
 | 
			
		||||
    void rotate(double angle, Point* center);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,10 @@ extern "C" {
 | 
			
		|||
 | 
			
		||||
#define EPSILON 1e-4
 | 
			
		||||
#define SCALING_FACTOR 0.000001
 | 
			
		||||
#define PI 3.141592653589793238
 | 
			
		||||
#define scale_(val) (val / SCALING_FACTOR)
 | 
			
		||||
#define unscale(val) (val * SCALING_FACTOR)
 | 
			
		||||
typedef long coord_t;
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {}
 | 
			
		||||
using namespace Slic3r;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ use strict;
 | 
			
		|||
use warnings;
 | 
			
		||||
 | 
			
		||||
use Slic3r::XS;
 | 
			
		||||
use Test::More tests => 88;
 | 
			
		||||
use Test::More tests => 89;
 | 
			
		||||
 | 
			
		||||
foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
 | 
			
		||||
    $config->set('layer_height', 0.3);
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,9 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) {
 | 
			
		|||
    my $config2 = Slic3r::Config->new;
 | 
			
		||||
    $config2->apply_static($config);
 | 
			
		||||
    is $config2->get('perimeters'), Slic3r::Config::print_config_def()->{perimeters}{default}, 'apply_static and print_config_def';
 | 
			
		||||
    
 | 
			
		||||
    $config->set('top_solid_infill_speed', 70);
 | 
			
		||||
    is $config->get_abs_value('top_solid_infill_speed'), 70, 'get_abs_value() works when ratio_over references a floatOrPercent option';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								xs/t/16_flow.t
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								xs/t/16_flow.t
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
#!/usr/bin/perl
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
 | 
			
		||||
use Slic3r::XS;
 | 
			
		||||
use Test::More tests => 2;
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    my $flow = Slic3r::Flow->new_from_width(
 | 
			
		||||
        role => Slic3r::Flow::FLOW_ROLE_PERIMETER,
 | 
			
		||||
        width               => '1',
 | 
			
		||||
        nozzle_diameter     => 0.5,
 | 
			
		||||
        layer_height        => 0.3, 
 | 
			
		||||
        bridge_flow_ratio   => 1,
 | 
			
		||||
    );
 | 
			
		||||
    isa_ok $flow, 'Slic3r::Flow', 'new_from_width';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    my $flow = Slic3r::Flow->new(
 | 
			
		||||
        width               => 1,
 | 
			
		||||
        spacing             => 0.95,
 | 
			
		||||
        nozzle_diameter     => 0.5,
 | 
			
		||||
    );
 | 
			
		||||
    isa_ok $flow, 'Slic3r::Flow', 'new';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__END__
 | 
			
		||||
							
								
								
									
										80
									
								
								xs/xsp/Flow.xsp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								xs/xsp/Flow.xsp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
%module{Slic3r::XS};
 | 
			
		||||
 | 
			
		||||
%{
 | 
			
		||||
#include <myinit.h>
 | 
			
		||||
#include "Flow.hpp"
 | 
			
		||||
%}
 | 
			
		||||
 | 
			
		||||
%name{Slic3r::Flow} class Flow {
 | 
			
		||||
    ~Flow();
 | 
			
		||||
    %name{_new} Flow(float width, float spacing, float nozzle_diameter);
 | 
			
		||||
    void set_bridge(bool bridge)
 | 
			
		||||
        %code{% THIS->bridge = bridge; %};
 | 
			
		||||
    Flow* clone()
 | 
			
		||||
        %code{% const char* CLASS = "Slic3r::Flow"; RETVAL = new Flow(*THIS); %};
 | 
			
		||||
    
 | 
			
		||||
    float width()
 | 
			
		||||
        %code{% RETVAL = THIS->width; %};
 | 
			
		||||
    float spacing()
 | 
			
		||||
        %code{% RETVAL = THIS->spacing; %};
 | 
			
		||||
    float nozzle_diameter()
 | 
			
		||||
        %code{% RETVAL = THIS->nozzle_diameter; %};
 | 
			
		||||
    bool bridge()
 | 
			
		||||
        %code{% RETVAL = THIS->bridge; %};
 | 
			
		||||
    long scaled_width()
 | 
			
		||||
        %code{% RETVAL = THIS->scaled_width; %};
 | 
			
		||||
    long scaled_spacing()
 | 
			
		||||
        %code{% RETVAL = THIS->scaled_spacing; %};
 | 
			
		||||
    
 | 
			
		||||
    double mm3_per_mm(float height);
 | 
			
		||||
%{
 | 
			
		||||
 | 
			
		||||
Flow*
 | 
			
		||||
_new_from_width(CLASS, role, width, nozzle_diameter, height, bridge_flow_ratio)
 | 
			
		||||
    char*           CLASS;
 | 
			
		||||
    FlowRole        role;
 | 
			
		||||
    std::string     width;
 | 
			
		||||
    float           nozzle_diameter;
 | 
			
		||||
    float           height;
 | 
			
		||||
    float           bridge_flow_ratio;
 | 
			
		||||
    CODE:
 | 
			
		||||
        ConfigOptionFloatOrPercent optwidth;
 | 
			
		||||
        optwidth.deserialize(width);
 | 
			
		||||
        RETVAL = new Flow(Flow::new_from_config_width(role, optwidth, nozzle_diameter, height, bridge_flow_ratio));
 | 
			
		||||
    OUTPUT:
 | 
			
		||||
        RETVAL
 | 
			
		||||
 | 
			
		||||
Flow*
 | 
			
		||||
_new_from_spacing(CLASS, spacing, nozzle_diameter, height, bridge)
 | 
			
		||||
    char*           CLASS;
 | 
			
		||||
    float           spacing;
 | 
			
		||||
    float           nozzle_diameter;
 | 
			
		||||
    float           height;
 | 
			
		||||
    bool            bridge;
 | 
			
		||||
    CODE:
 | 
			
		||||
        RETVAL = new Flow(Flow::new_from_spacing(spacing, nozzle_diameter, height, bridge));
 | 
			
		||||
    OUTPUT:
 | 
			
		||||
        RETVAL
 | 
			
		||||
 | 
			
		||||
%}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
%package{Slic3r::Flow};
 | 
			
		||||
%{
 | 
			
		||||
 | 
			
		||||
IV
 | 
			
		||||
_constant()
 | 
			
		||||
  ALIAS:
 | 
			
		||||
    FLOW_ROLE_PERIMETER                     = frPerimeter
 | 
			
		||||
    FLOW_ROLE_INFILL                        = frInfill
 | 
			
		||||
    FLOW_ROLE_SOLID_INFILL                  = frSolidInfill
 | 
			
		||||
    FLOW_ROLE_TOP_SOLID_INFILL              = frTopSolidInfill
 | 
			
		||||
    FLOW_ROLE_SUPPORT_MATERIAL              = frSupportMaterial
 | 
			
		||||
    FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE    = frSupportMaterialInterface
 | 
			
		||||
  PROTOTYPE:
 | 
			
		||||
  CODE:
 | 
			
		||||
    RETVAL = ix;
 | 
			
		||||
  OUTPUT: RETVAL
 | 
			
		||||
 | 
			
		||||
%}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,11 +18,13 @@ ExPolygonCollection*    O_OBJECT
 | 
			
		|||
ExtrusionEntityCollection*    O_OBJECT
 | 
			
		||||
ExtrusionPath*  O_OBJECT
 | 
			
		||||
ExtrusionLoop*  O_OBJECT
 | 
			
		||||
Flow*           O_OBJECT
 | 
			
		||||
PrintState*  O_OBJECT
 | 
			
		||||
Surface*        O_OBJECT
 | 
			
		||||
SurfaceCollection*      O_OBJECT
 | 
			
		||||
 | 
			
		||||
ExtrusionRole     T_UV
 | 
			
		||||
FlowRole     T_UV
 | 
			
		||||
PrintStep     T_UV
 | 
			
		||||
SurfaceType     T_UV
 | 
			
		||||
ClipperLib::JoinType		T_UV
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@
 | 
			
		|||
%typemap{FullPrintConfig*};
 | 
			
		||||
%typemap{ExPolygon*};
 | 
			
		||||
%typemap{ExPolygonCollection*};
 | 
			
		||||
%typemap{Flow*};
 | 
			
		||||
%typemap{Line*};
 | 
			
		||||
%typemap{Polyline*};
 | 
			
		||||
%typemap{Polygon*};
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +44,12 @@
 | 
			
		|||
    $CVar = (ExtrusionRole)SvUV($PerlVar);
 | 
			
		||||
  %};
 | 
			
		||||
};
 | 
			
		||||
%typemap{FlowRole}{parsed}{
 | 
			
		||||
  %cpp_type{FlowRole};
 | 
			
		||||
  %precall_code{%
 | 
			
		||||
    $CVar = (FlowRole)SvUV($PerlVar);
 | 
			
		||||
  %};
 | 
			
		||||
};
 | 
			
		||||
%typemap{PrintStep}{parsed}{
 | 
			
		||||
  %cpp_type{PrintStep};
 | 
			
		||||
  %precall_code{%
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue