2013-12-07 15:14:30 +00:00
# ifndef slic3r_Config_hpp_
# define slic3r_Config_hpp_
# include <myinit.h>
# include <map>
2013-12-20 19:54:11 +00:00
# include <sstream>
# include <cstdio>
# include <cstdlib>
2013-12-21 09:46:43 +00:00
# include <iostream>
2013-12-07 15:14:30 +00:00
# include <string>
# include <vector>
2013-12-20 19:54:11 +00:00
# include "Point.hpp"
2013-12-07 15:14:30 +00:00
2013-12-20 15:37:28 +00:00
namespace Slic3r {
2013-12-07 15:14:30 +00:00
typedef std : : string t_config_option_key ;
typedef std : : vector < std : : string > t_config_option_keys ;
2013-12-20 15:37:28 +00:00
class ConfigOption {
public :
virtual ~ ConfigOption ( ) { } ;
2013-12-20 19:54:11 +00:00
virtual std : : string serialize ( ) = 0 ;
virtual void deserialize ( std : : string str ) = 0 ;
2013-12-20 15:37:28 +00:00
} ;
class ConfigOptionFloat : public ConfigOption
2013-12-07 15:14:30 +00:00
{
public :
2013-12-20 15:37:28 +00:00
float value ;
2013-12-20 19:54:11 +00:00
ConfigOptionFloat ( ) : value ( 0 ) { } ;
2013-12-20 15:37:28 +00:00
operator float ( ) const { return this - > value ; } ;
2013-12-20 19:54:11 +00:00
std : : string serialize ( ) {
std : : ostringstream ss ;
ss < < this - > value ;
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
this - > value = : : atof ( str . c_str ( ) ) ;
} ;
2013-12-20 15:37:28 +00:00
} ;
2013-12-21 13:27:58 +00:00
class ConfigOptionFloats : public ConfigOption
{
public :
std : : vector < float > values ;
std : : string serialize ( ) {
std : : ostringstream ss ;
for ( std : : vector < float > : : const_iterator it = this - > values . begin ( ) ; it ! = this - > values . end ( ) ; + + it ) {
if ( it - this - > values . begin ( ) ! = 0 ) ss < < " , " ;
ss < < * it ;
}
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
this - > values . clear ( ) ;
std : : istringstream is ( str ) ;
std : : string item_str ;
while ( std : : getline ( is , item_str , ' , ' ) ) {
this - > values . push_back ( : : atof ( item_str . c_str ( ) ) ) ;
}
} ;
} ;
2013-12-20 15:37:28 +00:00
class ConfigOptionInt : public ConfigOption
{
public :
int value ;
2013-12-20 19:54:11 +00:00
ConfigOptionInt ( ) : value ( 0 ) { } ;
2013-12-20 15:37:28 +00:00
operator int ( ) const { return this - > value ; } ;
2013-12-20 19:54:11 +00:00
std : : string serialize ( ) {
std : : ostringstream ss ;
ss < < this - > value ;
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
this - > value = : : atoi ( str . c_str ( ) ) ;
} ;
2013-12-20 15:37:28 +00:00
} ;
2013-12-21 13:27:58 +00:00
class ConfigOptionInts : public ConfigOption
{
public :
std : : vector < int > values ;
std : : string serialize ( ) {
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 < < " , " ;
ss < < * it ;
}
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
this - > values . clear ( ) ;
std : : istringstream is ( str ) ;
std : : string item_str ;
while ( std : : getline ( is , item_str , ' , ' ) ) {
this - > values . push_back ( : : atoi ( item_str . c_str ( ) ) ) ;
}
} ;
} ;
2013-12-20 15:37:28 +00:00
class ConfigOptionString : public ConfigOption
{
public :
std : : string value ;
2013-12-20 19:54:11 +00:00
ConfigOptionString ( ) : value ( " " ) { } ;
2013-12-20 15:37:28 +00:00
operator std : : string ( ) const { return this - > value ; } ;
2013-12-20 19:54:11 +00:00
std : : string serialize ( ) {
std : : string str = this - > value ;
// s/\R/\\n/g
size_t pos = 0 ;
while ( ( pos = str . find ( " \n " , pos ) ) ! = std : : string : : npos | | ( pos = str . find ( " \r " , pos ) ) ! = std : : string : : npos ) {
str . replace ( pos , 1 , " \\ n " ) ;
pos + = 2 ; // length of "\\n"
}
return str ;
} ;
void deserialize ( std : : string str ) {
// s/\\n/\n/g
size_t pos = 0 ;
while ( ( pos = str . find ( " \\ n " , pos ) ) ! = std : : string : : npos ) {
str . replace ( pos , 2 , " \n " ) ;
pos + = 1 ; // length of "\n"
}
this - > value = str ;
} ;
2013-12-20 15:37:28 +00:00
} ;
class ConfigOptionFloatOrPercent : public ConfigOption
{
public :
float value ;
bool percent ;
2013-12-20 19:54:11 +00:00
ConfigOptionFloatOrPercent ( ) : value ( 0 ) , percent ( false ) { } ;
std : : string serialize ( ) {
std : : ostringstream ss ;
ss < < this - > value ;
std : : string s ( ss . str ( ) ) ;
if ( this - > percent ) s + = " % " ;
return s ;
} ;
void deserialize ( std : : string str ) {
if ( str . find_first_of ( " % " ) ! = std : : string : : npos ) {
sscanf ( str . c_str ( ) , " %f%% " , & this - > value ) ;
this - > percent = true ;
} else {
this - > value = : : atof ( str . c_str ( ) ) ;
this - > percent = false ;
}
} ;
} ;
class ConfigOptionPoint : public ConfigOption
{
public :
Pointf point ;
ConfigOptionPoint ( ) : point ( Pointf ( 0 , 0 ) ) { } ;
2013-12-20 20:32:18 +00:00
operator Pointf ( ) const { return this - > point ; } ;
2013-12-20 19:54:11 +00:00
std : : string serialize ( ) {
std : : ostringstream ss ;
ss < < this - > point . x ;
ss < < " , " ;
ss < < this - > point . y ;
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
sscanf ( str . c_str ( ) , " %f%*1[,x]%f " , & this - > point . x , & this - > point . y ) ;
} ;
2013-12-07 15:14:30 +00:00
} ;
2013-12-21 13:27:58 +00:00
class ConfigOptionPoints : public ConfigOption
{
public :
Pointfs points ;
std : : string serialize ( ) {
std : : ostringstream ss ;
for ( Pointfs : : const_iterator it = this - > points . begin ( ) ; it ! = this - > points . end ( ) ; + + it ) {
if ( it - this - > points . begin ( ) ! = 0 ) ss < < " , " ;
ss < < it - > x ;
ss < < " x " ;
ss < < it - > y ;
}
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
this - > points . clear ( ) ;
std : : istringstream is ( str ) ;
std : : string point_str ;
while ( std : : getline ( is , point_str , ' , ' ) ) {
Pointf point ;
sscanf ( point_str . c_str ( ) , " %fx%f " , & point . x , & point . y ) ;
this - > points . push_back ( point ) ;
}
} ;
} ;
2013-12-20 20:32:18 +00:00
class ConfigOptionBool : public ConfigOption
{
public :
bool value ;
ConfigOptionBool ( ) : value ( false ) { } ;
operator bool ( ) const { return this - > value ; } ;
std : : string serialize ( ) {
return std : : string ( this - > value ? " 1 " : " 0 " ) ;
} ;
void deserialize ( std : : string str ) {
this - > value = ( str . compare ( " 1 " ) = = 0 ) ;
} ;
} ;
2013-12-21 13:27:58 +00:00
class ConfigOptionBools : public ConfigOption
{
public :
std : : vector < bool > values ;
std : : string serialize ( ) {
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 < < " , " ;
ss < < ( * it ? " 1 " : " 0 " ) ;
}
return ss . str ( ) ;
} ;
void deserialize ( std : : string str ) {
this - > values . clear ( ) ;
std : : istringstream is ( str ) ;
std : : string item_str ;
while ( std : : getline ( is , item_str , ' , ' ) ) {
this - > values . push_back ( item_str . compare ( " 1 " ) = = 0 ) ;
}
} ;
2013-12-20 20:32:18 +00:00
} ;
2013-12-21 09:46:43 +00:00
template < class T >
class ConfigOptionEnum : public ConfigOption
2013-12-20 20:32:18 +00:00
{
public :
2013-12-21 09:46:43 +00:00
T value ;
2013-12-20 20:32:18 +00:00
2013-12-21 09:46:43 +00:00
operator T ( ) const { return this - > value ; } ;
2013-12-20 20:32:18 +00:00
2013-12-21 13:48:25 +00:00
std : : string serialize ( ) {
typename std : : map < std : : string , T > enum_keys_map = ConfigOptionEnum < T > : : get_enum_values ( ) ;
for ( typename std : : map < std : : string , T > : : iterator it = enum_keys_map . begin ( ) ; it ! = enum_keys_map . end ( ) ; + + it ) {
if ( it - > second = = this - > value ) return it - > first ;
}
return " " ;
} ;
void deserialize ( std : : string str ) {
typename std : : map < std : : string , T > enum_keys_map = ConfigOptionEnum < T > : : get_enum_values ( ) ;
assert ( enum_keys_map . count ( str ) > 0 ) ;
this - > value = enum_keys_map [ str ] ;
} ;
2013-12-21 09:46:43 +00:00
static std : : map < std : : string , T > get_enum_values ( ) ;
} ;
2013-12-20 20:32:18 +00:00
2013-12-21 13:27:58 +00:00
enum GCodeFlavor {
gcfRepRap , gcfTeacup , gcfMakerWare , gcfSailfish , gcfMach3 , gcfNoExtrusion ,
} ;
2013-12-21 09:46:43 +00:00
typedef ConfigOptionEnum < GCodeFlavor > ConfigOptionEnumGCodeFlavor ;
2013-12-21 13:27:58 +00:00
// we declare this as inline to keep it in this file along with all other option definitions
template < > inline std : : map < std : : string , GCodeFlavor > ConfigOptionEnum < GCodeFlavor > : : get_enum_values ( ) {
std : : map < std : : string , GCodeFlavor > keys_map ;
keys_map [ " reprap " ] = gcfRepRap ;
keys_map [ " teacup " ] = gcfTeacup ;
keys_map [ " makerware " ] = gcfMakerWare ;
keys_map [ " sailfish " ] = gcfSailfish ;
keys_map [ " mach3 " ] = gcfMach3 ;
keys_map [ " no-extrusion " ] = gcfNoExtrusion ;
return keys_map ;
}
2013-12-07 15:14:30 +00:00
enum ConfigOptionType {
coFloat ,
2013-12-21 13:27:58 +00:00
coFloats ,
2013-12-07 15:14:30 +00:00
coInt ,
2013-12-21 13:27:58 +00:00
coInts ,
2013-12-07 15:14:30 +00:00
coString ,
2013-12-20 15:37:28 +00:00
coFloatOrPercent ,
2013-12-20 19:54:11 +00:00
coPoint ,
2013-12-21 13:27:58 +00:00
coPoints ,
2013-12-20 20:32:18 +00:00
coBool ,
2013-12-21 13:27:58 +00:00
coBools ,
2013-12-21 09:46:43 +00:00
coEnumGCodeFlavor ,
2013-12-07 15:14:30 +00:00
} ;
class ConfigOptionDef
{
public :
ConfigOptionType type ;
std : : string label ;
std : : string tooltip ;
2013-12-20 19:54:11 +00:00
std : : string ratio_over ;
2013-12-07 15:14:30 +00:00
} ;
typedef std : : map < t_config_option_key , ConfigOptionDef > t_optiondef_map ;
2013-12-20 19:54:11 +00:00
ConfigOptionDef * get_config_option_def ( const t_config_option_key opt_key ) ;
2013-12-07 15:14:30 +00:00
class ConfigBase
{
public :
2013-12-20 19:54:11 +00:00
virtual ConfigOption * option ( const t_config_option_key opt_key , bool create = false ) = 0 ;
2013-12-07 15:14:30 +00:00
virtual void keys ( t_config_option_keys * keys ) = 0 ;
2013-12-20 15:37:28 +00:00
void apply ( ConfigBase & other , bool ignore_nonexistent = false ) ;
2013-12-20 19:54:11 +00:00
std : : string serialize ( const t_config_option_key opt_key ) ;
void set_deserialize ( const t_config_option_key opt_key , std : : string str ) ;
float get_abs_value ( const t_config_option_key opt_key ) ;
2013-12-07 15:14:30 +00:00
2013-12-20 15:37:28 +00:00
# ifdef SLIC3RXS
SV * get ( t_config_option_key opt_key ) ;
2013-12-20 19:54:11 +00:00
void set ( t_config_option_key opt_key , SV * value ) ;
2013-12-20 15:37:28 +00:00
# endif
2013-12-07 15:14:30 +00:00
} ;
class DynamicConfig : public ConfigBase
{
public :
2013-12-20 19:54:11 +00:00
DynamicConfig ( ) { } ;
~ DynamicConfig ( ) ;
ConfigOption * option ( const t_config_option_key opt_key , bool create = false ) ;
2013-12-20 15:37:28 +00:00
void keys ( t_config_option_keys * keys ) ;
bool has ( const t_config_option_key opt_key ) const ;
2013-12-07 15:14:30 +00:00
2013-12-20 15:37:28 +00:00
private :
2013-12-20 19:54:11 +00:00
DynamicConfig ( const DynamicConfig & other ) ; // we disable this by making it private and unimplemented
DynamicConfig & operator = ( const DynamicConfig & other ) ; // we disable this by making it private and unimplemented
2013-12-20 15:37:28 +00:00
typedef std : : map < t_config_option_key , ConfigOption * > t_options_map ;
t_options_map options ;
2013-12-07 15:14:30 +00:00
} ;
class StaticConfig : public ConfigBase
{
public :
2013-12-20 15:37:28 +00:00
void keys ( t_config_option_keys * keys ) ;
2013-12-07 15:14:30 +00:00
} ;
class FullConfig : public StaticConfig
{
public :
2013-12-21 09:46:43 +00:00
ConfigOptionFloat layer_height ;
ConfigOptionFloatOrPercent first_layer_height ;
ConfigOptionInt perimeters ;
ConfigOptionString extrusion_axis ;
ConfigOptionPoint print_center ;
2013-12-21 13:27:58 +00:00
ConfigOptionPoints extruder_offset ;
2013-12-21 09:46:43 +00:00
ConfigOptionString notes ;
ConfigOptionBool use_relative_e_distances ;
ConfigOptionEnumGCodeFlavor gcode_flavor ;
2013-12-21 13:27:58 +00:00
ConfigOptionFloats nozzle_diameter ;
ConfigOptionInts temperature ;
ConfigOptionBools wipe ;
2013-12-07 15:14:30 +00:00
2013-12-20 19:54:11 +00:00
ConfigOption * option ( const t_config_option_key opt_key , bool create = false ) {
assert ( ! create ) ; // can't create options in StaticConfig
2013-12-07 15:14:30 +00:00
if ( opt_key = = " layer_height " ) return & this - > layer_height ;
if ( opt_key = = " first_layer_height " ) return & this - > first_layer_height ;
2013-12-20 19:54:11 +00:00
if ( opt_key = = " perimeters " ) return & this - > perimeters ;
if ( opt_key = = " extrusion_axis " ) return & this - > extrusion_axis ;
if ( opt_key = = " print_center " ) return & this - > print_center ;
2013-12-21 13:27:58 +00:00
if ( opt_key = = " extruder_offset " ) return & this - > extruder_offset ;
2013-12-20 19:54:11 +00:00
if ( opt_key = = " notes " ) return & this - > notes ;
2013-12-20 20:32:18 +00:00
if ( opt_key = = " use_relative_e_distances " ) return & this - > use_relative_e_distances ;
2013-12-21 09:46:43 +00:00
if ( opt_key = = " gcode_flavor " ) return & this - > gcode_flavor ;
2013-12-21 13:27:58 +00:00
if ( opt_key = = " nozzle_diameter " ) return & this - > nozzle_diameter ;
if ( opt_key = = " temperature " ) return & this - > temperature ;
if ( opt_key = = " wipe " ) return & this - > wipe ;
2013-12-07 15:14:30 +00:00
return NULL ;
} ;
} ;
2013-12-20 15:37:28 +00:00
static t_optiondef_map _build_optiondef_map ( ) {
t_optiondef_map Options ;
Options [ " layer_height " ] . type = coFloat ;
Options [ " layer_height " ] . label = " Layer height " ;
Options [ " layer_height " ] . tooltip = " This setting controls the height (and thus the total number) of the slices/layers. Thinner layers give better accuracy but take more time to print. " ;
Options [ " first_layer_height " ] . type = coFloatOrPercent ;
2013-12-20 19:54:11 +00:00
Options [ " first_layer_height " ] . ratio_over = " layer_height " ;
Options [ " perimeters " ] . type = coInt ;
Options [ " perimeters " ] . label = " Perimeters (minimum) " ;
Options [ " perimeters " ] . tooltip = " This option sets the number of perimeters to generate for each layer. Note that Slic3r may increase this number automatically when it detects sloping surfaces which benefit from a higher number of perimeters if the Extra Perimeters option is enabled. " ;
Options [ " extrusion_axis " ] . type = coString ;
Options [ " print_center " ] . type = coPoint ;
2013-12-21 13:27:58 +00:00
Options [ " extruder_offset " ] . type = coPoints ;
2013-12-20 19:54:11 +00:00
Options [ " notes " ] . type = coString ;
2013-12-20 20:32:18 +00:00
Options [ " use_relative_e_distances " ] . type = coBool ;
2013-12-21 09:46:43 +00:00
Options [ " gcode_flavor " ] . type = coEnumGCodeFlavor ;
2013-12-21 13:27:58 +00:00
Options [ " nozzle_diameter " ] . type = coFloats ;
Options [ " temperature " ] . type = coInts ;
Options [ " wipe " ] . type = coBools ;
2013-12-20 15:37:28 +00:00
return Options ;
}
2013-12-21 09:46:43 +00:00
2013-12-20 15:37:28 +00:00
static FullConfig _build_default_config ( ) {
FullConfig defconf ;
2013-12-20 20:32:18 +00:00
defconf . layer_height . value = 0.4 ;
defconf . first_layer_height . value = 0.35 ;
defconf . first_layer_height . percent = false ;
defconf . perimeters . value = 3 ;
defconf . extrusion_axis . value = " E " ;
defconf . print_center . point = Pointf ( 100 , 100 ) ;
2013-12-21 13:27:58 +00:00
defconf . extruder_offset . points . push_back ( Pointf ( 0 , 0 ) ) ;
2013-12-20 20:32:18 +00:00
defconf . notes . value = " " ;
defconf . use_relative_e_distances . value = false ;
2013-12-21 09:46:43 +00:00
defconf . gcode_flavor . value = gcfRepRap ;
2013-12-21 13:27:58 +00:00
defconf . nozzle_diameter . values . push_back ( 0.5 ) ;
defconf . temperature . values . push_back ( 200 ) ;
defconf . wipe . values . push_back ( true ) ;
2013-12-20 15:37:28 +00:00
return defconf ;
}
2013-12-07 15:14:30 +00:00
}
# endif