Code documentation of options and functions for libslic3r internals, ported from Prusa3d fork (written by @bubnikv)

This commit is contained in:
Joseph Lenox 2016-11-20 22:20:19 -06:00 committed by Alessandro Ranellucci
parent 38291d3c80
commit d9a92bc4dc
16 changed files with 243 additions and 31 deletions

View File

@ -14,6 +14,11 @@ using ClipperLib::jtSquare;
namespace Slic3r { namespace Slic3r {
// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library.
//FIXME Vojtech: Better to use a power of 2 coefficient and to use bit shifts for scaling.
// How about 2^17=131072?
// By the way, is the scalling needed at all? Cura runs all the computation with a fixed point precision of 1um, while Slic3r scales to 1nm,
// further scaling by 10e5 brings us to
#define CLIPPER_OFFSET_SCALE 100000.0 #define CLIPPER_OFFSET_SCALE 100000.0
//----------------------------------------------------------- //-----------------------------------------------------------

View File

@ -140,6 +140,8 @@ ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str,
return opt->deserialize(str, append); return opt->deserialize(str, append);
} }
// 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 double
ConfigBase::get_abs_value(const t_config_option_key &opt_key) { ConfigBase::get_abs_value(const t_config_option_key &opt_key) {
ConfigOption* opt = this->option(opt_key, false); ConfigOption* opt = this->option(opt_key, false);
@ -157,6 +159,8 @@ 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 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) {
// get stored option value // get stored option value
@ -392,7 +396,6 @@ StaticConfig::set_defaults()
t_config_option_keys keys = this->keys(); t_config_option_keys keys = this->keys();
for (t_config_option_keys::const_iterator it = keys.begin(); it != keys.end(); ++it) { for (t_config_option_keys::const_iterator it = keys.begin(); it != keys.end(); ++it) {
const ConfigOptionDef* def = this->def->get(*it); const ConfigOptionDef* def = this->def->get(*it);
if (def->default_value != NULL) if (def->default_value != NULL)
this->option(*it)->set(*def->default_value); this->option(*it)->set(*def->default_value);
} }

View File

@ -15,9 +15,11 @@
namespace Slic3r { namespace Slic3r {
// Name of the configuration option.
typedef std::string t_config_option_key; typedef std::string t_config_option_key;
typedef std::vector<std::string> t_config_option_keys; typedef std::vector<std::string> t_config_option_keys;
// A generic value of a configuration option.
class ConfigOption { class ConfigOption {
public: public:
virtual ~ConfigOption() {}; virtual ~ConfigOption() {};
@ -34,6 +36,7 @@ class ConfigOption {
friend bool operator!= (const ConfigOption &a, const ConfigOption &b); friend bool operator!= (const ConfigOption &a, const ConfigOption &b);
}; };
// Value of a single valued option (bool, int, float, string, point, enum)
template <class T> template <class T>
class ConfigOptionSingle : public ConfigOption { class ConfigOptionSingle : public ConfigOption {
public: public:
@ -47,12 +50,14 @@ class ConfigOptionSingle : public ConfigOption {
}; };
}; };
// Value of a vector valued option (bools, ints, floats, strings, points)
class ConfigOptionVectorBase : public ConfigOption { class ConfigOptionVectorBase : public ConfigOption {
public: public:
virtual ~ConfigOptionVectorBase() {}; virtual ~ConfigOptionVectorBase() {};
virtual std::vector<std::string> vserialize() const = 0; virtual std::vector<std::string> vserialize() const = 0;
}; };
// Value of a vector valued option (bools, ints, floats, strings, points), template
template <class T> template <class T>
class ConfigOptionVector : public ConfigOptionVectorBase class ConfigOptionVector : public ConfigOptionVectorBase
{ {
@ -482,6 +487,7 @@ class ConfigOptionBools : public ConfigOptionVector<bool>
}; };
}; };
// Map from an enum name to an enum integer value.
typedef std::map<std::string,int> t_config_enum_values; typedef std::map<std::string,int> t_config_enum_values;
template <class T> template <class T>
@ -508,11 +514,14 @@ class ConfigOptionEnum : public ConfigOptionSingle<T>
return true; return true;
}; };
// Map from an enum name to an enum integer value.
//FIXME The map is called often, it shall be initialized statically.
static t_config_enum_values get_enum_values(); static t_config_enum_values get_enum_values();
}; };
/* We use this one in DynamicConfig objects, otherwise it's better to use // Generic enum configuration value.
the specialized ConfigOptionEnum<T> containers. */ // We use this one in DynamicConfig objects when creating a config value object for ConfigOptionType == coEnum.
// In the StaticConfig, it is better to use the specialized ConfigOptionEnum<T> containers.
class ConfigOptionEnumGeneric : public ConfigOptionInt class ConfigOptionEnumGeneric : public ConfigOptionInt
{ {
public: public:
@ -532,51 +541,105 @@ class ConfigOptionEnumGeneric : public ConfigOptionInt
}; };
}; };
// Type of a configuration value.
enum ConfigOptionType { enum ConfigOptionType {
coNone, coNone,
// single float
coFloat, coFloat,
// vector of floats
coFloats, coFloats,
// single int
coInt, coInt,
// vector of ints
coInts, coInts,
// single string
coString, coString,
// vector of strings
coStrings, coStrings,
// percent value. Currently only used for infill.
coPercent, coPercent,
// a fraction or an absolute value
coFloatOrPercent, coFloatOrPercent,
// single 2d point. Currently not used.
coPoint, coPoint,
coPoint3, // vector of 2d points. Currently used for the definition of the print bed and for the extruder offsets.
coPoints, coPoints,
coPoint3,
// single boolean value
coBool, coBool,
// vector of boolean values
coBools, coBools,
// a generic enum
coEnum, coEnum,
}; };
// Definition of a configuration value for the purpose of GUI presentation, editing, value mapping and config file handling.
class ConfigOptionDef class ConfigOptionDef
{ {
public: public:
// What type? bool, int, string etc.
ConfigOptionType type; ConfigOptionType type;
// Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor.
ConfigOption* default_value; ConfigOption* default_value;
// Usually empty.
// Special values - "i_enum_open", "f_enum_open" to provide combo box for int or float selection,
// "select_open" - to open a selection dialog (currently only a serial port selection).
std::string gui_type; std::string gui_type;
// Usually empty. Otherwise "serialized" or "show_value"
// The flags may be combined.
// "serialized" - vector valued option is entered in a single edit field. Values are separated by a semicolon.
// "show_value" - even if enum_values / enum_labels are set, still display the value, not the enum label.
std::string gui_flags; std::string gui_flags;
// Label of the GUI input field.
// In case the GUI input fields are grouped in some views, the label defines a short label of a grouped value,
// while full_label contains a label of a stand-alone field.
// The full label is shown, when adding an override parameter for an object or a modified object.
std::string label; std::string label;
std::string full_label; std::string full_label;
// Category of a configuration field, from the GUI perspective.
// One of: "Layers and Perimeters", "Infill", "Support material", "Speed", "Extruders", "Advanced", "Extrusion Width"
std::string category; std::string category;
// A tooltip text shown in the GUI.
std::string tooltip; std::string tooltip;
// Text right from the input field, usually a unit of measurement.
std::string sidetext; std::string sidetext;
// Format of this parameter on a command line.
std::string cli; std::string cli;
// Set for type == coFloatOrPercent.
// It provides a link to a configuration value, of which this option provides a ratio.
// For example,
// For example external_perimeter_speed may be defined as a fraction of perimeter_speed.
t_config_option_key ratio_over; t_config_option_key ratio_over;
// True for multiline strings.
bool multiline; bool multiline;
// For text input: If true, the GUI text box spans the complete page width.
bool full_width; bool full_width;
// Not editable. Currently only used for the display of the number of threads.
bool readonly; bool readonly;
// Height of a multiline GUI text box.
int height; int height;
// Optional width of an input field.
int width; int width;
// <min, max> limit of a numeric input.
// If not set, the <min, max> is set to <INT_MIN, INT_MAX>
// By setting min=0, only nonnegative input is allowed.
int min; int min;
int max; int max;
// Legacy names for this configuration option.
// Used when parsing legacy configuration file.
std::vector<t_config_option_key> aliases; std::vector<t_config_option_key> aliases;
// Sometimes a single value may well define multiple values in a "beginner" mode.
// Currently used for aliasing "solid_layers" to "top_solid_layers", "bottom_solid_layers".
std::vector<t_config_option_key> shortcut; std::vector<t_config_option_key> shortcut;
// Definition of values / labels for a combo box.
// Mostly used for enums (when type == coEnum), but may be used for ints resp. floats, if gui_type is set to "i_enum_open" resp. "f_enum_open".
std::vector<std::string> enum_values; std::vector<std::string> enum_values;
std::vector<std::string> enum_labels; std::vector<std::string> enum_labels;
// For enums (when type == coEnum). Maps enum_values to enums.
// Initialized by ConfigOptionEnum<xxx>::get_enum_values()
t_config_enum_values enum_keys_map; t_config_enum_values enum_keys_map;
ConfigOptionDef() : type(coNone), default_value(NULL), ConfigOptionDef() : type(coNone), default_value(NULL),
multiline(false), full_width(false), readonly(false), multiline(false), full_width(false), readonly(false),
height(-1), width(-1), min(INT_MIN), max(INT_MAX) {}; height(-1), width(-1), min(INT_MIN), max(INT_MAX) {};
@ -587,8 +650,14 @@ class ConfigOptionDef
ConfigOptionDef& operator= (ConfigOptionDef other); ConfigOptionDef& operator= (ConfigOptionDef other);
}; };
// Map from a config option name to its definition.
// The definition does not carry an actual value of the config option, only its constant default value.
// t_config_option_key is std::string
typedef std::map<t_config_option_key,ConfigOptionDef> t_optiondef_map; typedef std::map<t_config_option_key,ConfigOptionDef> t_optiondef_map;
// Definition of configuration values for the purpose of GUI presentation, editing, value mapping and config file handling.
// The configuration definition is static: It does not carry the actual configuration values,
// but it carries the defaults of the configuration values.
class ConfigDef class ConfigDef
{ {
public: public:
@ -598,9 +667,14 @@ class ConfigDef
void merge(const ConfigDef &other); void merge(const ConfigDef &other);
}; };
// An abstract configuration store.
class ConfigBase class ConfigBase
{ {
public: public:
// Definition of configuration values for the purpose of GUI presentation, editing, value mapping and config file handling.
// The configuration definition is static: It does not carry the actual configuration values,
// but it carries the defaults of the configuration values.
// ConfigBase does not own ConfigDef, it only references it.
const ConfigDef* def; const ConfigDef* def;
ConfigBase() : def(NULL) {}; ConfigBase() : def(NULL) {};
@ -623,6 +697,8 @@ class ConfigBase
void save(const std::string &file) const; void save(const std::string &file) const;
}; };
// Configuration store with dynamic number of configuration values.
// In Slic3r, the dynamic config is mostly used at the user interface layer.
class DynamicConfig : public virtual ConfigBase class DynamicConfig : public virtual ConfigBase
{ {
public: public:
@ -643,13 +719,20 @@ class DynamicConfig : public virtual ConfigBase
t_options_map options; t_options_map options;
}; };
// Configuration store with a static definition of configuration values.
// In Slic3r, the static configuration stores are during the slicing / g-code generation for efficiency reasons,
// because the configuration values could be accessed directly.
class StaticConfig : public virtual ConfigBase class StaticConfig : public virtual ConfigBase
{ {
public: public:
StaticConfig() : ConfigBase() {}; StaticConfig() : ConfigBase() {};
// Gets list of config option names for each config option of this->def, which has a static counter-part defined by the derived object
// and which could be resolved by this->optptr(key) call.
t_config_option_keys keys() const; t_config_option_keys keys() const;
//virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) = 0; // Set all statically defined config options to their defaults defined by this->def.
void set_defaults(); void set_defaults();
// The derived class has to implement optptr to resolve a static configuration value.
// virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) = 0;
}; };
class UnknownOptionException : public std::exception {}; class UnknownOptionException : public std::exception {};

View File

@ -76,12 +76,19 @@ class GCode {
Wipe wipe; Wipe wipe;
AvoidCrossingPerimeters avoid_crossing_perimeters; AvoidCrossingPerimeters avoid_crossing_perimeters;
bool enable_loop_clipping; bool enable_loop_clipping;
// If enabled, the G-code generator will put following comments at the ends
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _BRIDGE_FAN_START, _BRIDGE_FAN_END
// Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module.
bool enable_cooling_markers; bool enable_cooling_markers;
size_t layer_count; size_t layer_count;
int layer_index; // just a counter int layer_index; // just a counter
const Layer* layer; const Layer* layer;
std::map<const PrintObject*,Point> _seam_position; std::map<const PrintObject*,Point> _seam_position;
bool first_layer; // this flag triggers first layer speeds bool first_layer; // this flag triggers first layer speeds
// Used by the CoolingBuffer.pm Perl module to calculate time spent per layer change.
// This value is not quite precise. First it only accouts for extrusion moves and travel moves,
// it does not account for wipe, retract / unretract moves.
// second it does not account for the velocity profiles of the printer.
float elapsed_time; // seconds float elapsed_time; // seconds
double volumetric_speed; double volumetric_speed;

View File

@ -162,6 +162,10 @@ Layer::any_bottom_region_slice_contains(const T &item) const
} }
template bool Layer::any_bottom_region_slice_contains<Polyline>(const Polyline &item) const; template bool Layer::any_bottom_region_slice_contains<Polyline>(const Polyline &item) const;
// Here the perimeters are created cummulatively for all layer regions sharing the same parameters influencing the perimeters.
// The perimeter paths and the thin fills (ExtrusionEntityCollection) are assigned to the first compatible layer region.
// The resulting fill surface is split back among the originating regions.
void void
Layer::make_perimeters() Layer::make_perimeters()
{ {

View File

@ -76,6 +76,7 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection*
); );
if (this->layer()->lower_layer != NULL) if (this->layer()->lower_layer != NULL)
// Cummulative sum of polygons over all the regions.
g.lower_slices = &this->layer()->lower_layer->slices; g.lower_slices = &this->layer()->lower_layer->slices;
g.layer_id = this->layer()->id(); g.layer_id = this->layer()->id();

View File

@ -28,10 +28,18 @@ typedef std::vector<ModelObject*> ModelObjectPtrs;
typedef std::vector<ModelVolume*> ModelVolumePtrs; typedef std::vector<ModelVolume*> ModelVolumePtrs;
typedef std::vector<ModelInstance*> ModelInstancePtrs; typedef std::vector<ModelInstance*> ModelInstancePtrs;
// The print bed content.
// Description of a triangular model with multiple materials, multiple instances with various affine transformations
// and with multiple modifier meshes.
// A model groups multiple objects, each object having possibly multiple instances,
// all objects may share mutliple materials.
class Model class Model
{ {
public: public:
// Materials are owned by a model and referenced by objects through t_model_material_id.
// Single material may be shared by multiple models.
ModelMaterialMap materials; ModelMaterialMap materials;
// Objects are owned by a model. Each model may have multiple instances, each instance having its own transformation (shift, scale, rotation).
ModelObjectPtrs objects; ModelObjectPtrs objects;
Model(); Model();
@ -66,34 +74,48 @@ class Model
void print_info() const; void print_info() const;
}; };
// Material, which may be shared across multiple ModelObjects of a single Model.
class ModelMaterial class ModelMaterial
{ {
friend class Model; friend class Model;
public: public:
// Attributes are defined by the AMF file format, but they don't seem to be used by Slic3r for any purpose.
t_model_material_attributes attributes; t_model_material_attributes attributes;
// Dynamic configuration storage for the object specific configuration values, overriding the global configuration.
DynamicPrintConfig config; DynamicPrintConfig config;
Model* get_model() const { return this->model; }; Model* get_model() const { return this->model; };
void apply(const t_model_material_attributes &attributes); void apply(const t_model_material_attributes &attributes);
private: private:
// Parent, owning this material.
Model* model; Model* model;
ModelMaterial(Model *model); ModelMaterial(Model *model);
ModelMaterial(Model *model, const ModelMaterial &other); ModelMaterial(Model *model, const ModelMaterial &other);
}; };
// A printable object, possibly having multiple print volumes (each with its own set of parameters and materials),
// and possibly having multiple modifier volumes, each modifier volume with its set of parameters and materials.
// Each ModelObject may be instantiated mutliple times, each instance having different placement on the print bed,
// different rotation and different uniform scaling.
class ModelObject class ModelObject
{ {
friend class Model; friend class Model;
public: public:
std::string name; std::string name;
std::string input_file; std::string input_file;
// Instances of this ModelObject. Each instance defines a shift on the print bed, rotation around the Z axis and a uniform scaling.
// Instances are owned by this ModelObject.
ModelInstancePtrs instances; ModelInstancePtrs instances;
// Printable and modifier volumes, each with its material ID and a set of override parameters.
// ModelVolumes are owned by this ModelObject.
ModelVolumePtrs volumes; ModelVolumePtrs volumes;
// Configuration parameters specific to a single ModelObject, overriding the global Slic3r settings.
DynamicPrintConfig config; DynamicPrintConfig config;
// Variation of a layer thickness for spans of Z coordinates.
t_layer_height_ranges layer_height_ranges; t_layer_height_ranges layer_height_ranges;
/* This vector accumulates the total translation applied to the object by the /* This vector accumulates the total translation applied to the object by the
center_around_origin() method. Callers might want to apply the same translation center_around_origin() method. Callers might want to apply the same translation
to new volumes before adding them to this object in order to preserve alignment to new volumes before adding them to this object in order to preserve alignment
@ -142,6 +164,7 @@ class ModelObject
void print_info() const; void print_info() const;
private: private:
// Parent object, owning this ModelObject.
Model* model; Model* model;
ModelObject(Model *model); ModelObject(Model *model);
@ -151,15 +174,22 @@ class ModelObject
~ModelObject(); ~ModelObject();
}; };
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.
// ModelVolume instances are owned by a ModelObject.
class ModelVolume class ModelVolume
{ {
friend class ModelObject; friend class ModelObject;
public: public:
std::string name; std::string name;
// The triangular model.
TriangleMesh mesh; TriangleMesh mesh;
// Configuration parameters specific to an object model geometry or a modifier volume,
// overriding the global Slic3r settings and the ModelObject settings.
DynamicPrintConfig config; DynamicPrintConfig config;
// Is it an object to be printed, or a modifier volume?
bool modifier; bool modifier;
// A parent object owning this modifier volume.
ModelObject* get_object() const { return this->object; }; ModelObject* get_object() const { return this->object; };
t_model_material_id material_id() const; t_model_material_id material_id() const;
void material_id(t_model_material_id material_id); void material_id(t_model_material_id material_id);
@ -169,6 +199,7 @@ class ModelVolume
ModelMaterial* assign_unique_material(); ModelMaterial* assign_unique_material();
private: private:
// Parent object owning this ModelVolume.
ModelObject* object; ModelObject* object;
t_model_material_id _material_id; t_model_material_id _material_id;
@ -178,19 +209,25 @@ class ModelVolume
void swap(ModelVolume &other); void swap(ModelVolume &other);
}; };
// A single instance of a ModelObject.
// Knows the affine transformation of an object.
class ModelInstance class ModelInstance
{ {
friend class ModelObject; friend class ModelObject;
public: public:
double rotation; // in radians around mesh center point double rotation; // Rotation around the Z axis, in radians around mesh center point
double scaling_factor; double scaling_factor;
Pointf offset; // in unscaled coordinates Pointf offset; // in unscaled coordinates
ModelObject* get_object() const { return this->object; }; ModelObject* get_object() const { return this->object; };
// To be called on an external mesh
void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const; void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const;
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
void transform_polygon(Polygon* polygon) const; void transform_polygon(Polygon* polygon) const;
private: private:
// Parent object, owning this instance.
ModelObject* object; ModelObject* object;
ModelInstance(ModelObject *object); ModelInstance(ModelObject *object);

View File

@ -42,6 +42,6 @@ class MultiPoint
static Points _douglas_peucker(const Points &points, const double tolerance); static Points _douglas_peucker(const Points &points, const double tolerance);
}; };
} } // namespace Slic3r
#endif #endif

View File

@ -535,12 +535,6 @@ PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRo
return coll; return coll;
} }
bool
PerimeterGeneratorLoop::is_external() const
{
return this->depth == 0;
}
bool bool
PerimeterGeneratorLoop::is_internal_contour() const PerimeterGeneratorLoop::is_internal_contour() const
{ {

View File

@ -11,25 +11,33 @@
namespace Slic3r { namespace Slic3r {
class PerimeterGeneratorLoop; // Hierarchy of perimeters.
typedef std::vector<PerimeterGeneratorLoop> PerimeterGeneratorLoops;
class PerimeterGeneratorLoop { class PerimeterGeneratorLoop {
public: public:
// Polygon of this contour.
Polygon polygon; Polygon polygon;
// Is it a contour or a hole?
// Contours are CCW oriented, holes are CW oriented.
bool is_contour; bool is_contour;
// Depth in the hierarchy. External perimeter has depth = 0. An external perimeter could be both a contour and a hole.
unsigned short depth; unsigned short depth;
// Children contour, may be both CCW and CW oriented (outer contours or holes).
std::vector<PerimeterGeneratorLoop> children; std::vector<PerimeterGeneratorLoop> children;
PerimeterGeneratorLoop(Polygon polygon, unsigned short depth) PerimeterGeneratorLoop(Polygon polygon, unsigned short depth)
: polygon(polygon), is_contour(false), depth(depth) : polygon(polygon), is_contour(false), depth(depth)
{}; {};
bool is_external() const; // External perimeter. It may be CCW or CW oriented (outer contour or hole contour).
bool is_external() const { return this->depth == 0; }
// An island, which may have holes, but it does not have another internal island.
bool is_internal_contour() const; bool is_internal_contour() const;
}; };
typedef std::vector<PerimeterGeneratorLoop> PerimeterGeneratorLoops;
class PerimeterGenerator { class PerimeterGenerator {
public: public:
// Inputs:
const SurfaceCollection* slices; const SurfaceCollection* slices;
const ExPolygonCollection* lower_slices; const ExPolygonCollection* lower_slices;
double layer_height; double layer_height;
@ -41,14 +49,26 @@ class PerimeterGenerator {
PrintRegionConfig* config; PrintRegionConfig* config;
PrintObjectConfig* object_config; PrintObjectConfig* object_config;
PrintConfig* print_config; PrintConfig* print_config;
// Outputs:
ExtrusionEntityCollection* loops; ExtrusionEntityCollection* loops;
ExtrusionEntityCollection* gap_fill; ExtrusionEntityCollection* gap_fill;
SurfaceCollection* fill_surfaces; SurfaceCollection* fill_surfaces;
PerimeterGenerator(const SurfaceCollection* slices, double layer_height, Flow flow, PerimeterGenerator(
PrintRegionConfig* config, PrintObjectConfig* object_config, // Input:
PrintConfig* print_config, ExtrusionEntityCollection* loops, const SurfaceCollection* slices,
ExtrusionEntityCollection* gap_fill, SurfaceCollection* fill_surfaces) double layer_height,
Flow flow,
PrintRegionConfig* config,
PrintObjectConfig* object_config,
PrintConfig* print_config,
// Output:
// Loops with the external thin walls
ExtrusionEntityCollection* loops,
// Gaps without the thin walls
ExtrusionEntityCollection* gap_fill,
// Infills without the gap fills
SurfaceCollection* fill_surfaces)
: slices(slices), lower_slices(NULL), layer_height(layer_height), : slices(slices), lower_slices(NULL), layer_height(layer_height),
layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow), layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow),
overhang_flow(flow), solid_infill_flow(flow), overhang_flow(flow), solid_infill_flow(flow),

View File

@ -59,6 +59,7 @@ Polygon::split_at_vertex(const Point &point) const
return Polyline(); return Polyline();
} }
// Split a closed polygon into an open polyline, with the split point duplicated at both ends.
Polyline Polyline
Polygon::split_at_index(int index) const Polygon::split_at_index(int index) const
{ {
@ -71,6 +72,7 @@ Polygon::split_at_index(int index) const
return polyline; return polyline;
} }
// Split a closed polygon into an open polyline, with the split point duplicated at both ends.
Polyline Polyline
Polygon::split_at_first_point() const Polygon::split_at_first_point() const
{ {
@ -127,6 +129,8 @@ Polygon::is_valid() const
return this->points.size() >= 3; return this->points.size() >= 3;
} }
// Does an unoriented polygon contain a point?
// Tested by counting intersections along a horizontal line.
bool bool
Polygon::contains(const Point &point) const Polygon::contains(const Point &point) const
{ {
@ -135,6 +139,8 @@ Polygon::contains(const Point &point) const
Points::const_iterator i = this->points.begin(); Points::const_iterator i = this->points.begin();
Points::const_iterator j = this->points.end() - 1; Points::const_iterator j = this->points.end() - 1;
for (; i != this->points.end(); j = i++) { for (; i != this->points.end(); j = i++) {
//FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point.y well.
// Does the ray with y == point.y intersect this line segment?
if ( ((i->y > point.y) != (j->y > point.y)) if ( ((i->y > point.y) != (j->y > point.y))
&& ((double)point.x < (double)(j->x - i->x) * (double)(point.y - i->y) / (double)(j->y - i->y) + (double)i->x) ) && ((double)point.x < (double)(j->x - i->x) * (double)(point.y - i->y) / (double)(j->y - i->y) + (double)i->x) )
result = !result; result = !result;

View File

@ -25,7 +25,9 @@ class Polygon : public MultiPoint {
Point last_point() const; Point last_point() const;
virtual Lines lines() const; virtual Lines lines() const;
Polyline split_at_vertex(const Point &point) const; Polyline split_at_vertex(const Point &point) const;
// Split a closed polygon into an open polyline, with the split point duplicated at both ends.
Polyline split_at_index(int index) const; Polyline split_at_index(int index) const;
// Split a closed polygon into an open polyline, with the split point duplicated at both ends.
Polyline split_at_first_point() const; Polyline split_at_first_point() const;
Points equally_spaced_points(double distance) const; Points equally_spaced_points(double distance) const;
double area() const; double area() const;
@ -34,6 +36,8 @@ class Polygon : public MultiPoint {
bool make_counter_clockwise(); bool make_counter_clockwise();
bool make_clockwise(); bool make_clockwise();
bool is_valid() const; bool is_valid() const;
// Does an unoriented polygon contain a point?
// Tested by counting intersections along a horizontal line.
bool contains(const Point &point) const; bool contains(const Point &point) const;
Polygons simplify(double tolerance) const; Polygons simplify(double tolerance) const;
void simplify(double tolerance, Polygons &polygons) const; void simplify(double tolerance, Polygons &polygons) const;

View File

@ -635,7 +635,7 @@ Print::validate() const
if (!object_height.empty() && object_height.back() > scale_(this->config.extruder_clearance_height.value)) if (!object_height.empty() && object_height.back() > scale_(this->config.extruder_clearance_height.value))
throw PrintValidationException("Some objects are too tall and cannot be printed without extruder collisions."); throw PrintValidationException("Some objects are too tall and cannot be printed without extruder collisions.");
} }
} } // end if (this->config.complete_objects)
if (this->config.spiral_vase) { if (this->config.spiral_vase) {
size_t total_copies_count = 0; size_t total_copies_count = 0;
@ -833,6 +833,7 @@ Print::auto_assign_extruders(ModelObject* model_object) const
size_t extruders = this->config.nozzle_diameter.values.size(); size_t extruders = this->config.nozzle_diameter.values.size();
for (ModelVolumePtrs::const_iterator v = model_object->volumes.begin(); v != model_object->volumes.end(); ++v) { for (ModelVolumePtrs::const_iterator v = model_object->volumes.begin(); v != model_object->volumes.end(); ++v) {
if (!(*v)->material_id().empty()) { if (!(*v)->material_id().empty()) {
//FIXME Vojtech: This assigns an extruder ID even to a modifier volume, if it has a material assigned.
size_t extruder_id = (v - model_object->volumes.begin()) + 1; size_t extruder_id = (v - model_object->volumes.begin()) + 1;
if (!(*v)->config.has("extruder")) if (!(*v)->config.has("extruder"))
(*v)->config.opt<ConfigOptionInt>("extruder", true)->value = extruder_id; (*v)->config.opt<ConfigOptionInt>("extruder", true)->value = extruder_id;

View File

@ -20,7 +20,7 @@ class Print;
class PrintObject; class PrintObject;
class ModelObject; class ModelObject;
// Print step IDs for keeping track of the print state.
enum PrintStep { enum PrintStep {
psSkirt, psBrim, psSkirt, psBrim,
}; };
@ -34,6 +34,7 @@ class PrintValidationException : public std::runtime_error {
PrintValidationException(const std::string &error) : std::runtime_error(error) {}; PrintValidationException(const std::string &error) : std::runtime_error(error) {};
}; };
// To be instantiated over PrintStep or PrintObjectStep enums.
template <class StepType> template <class StepType>
class PrintState class PrintState
{ {
@ -120,6 +121,7 @@ class PrintObject
size_t layer_count() const; size_t layer_count() const;
void clear_layers(); void clear_layers();
Layer* get_layer(int idx); Layer* get_layer(int idx);
// print_z: top of the layer; slice_z: center of the layer.
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
void delete_layer(int idx); void delete_layer(int idx);
@ -152,6 +154,7 @@ class PrintObject
typedef std::vector<PrintObject*> PrintObjectPtrs; typedef std::vector<PrintObject*> PrintObjectPtrs;
typedef std::vector<PrintRegion*> PrintRegionPtrs; typedef std::vector<PrintRegion*> PrintRegionPtrs;
// The complete print tray with possibly multiple objects.
class Print class Print
{ {
public: public:

View File

@ -1,3 +1,20 @@
// Configuration store of Slic3r.
//
// The configuration store is either static or dynamic.
// DynamicPrintConfig is used mainly at the user interface. while the StaticPrintConfig is used
// during the slicing and the g-code generation.
//
// The classes derived from StaticPrintConfig form a following hierarchy.
// Virtual inheritance is used for some of the parent objects.
//
// FullPrintConfig
// PrintObjectConfig
// PrintRegionConfig
// PrintConfig
// GCodeConfig
// HostConfig
//
#ifndef slic3r_PrintConfig_hpp_ #ifndef slic3r_PrintConfig_hpp_
#define slic3r_PrintConfig_hpp_ #define slic3r_PrintConfig_hpp_
@ -69,14 +86,19 @@ template<> inline t_config_enum_values ConfigOptionEnum<SeamPosition>::get_enum_
return keys_map; return keys_map;
} }
// Defines each and every confiuration option of Slic3r, including the properties of the GUI dialogs.
// Does not store the actual values, but defines default values.
class PrintConfigDef : public ConfigDef class PrintConfigDef : public ConfigDef
{ {
public: public:
PrintConfigDef(); PrintConfigDef();
}; };
// The one and only global definition of SLic3r configuration options.
// This definition is constant.
extern PrintConfigDef print_config_def; extern PrintConfigDef print_config_def;
// Slic3r configuration storage with print_config_def assigned.
class PrintConfigBase : public virtual ConfigBase class PrintConfigBase : public virtual ConfigBase
{ {
public: public:
@ -87,6 +109,12 @@ class PrintConfigBase : public virtual ConfigBase
double min_object_distance() const; double min_object_distance() const;
}; };
// Slic3r dynamic configuration, used to override the configuration
// per object, per modification volume or per printing material.
// The dynamic configuration is also used to store user modifications of the print global parameters,
// so the modified configuration values may be diffed against the active configuration
// to invalidate the proper slicing resp. g-code generation processing steps.
// This object is mapped to Perl as Slic3r::Config.
class DynamicPrintConfig : public PrintConfigBase, public DynamicConfig class DynamicPrintConfig : public PrintConfigBase, public DynamicConfig
{ {
public: public:
@ -94,12 +122,14 @@ class DynamicPrintConfig : public PrintConfigBase, public DynamicConfig
void normalize(); void normalize();
}; };
class StaticPrintConfig : public PrintConfigBase, public StaticConfig class StaticPrintConfig : public PrintConfigBase, public StaticConfig
{ {
public: public:
StaticPrintConfig() : PrintConfigBase(), StaticConfig() {}; StaticPrintConfig() : PrintConfigBase(), StaticConfig() {};
}; };
// This object is mapped to Perl as Slic3r::Config::PrintObject.
class PrintObjectConfig : public virtual StaticPrintConfig class PrintObjectConfig : public virtual StaticPrintConfig
{ {
public: public:
@ -131,7 +161,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
if (initialize) if (initialize)
this->set_defaults(); this->set_defaults();
} }
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(dont_support_bridges); OPT_PTR(dont_support_bridges);
OPT_PTR(extrusion_width); OPT_PTR(extrusion_width);
@ -161,6 +191,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
}; };
}; };
// This object is mapped to Perl as Slic3r::Config::PrintRegion.
class PrintRegionConfig : public virtual StaticPrintConfig class PrintRegionConfig : public virtual StaticPrintConfig
{ {
public: public:
@ -201,7 +232,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
if (initialize) if (initialize)
this->set_defaults(); this->set_defaults();
} }
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(bottom_solid_layers); OPT_PTR(bottom_solid_layers);
OPT_PTR(bridge_flow_ratio); OPT_PTR(bridge_flow_ratio);
@ -240,6 +271,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
}; };
}; };
// This object is mapped to Perl as Slic3r::Config::GCode.
class GCodeConfig : public virtual StaticPrintConfig class GCodeConfig : public virtual StaticPrintConfig
{ {
public: public:
@ -316,6 +348,7 @@ class GCodeConfig : public virtual StaticPrintConfig
}; };
}; };
// This object is mapped to Perl as Slic3r::Config::Print.
class PrintConfig : public GCodeConfig class PrintConfig : public GCodeConfig
{ {
public: public:
@ -374,7 +407,7 @@ class PrintConfig : public GCodeConfig
if (initialize) if (initialize)
this->set_defaults(); this->set_defaults();
} }
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(avoid_crossing_perimeters); OPT_PTR(avoid_crossing_perimeters);
OPT_PTR(bed_shape); OPT_PTR(bed_shape);
@ -447,7 +480,7 @@ class HostConfig : public virtual StaticPrintConfig
if (initialize) if (initialize)
this->set_defaults(); this->set_defaults();
} }
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(octoprint_host); OPT_PTR(octoprint_host);
OPT_PTR(octoprint_apikey); OPT_PTR(octoprint_apikey);
@ -458,6 +491,7 @@ class HostConfig : public virtual StaticPrintConfig
}; };
}; };
// This object is mapped to Perl as Slic3r::Config::Full.
class FullPrintConfig class FullPrintConfig
: public PrintObjectConfig, public PrintRegionConfig, public PrintConfig, public HostConfig : public PrintObjectConfig, public PrintRegionConfig, public PrintConfig, public HostConfig
{ {

View File

@ -8,12 +8,22 @@
#define SLIC3R_VERSION "1.3.0-dev" #define SLIC3R_VERSION "1.3.0-dev"
//FIXME This epsilon value is used for many non-related purposes:
// For a threshold of a squared Euclidean distance,
// for a trheshold in a difference of radians,
// for a threshold of a cross product of two non-normalized vectors etc.
#define EPSILON 1e-4 #define EPSILON 1e-4
// Scaling factor for a conversion from coord_t to coordf_t: 10e-6
// This scaling generates a following fixed point representation with for a 32bit integer:
// 0..4294mm with 1nm resolution
#define SCALING_FACTOR 0.000001 #define SCALING_FACTOR 0.000001
// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm.
#define RESOLUTION 0.0125 #define RESOLUTION 0.0125
#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR) #define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR)
#define PI 3.141592653589793238 #define PI 3.141592653589793238
// When extruding a closed loop, the loop is interrupted and shortened a bit to reduce the seam.
#define LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER 0.15 #define LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER 0.15
// Maximum perimeter length for the loop to apply the small perimeter speed.
#define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI #define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI
#define INSET_OVERLAP_TOLERANCE 0.4 #define INSET_OVERLAP_TOLERANCE 0.4
#define EXTERNAL_INFILL_MARGIN 3 #define EXTERNAL_INFILL_MARGIN 3