New --scale-to-fit option in slic3r.cpp

This commit is contained in:
Alessandro Ranellucci 2016-10-18 10:22:34 +02:00
parent 3700950474
commit 68acf19c09
9 changed files with 81 additions and 6 deletions

View File

@ -63,6 +63,9 @@ main(const int argc, const char **argv)
// apply command line transform options
for (ModelObjectPtrs::iterator o = model.objects.begin(); o != model.objects.end(); ++o) {
if (cli_config.scale_to_fit.is_positive_volume())
(*o)->scale_to_fit(cli_config.scale_to_fit.value);
(*o)->scale(cli_config.scale.value);
(*o)->rotate(cli_config.rotate.value, Z);
}

View File

@ -283,6 +283,8 @@ DynamicConfig::optptr(const t_config_option_key &opt_key, bool create) {
opt = new ConfigOptionFloatOrPercent ();
} else if (optdef->type == coPoint) {
opt = new ConfigOptionPoint ();
} else if (optdef->type == coPoint3) {
opt = new ConfigOptionPoint3 ();
} else if (optdef->type == coPoints) {
opt = new ConfigOptionPoints ();
} else if (optdef->type == coBool) {

View File

@ -10,6 +10,8 @@
#include <stdexcept>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "libslic3r.h"
#include "Point.hpp"
@ -352,15 +354,55 @@ class ConfigOptionPoint : public ConfigOptionSingle<Pointf>
};
bool deserialize(std::string str, bool append = false) {
std::istringstream iss(str);
iss >> this->value.x;
iss.ignore(std::numeric_limits<std::streamsize>::max(), ',');
iss.ignore(std::numeric_limits<std::streamsize>::max(), 'x');
iss >> this->value.y;
std::vector<std::string> tokens(2);
boost::split(tokens, str, boost::is_any_of(",x"));
try {
this->value.x = boost::lexical_cast<coordf_t>(tokens[0]);
this->value.y = boost::lexical_cast<coordf_t>(tokens[1]);
} catch (boost::bad_lexical_cast &e){
std::cout << "Exception caught : " << e.what() << std::endl;
return false;
}
return true;
};
};
class ConfigOptionPoint3 : public ConfigOptionSingle<Pointf3>
{
public:
ConfigOptionPoint3() : ConfigOptionSingle<Pointf3>(Pointf3(0,0,0)) {};
ConfigOptionPoint3(Pointf3 _value) : ConfigOptionSingle<Pointf3>(_value) {};
ConfigOptionPoint3* clone() const { return new ConfigOptionPoint3(this->value); };
std::string serialize() const {
std::ostringstream ss;
ss << this->value.x;
ss << ",";
ss << this->value.y;
ss << ",";
ss << this->value.z;
return ss.str();
};
bool deserialize(std::string str, bool append = false) {
std::vector<std::string> tokens(3);
boost::split(tokens, str, boost::is_any_of(",x"));
try {
this->value.x = boost::lexical_cast<coordf_t>(tokens[0]);
this->value.y = boost::lexical_cast<coordf_t>(tokens[1]);
this->value.z = boost::lexical_cast<coordf_t>(tokens[2]);
} catch (boost::bad_lexical_cast &e){
std::cout << "Exception caught : " << e.what() << std::endl;
return false;
}
return true;
};
bool is_positive_volume () {
return this->value.x > 0 && this->value.y > 0 && this->value.z > 0;
};
};
class ConfigOptionPoints : public ConfigOptionVector<Pointf>
{
public:
@ -526,6 +568,7 @@ enum ConfigOptionType {
coPercent,
coFloatOrPercent,
coPoint,
coPoint3,
coPoints,
coBool,
coBools,

View File

@ -609,6 +609,20 @@ ModelObject::scale(const Pointf3 &versor)
this->invalidate_bounding_box();
}
void
ModelObject::scale_to_fit(const Sizef3 &size)
{
Sizef3 orig_size = this->bounding_box().size();
float factor = fminf(
size.x / orig_size.x,
fminf(
size.y / orig_size.y,
size.z / orig_size.z
)
);
this->scale(factor);
}
void
ModelObject::rotate(float angle, const Axis &axis)
{

View File

@ -2,6 +2,7 @@
#define slic3r_Model_hpp_
#include "libslic3r.h"
#include "BoundingBox.hpp"
#include "PrintConfig.hpp"
#include "Layer.hpp"
#include "Point.hpp"
@ -129,6 +130,7 @@ class ModelObject
void translate(coordf_t x, coordf_t y, coordf_t z);
void scale(float factor);
void scale(const Pointf3 &versor);
void scale_to_fit(const Sizef3 &size);
void rotate(float angle, const Axis &axis);
void mirror(const Axis &axis);
size_t materials_count() const;

View File

@ -1412,6 +1412,12 @@ CLIConfigDef::CLIConfigDef()
def->tooltip = "Scaling factor (default: 1).";
def->cli = "scale";
def->default_value = new ConfigOptionFloat(1);
def = this->add("scale_to_fit", coPoint3);
def->label = "Scale to Fit";
def->tooltip = "Scale to fit the given volume.";
def->cli = "scale-to-fit";
def->default_value = new ConfigOptionPoint3(Pointf3(0,0,0));
}
CLIConfigDef cli_config_def;

View File

@ -526,6 +526,7 @@ class CLIConfig
ConfigOptionFloat rotate;
ConfigOptionString save;
ConfigOptionFloat scale;
ConfigOptionPoint3 scale_to_fit;
CLIConfig() : ConfigBase(), StaticConfig() {
this->def = &cli_config_def;
@ -542,6 +543,7 @@ class CLIConfig
OPT_PTR(rotate);
OPT_PTR(save);
OPT_PTR(scale);
OPT_PTR(scale_to_fit);
return NULL;
};

View File

@ -115,6 +115,9 @@ ConfigOption_to_SV(const ConfigOption &opt, const ConfigOptionDef &def) {
} else if (def.type == coPoint) {
const ConfigOptionPoint* optv = dynamic_cast<const ConfigOptionPoint*>(&opt);
return perl_to_SV_clone_ref(optv->value);
} else if (def.type == coPoint3) {
const ConfigOptionPoint3* optv = dynamic_cast<const ConfigOptionPoint3*>(&opt);
return perl_to_SV_clone_ref(optv->value);
} else if (def.type == coPoints) {
const ConfigOptionPoints* optv = dynamic_cast<const ConfigOptionPoints*>(&opt);
AV* av = newAV();

View File

@ -118,7 +118,7 @@ print_config_def()
opt_type = "s";
} else if (optdef->type == coStrings) {
opt_type = "s@";
} else if (optdef->type == coPoint || optdef->type == coPoints) {
} else if (optdef->type == coPoint || optdef->type == coPoint3 || optdef->type == coPoints) {
opt_type = "point";
} else if (optdef->type == coBool || optdef->type == coBools) {
opt_type = "bool";