mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-22 00:01:09 -06:00
Ported Flow to XS
This commit is contained in:
parent
87342d324c
commit
036badf932
16 changed files with 360 additions and 201 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue