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

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2016-11-01 15:41:24 +0300
committerbubnikv <bubnikv@gmail.com>2016-11-01 15:41:24 +0300
commit3d3654707b97f679037cb66c2143338cf8baf917 (patch)
treee13ed4e8725d1f4d4c1b713f518ac5167e72e16a /xs/src/libslic3r/Config.cpp
parent4e66ed81d26774a6196259dee35a5da0c678d081 (diff)
Added "Notes" page to the filament configuration.
Added "filament_max_volumetric_speed", a cap on the maximum volumetric extrusion role, filament specific. This is very useful when mixing rigid filament with a soft filament. Extended the import / export of multi-string values into configuration values, including the test cases. Multi-line strings will be enclosed into quotes, quotes escaped using a C-style escape sequences. Single word strings could still be stored without quotes.
Diffstat (limited to 'xs/src/libslic3r/Config.cpp')
-rw-r--r--xs/src/libslic3r/Config.cpp165
1 files changed, 159 insertions, 6 deletions
diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp
index 39c0da2bb..cdeee4dd8 100644
--- a/xs/src/libslic3r/Config.cpp
+++ b/xs/src/libslic3r/Config.cpp
@@ -8,6 +8,159 @@
namespace Slic3r {
+std::string escape_string_cstyle(const std::string &str)
+{
+ // Allocate a buffer twice the input string length,
+ // so the output will fit even if all input characters get escaped.
+ std::vector<char> out(str.size() * 2, 0);
+ char *outptr = out.data();
+ for (size_t i = 0; i < str.size(); ++ i) {
+ char c = str[i];
+ if (c == '\n' || c == '\r') {
+ (*outptr ++) = '\\';
+ (*outptr ++) = 'n';
+ } else
+ (*outptr ++) = c;
+ }
+ return std::string(out.data(), outptr - out.data());
+}
+
+std::string escape_strings_cstyle(const std::vector<std::string> &strs)
+{
+ // 1) Estimate the output buffer size to avoid buffer reallocation.
+ size_t outbuflen = 0;
+ for (size_t i = 0; i < strs.size(); ++ i)
+ // Reserve space for every character escaped + quotes + semicolon.
+ outbuflen += strs[i].size() * 2 + 3;
+ // 2) Fill in the buffer.
+ std::vector<char> out(outbuflen, 0);
+ char *outptr = out.data();
+ for (size_t j = 0; j < strs.size(); ++ j) {
+ if (j > 0)
+ // Separate the strings.
+ (*outptr ++) = ';';
+ const std::string &str = strs[j];
+ // Is the string simple or complex? Complex string contains spaces, tabs, new lines and other
+ // escapable characters. Empty string shall be quoted as well, if it is the only string in strs.
+ bool should_quote = strs.size() == 1 && str.empty();
+ for (size_t i = 0; i < str.size(); ++ i) {
+ char c = str[i];
+ if (c == ' ' || c == '\t' || c == '\\' || c == '"' || c == '\r' || c == '\n') {
+ should_quote = true;
+ break;
+ }
+ }
+ if (should_quote) {
+ (*outptr ++) = '"';
+ for (size_t i = 0; i < str.size(); ++ i) {
+ char c = str[i];
+ if (c == '\\' || c == '"') {
+ (*outptr ++) = '\\';
+ (*outptr ++) = c;
+ } else if (c == '\n' || c == '\r') {
+ (*outptr ++) = '\\';
+ (*outptr ++) = 'n';
+ } else
+ (*outptr ++) = c;
+ }
+ (*outptr ++) = '"';
+ } else {
+ memcpy(outptr, str.data(), str.size());
+ outptr += str.size();
+ }
+ }
+ return std::string(out.data(), outptr - out.data());
+}
+
+bool unescape_string_cstyle(const std::string &str, std::string &str_out)
+{
+ std::vector<char> out(str.size(), 0);
+ char *outptr = out.data();
+ for (size_t i = 0; i < str.size(); ++ i) {
+ char c = str[i];
+ if (c == '\\') {
+ if (++ i == str.size())
+ return false;
+ c = str[i];
+ if (c == 'n')
+ (*outptr ++) = '\n';
+ } else
+ (*outptr ++) = c;
+ }
+ str_out.assign(out.data(), outptr - out.data());
+ return true;
+}
+
+bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &out)
+{
+ out.clear();
+ if (str.empty())
+ return true;
+
+ size_t i = 0;
+ for (;;) {
+ // Skip white spaces.
+ char c = str[i];
+ while (c == ' ' || c == '\t') {
+ if (++ i == str.size())
+ return true;
+ c = str[i];
+ }
+ // Start of a word.
+ std::vector<char> buf;
+ buf.reserve(16);
+ // Is it enclosed in quotes?
+ c = str[i];
+ if (c == '"') {
+ // Complex case, string is enclosed in quotes.
+ for (++ i; i < str.size(); ++ i) {
+ c = str[i];
+ if (c == '"') {
+ // End of string.
+ break;
+ }
+ if (c == '\\') {
+ if (++ i == str.size())
+ return false;
+ c = str[i];
+ if (c == 'n')
+ c = '\n';
+ }
+ buf.push_back(c);
+ }
+ if (i == str.size())
+ return false;
+ ++ i;
+ } else {
+ for (; i < str.size(); ++ i) {
+ c = str[i];
+ if (c == ';')
+ break;
+ buf.push_back(c);
+ }
+ }
+ // Store the string into the output vector.
+ out.push_back(std::string(buf.data(), buf.size()));
+ if (i == str.size())
+ break;
+ // Skip white spaces.
+ c = str[i];
+ while (c == ' ' || c == '\t') {
+ if (++ i == str.size())
+ // End of string. This is correct.
+ return true;
+ c = str[i];
+ }
+ if (c != ';')
+ return false;
+ if (++ i == str.size()) {
+ // Emit one additional empty string.
+ out.push_back(std::string());
+ return true;
+ }
+ }
+}
+
bool
operator== (const ConfigOption &a, const ConfigOption &b)
{
@@ -116,16 +269,16 @@ ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str)
// Return an absolute value of a possibly relative config variable.
// For example, return absolute infill extrusion width, either from an absolute value, or relative to the layer height.
double
-ConfigBase::get_abs_value(const t_config_option_key &opt_key) {
- ConfigOption* opt = this->option(opt_key, false);
- if (ConfigOptionFloatOrPercent* optv = dynamic_cast<ConfigOptionFloatOrPercent*>(opt)) {
+ConfigBase::get_abs_value(const t_config_option_key &opt_key) const {
+ const ConfigOption* opt = this->option(opt_key);
+ if (const ConfigOptionFloatOrPercent* optv = dynamic_cast<const ConfigOptionFloatOrPercent*>(opt)) {
// get option definition
const ConfigOptionDef* def = this->def->get(opt_key);
assert(def != NULL);
// 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)) {
+ } else if (const ConfigOptionFloat* optv = dynamic_cast<const ConfigOptionFloat*>(opt)) {
return optv->value;
} else {
throw "Not a valid option type for get_abs_value()";
@@ -135,9 +288,9 @@ ConfigBase::get_abs_value(const t_config_option_key &opt_key) {
// Return an absolute value of a possibly relative config variable.
// For example, return absolute infill extrusion width, either from an absolute value, or relative to a provided value.
double
-ConfigBase::get_abs_value(const t_config_option_key &opt_key, double ratio_over) {
+ConfigBase::get_abs_value(const t_config_option_key &opt_key, double ratio_over) const {
// get stored option value
- ConfigOptionFloatOrPercent* opt = dynamic_cast<ConfigOptionFloatOrPercent*>(this->option(opt_key));
+ const ConfigOptionFloatOrPercent* opt = dynamic_cast<const ConfigOptionFloatOrPercent*>(this->option(opt_key));
assert(opt != NULL);
// compute absolute value