From d9a92bc4dcd320833f7c7b49f04b745f3e184bb5 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Sun, 20 Nov 2016 22:20:19 -0600 Subject: [PATCH] Code documentation of options and functions for libslic3r internals, ported from Prusa3d fork (written by @bubnikv) --- xs/src/libslic3r/ClipperUtils.hpp | 5 ++ xs/src/libslic3r/Config.cpp | 5 +- xs/src/libslic3r/Config.hpp | 93 +++++++++++++++++++++++-- xs/src/libslic3r/GCode.hpp | 7 ++ xs/src/libslic3r/Layer.cpp | 4 ++ xs/src/libslic3r/LayerRegion.cpp | 1 + xs/src/libslic3r/Model.hpp | 41 ++++++++++- xs/src/libslic3r/MultiPoint.hpp | 2 +- xs/src/libslic3r/PerimeterGenerator.cpp | 6 -- xs/src/libslic3r/PerimeterGenerator.hpp | 40 ++++++++--- xs/src/libslic3r/Polygon.cpp | 6 ++ xs/src/libslic3r/Polygon.hpp | 4 ++ xs/src/libslic3r/Print.cpp | 3 +- xs/src/libslic3r/Print.hpp | 5 +- xs/src/libslic3r/PrintConfig.hpp | 42 +++++++++-- xs/src/libslic3r/libslic3r.h | 10 +++ 16 files changed, 243 insertions(+), 31 deletions(-) diff --git a/xs/src/libslic3r/ClipperUtils.hpp b/xs/src/libslic3r/ClipperUtils.hpp index 5410672e4..8ed333753 100644 --- a/xs/src/libslic3r/ClipperUtils.hpp +++ b/xs/src/libslic3r/ClipperUtils.hpp @@ -14,6 +14,11 @@ using ClipperLib::jtSquare; 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 //----------------------------------------------------------- diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index 59b0401c6..3cae922e9 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -140,6 +140,8 @@ ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str, 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 ConfigBase::get_abs_value(const t_config_option_key &opt_key) { 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 ConfigBase::get_abs_value(const t_config_option_key &opt_key, double ratio_over) { // get stored option value @@ -392,7 +396,6 @@ StaticConfig::set_defaults() t_config_option_keys keys = this->keys(); for (t_config_option_keys::const_iterator it = keys.begin(); it != keys.end(); ++it) { const ConfigOptionDef* def = this->def->get(*it); - if (def->default_value != NULL) this->option(*it)->set(*def->default_value); } diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index c293b4ef8..08a5a6a4b 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -15,9 +15,11 @@ namespace Slic3r { +// Name of the configuration option. typedef std::string t_config_option_key; typedef std::vector t_config_option_keys; +// A generic value of a configuration option. class ConfigOption { public: virtual ~ConfigOption() {}; @@ -34,6 +36,7 @@ class ConfigOption { friend bool operator!= (const ConfigOption &a, const ConfigOption &b); }; +// Value of a single valued option (bool, int, float, string, point, enum) template class ConfigOptionSingle : public ConfigOption { public: @@ -47,12 +50,14 @@ class ConfigOptionSingle : public ConfigOption { }; }; +// Value of a vector valued option (bools, ints, floats, strings, points) class ConfigOptionVectorBase : public ConfigOption { public: virtual ~ConfigOptionVectorBase() {}; virtual std::vector vserialize() const = 0; }; +// Value of a vector valued option (bools, ints, floats, strings, points), template template class ConfigOptionVector : public ConfigOptionVectorBase { @@ -482,6 +487,7 @@ class ConfigOptionBools : public ConfigOptionVector }; }; +// Map from an enum name to an enum integer value. typedef std::map t_config_enum_values; template @@ -508,11 +514,14 @@ class ConfigOptionEnum : public ConfigOptionSingle 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(); }; -/* We use this one in DynamicConfig objects, otherwise it's better to use - the specialized ConfigOptionEnum containers. */ +// Generic enum configuration value. +// 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 containers. class ConfigOptionEnumGeneric : public ConfigOptionInt { public: @@ -532,51 +541,105 @@ class ConfigOptionEnumGeneric : public ConfigOptionInt }; }; +// Type of a configuration value. enum ConfigOptionType { coNone, + // single float coFloat, + // vector of floats coFloats, + // single int coInt, + // vector of ints coInts, + // single string coString, + // vector of strings coStrings, + // percent value. Currently only used for infill. coPercent, + // a fraction or an absolute value coFloatOrPercent, + // single 2d point. Currently not used. coPoint, - coPoint3, + // vector of 2d points. Currently used for the definition of the print bed and for the extruder offsets. coPoints, + coPoint3, + // single boolean value coBool, + // vector of boolean values coBools, + // a generic enum coEnum, }; +// Definition of a configuration value for the purpose of GUI presentation, editing, value mapping and config file handling. class ConfigOptionDef { public: + // What type? bool, int, string etc. ConfigOptionType type; + // Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor. 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; + // 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; + // 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 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; + // A tooltip text shown in the GUI. std::string tooltip; + // Text right from the input field, usually a unit of measurement. std::string sidetext; + // Format of this parameter on a command line. 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; + // True for multiline strings. bool multiline; + // For text input: If true, the GUI text box spans the complete page width. bool full_width; + // Not editable. Currently only used for the display of the number of threads. bool readonly; + // Height of a multiline GUI text box. int height; + // Optional width of an input field. int width; + // limit of a numeric input. + // If not set, the is set to + // By setting min=0, only nonnegative input is allowed. int min; int max; + // Legacy names for this configuration option. + // Used when parsing legacy configuration file. std::vector 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 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 enum_values; std::vector enum_labels; + // For enums (when type == coEnum). Maps enum_values to enums. + // Initialized by ConfigOptionEnum::get_enum_values() t_config_enum_values enum_keys_map; - + ConfigOptionDef() : type(coNone), default_value(NULL), multiline(false), full_width(false), readonly(false), height(-1), width(-1), min(INT_MIN), max(INT_MAX) {}; @@ -587,8 +650,14 @@ class ConfigOptionDef 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_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 { public: @@ -598,9 +667,14 @@ class ConfigDef void merge(const ConfigDef &other); }; +// An abstract configuration store. class ConfigBase { 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; ConfigBase() : def(NULL) {}; @@ -623,6 +697,8 @@ class ConfigBase 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 { public: @@ -643,13 +719,20 @@ class DynamicConfig : public virtual ConfigBase 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 { public: 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; - //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(); + // 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 {}; diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index ebeb50e78..8698eb1a6 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -76,12 +76,19 @@ class GCode { Wipe wipe; AvoidCrossingPerimeters avoid_crossing_perimeters; 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; size_t layer_count; int layer_index; // just a counter const Layer* layer; std::map _seam_position; 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 double volumetric_speed; diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp index 4d12a76f7..55d3c8811 100644 --- a/xs/src/libslic3r/Layer.cpp +++ b/xs/src/libslic3r/Layer.cpp @@ -162,6 +162,10 @@ Layer::any_bottom_region_slice_contains(const T &item) const } template bool Layer::any_bottom_region_slice_contains(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 Layer::make_perimeters() { diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index 64e5a3dec..f5d10cd52 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -76,6 +76,7 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* ); if (this->layer()->lower_layer != NULL) + // Cummulative sum of polygons over all the regions. g.lower_slices = &this->layer()->lower_layer->slices; g.layer_id = this->layer()->id(); diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp index aeb784b0b..c0a7d78ea 100644 --- a/xs/src/libslic3r/Model.hpp +++ b/xs/src/libslic3r/Model.hpp @@ -28,10 +28,18 @@ typedef std::vector ModelObjectPtrs; typedef std::vector ModelVolumePtrs; typedef std::vector 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 { 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; + // Objects are owned by a model. Each model may have multiple instances, each instance having its own transformation (shift, scale, rotation). ModelObjectPtrs objects; Model(); @@ -66,34 +74,48 @@ class Model void print_info() const; }; +// Material, which may be shared across multiple ModelObjects of a single Model. class ModelMaterial { friend class Model; 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; + // Dynamic configuration storage for the object specific configuration values, overriding the global configuration. DynamicPrintConfig config; Model* get_model() const { return this->model; }; void apply(const t_model_material_attributes &attributes); private: + // Parent, owning this material. Model* model; ModelMaterial(Model *model); 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 { friend class Model; public: std::string name; 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; + // Printable and modifier volumes, each with its material ID and a set of override parameters. + // ModelVolumes are owned by this ModelObject. ModelVolumePtrs volumes; + // Configuration parameters specific to a single ModelObject, overriding the global Slic3r settings. DynamicPrintConfig config; + // Variation of a layer thickness for spans of Z coordinates. t_layer_height_ranges layer_height_ranges; - + /* This vector accumulates the total translation applied to the object by the 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 @@ -142,6 +164,7 @@ class ModelObject void print_info() const; private: + // Parent object, owning this ModelObject. Model* model; ModelObject(Model *model); @@ -151,15 +174,22 @@ class 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 { friend class ModelObject; public: std::string name; + // The triangular model. 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; + // Is it an object to be printed, or a modifier volume? bool modifier; + // A parent object owning this modifier volume. ModelObject* get_object() const { return this->object; }; t_model_material_id material_id() const; void material_id(t_model_material_id material_id); @@ -169,6 +199,7 @@ class ModelVolume ModelMaterial* assign_unique_material(); private: + // Parent object owning this ModelVolume. ModelObject* object; t_model_material_id _material_id; @@ -178,19 +209,25 @@ class ModelVolume void swap(ModelVolume &other); }; +// A single instance of a ModelObject. +// Knows the affine transformation of an object. class ModelInstance { friend class ModelObject; 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; Pointf offset; // in unscaled coordinates ModelObject* get_object() const { return this->object; }; + + // To be called on an external mesh 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; private: + // Parent object, owning this instance. ModelObject* object; ModelInstance(ModelObject *object); diff --git a/xs/src/libslic3r/MultiPoint.hpp b/xs/src/libslic3r/MultiPoint.hpp index d057b14f1..b83f23368 100644 --- a/xs/src/libslic3r/MultiPoint.hpp +++ b/xs/src/libslic3r/MultiPoint.hpp @@ -42,6 +42,6 @@ class MultiPoint static Points _douglas_peucker(const Points &points, const double tolerance); }; -} +} // namespace Slic3r #endif diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index 842801d4e..db1eb3255 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -535,12 +535,6 @@ PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRo return coll; } -bool -PerimeterGeneratorLoop::is_external() const -{ - return this->depth == 0; -} - bool PerimeterGeneratorLoop::is_internal_contour() const { diff --git a/xs/src/libslic3r/PerimeterGenerator.hpp b/xs/src/libslic3r/PerimeterGenerator.hpp index eb3fa0fcb..0e7fbd3e4 100644 --- a/xs/src/libslic3r/PerimeterGenerator.hpp +++ b/xs/src/libslic3r/PerimeterGenerator.hpp @@ -11,25 +11,33 @@ namespace Slic3r { -class PerimeterGeneratorLoop; -typedef std::vector PerimeterGeneratorLoops; - +// Hierarchy of perimeters. class PerimeterGeneratorLoop { - public: +public: + // Polygon of this contour. Polygon polygon; + // Is it a contour or a hole? + // Contours are CCW oriented, holes are CW oriented. 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; + // Children contour, may be both CCW and CW oriented (outer contours or holes). std::vector children; PerimeterGeneratorLoop(Polygon polygon, unsigned short 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; }; +typedef std::vector PerimeterGeneratorLoops; + class PerimeterGenerator { - public: +public: + // Inputs: const SurfaceCollection* slices; const ExPolygonCollection* lower_slices; double layer_height; @@ -41,14 +49,26 @@ class PerimeterGenerator { PrintRegionConfig* config; PrintObjectConfig* object_config; PrintConfig* print_config; + // Outputs: ExtrusionEntityCollection* loops; ExtrusionEntityCollection* gap_fill; SurfaceCollection* fill_surfaces; - PerimeterGenerator(const SurfaceCollection* slices, double layer_height, Flow flow, - PrintRegionConfig* config, PrintObjectConfig* object_config, - PrintConfig* print_config, ExtrusionEntityCollection* loops, - ExtrusionEntityCollection* gap_fill, SurfaceCollection* fill_surfaces) + PerimeterGenerator( + // Input: + const SurfaceCollection* slices, + 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), layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow), overhang_flow(flow), solid_infill_flow(flow), diff --git a/xs/src/libslic3r/Polygon.cpp b/xs/src/libslic3r/Polygon.cpp index 0fbfda370..e36512970 100644 --- a/xs/src/libslic3r/Polygon.cpp +++ b/xs/src/libslic3r/Polygon.cpp @@ -59,6 +59,7 @@ Polygon::split_at_vertex(const Point &point) const return Polyline(); } +// Split a closed polygon into an open polyline, with the split point duplicated at both ends. Polyline Polygon::split_at_index(int index) const { @@ -71,6 +72,7 @@ Polygon::split_at_index(int index) const return polyline; } +// Split a closed polygon into an open polyline, with the split point duplicated at both ends. Polyline Polygon::split_at_first_point() const { @@ -127,6 +129,8 @@ Polygon::is_valid() const return this->points.size() >= 3; } +// Does an unoriented polygon contain a point? +// Tested by counting intersections along a horizontal line. bool 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 j = this->points.end() - 1; 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)) && ((double)point.x < (double)(j->x - i->x) * (double)(point.y - i->y) / (double)(j->y - i->y) + (double)i->x) ) result = !result; diff --git a/xs/src/libslic3r/Polygon.hpp b/xs/src/libslic3r/Polygon.hpp index ccde4a740..e3ea13f24 100644 --- a/xs/src/libslic3r/Polygon.hpp +++ b/xs/src/libslic3r/Polygon.hpp @@ -25,7 +25,9 @@ class Polygon : public MultiPoint { Point last_point() const; virtual Lines lines() 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; + // Split a closed polygon into an open polyline, with the split point duplicated at both ends. Polyline split_at_first_point() const; Points equally_spaced_points(double distance) const; double area() const; @@ -34,6 +36,8 @@ class Polygon : public MultiPoint { bool make_counter_clockwise(); bool make_clockwise(); 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; Polygons simplify(double tolerance) const; void simplify(double tolerance, Polygons &polygons) const; diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 393677343..42827e6e9 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -635,7 +635,7 @@ Print::validate() const 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."); } - } + } // end if (this->config.complete_objects) if (this->config.spiral_vase) { 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(); for (ModelVolumePtrs::const_iterator v = model_object->volumes.begin(); v != model_object->volumes.end(); ++v) { 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; if (!(*v)->config.has("extruder")) (*v)->config.opt("extruder", true)->value = extruder_id; diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index fcf6d0a79..a2a5ba7b4 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -20,7 +20,7 @@ class Print; class PrintObject; class ModelObject; - +// Print step IDs for keeping track of the print state. enum PrintStep { psSkirt, psBrim, }; @@ -34,6 +34,7 @@ class PrintValidationException : public std::runtime_error { PrintValidationException(const std::string &error) : std::runtime_error(error) {}; }; +// To be instantiated over PrintStep or PrintObjectStep enums. template class PrintState { @@ -120,6 +121,7 @@ class PrintObject size_t layer_count() const; void clear_layers(); 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); void delete_layer(int idx); @@ -152,6 +154,7 @@ class PrintObject typedef std::vector PrintObjectPtrs; typedef std::vector PrintRegionPtrs; +// The complete print tray with possibly multiple objects. class Print { public: diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 8aaebab35..fc517c37f 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -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_ #define slic3r_PrintConfig_hpp_ @@ -69,14 +86,19 @@ template<> inline t_config_enum_values ConfigOptionEnum::get_enum_ 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 { public: PrintConfigDef(); }; +// The one and only global definition of SLic3r configuration options. +// This definition is constant. extern PrintConfigDef print_config_def; +// Slic3r configuration storage with print_config_def assigned. class PrintConfigBase : public virtual ConfigBase { public: @@ -87,6 +109,12 @@ class PrintConfigBase : public virtual ConfigBase 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 { public: @@ -94,12 +122,14 @@ class DynamicPrintConfig : public PrintConfigBase, public DynamicConfig void normalize(); }; + class StaticPrintConfig : public PrintConfigBase, public StaticConfig { public: StaticPrintConfig() : PrintConfigBase(), StaticConfig() {}; }; +// This object is mapped to Perl as Slic3r::Config::PrintObject. class PrintObjectConfig : public virtual StaticPrintConfig { public: @@ -131,7 +161,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig if (initialize) this->set_defaults(); } - + virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(dont_support_bridges); 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 { public: @@ -201,7 +232,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig if (initialize) this->set_defaults(); } - + virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(bottom_solid_layers); 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 { public: @@ -316,6 +348,7 @@ class GCodeConfig : public virtual StaticPrintConfig }; }; +// This object is mapped to Perl as Slic3r::Config::Print. class PrintConfig : public GCodeConfig { public: @@ -374,7 +407,7 @@ class PrintConfig : public GCodeConfig if (initialize) this->set_defaults(); } - + virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(avoid_crossing_perimeters); OPT_PTR(bed_shape); @@ -447,7 +480,7 @@ class HostConfig : public virtual StaticPrintConfig if (initialize) this->set_defaults(); } - + virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(octoprint_host); 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 : public PrintObjectConfig, public PrintRegionConfig, public PrintConfig, public HostConfig { diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index eb3fb8f03..db38bc215 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -8,12 +8,22 @@ #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 +// 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 +// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm. #define RESOLUTION 0.0125 #define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR) #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 +// Maximum perimeter length for the loop to apply the small perimeter speed. #define SMALL_PERIMETER_LENGTH (6.5 / SCALING_FACTOR) * 2 * PI #define INSET_OVERLAP_TOLERANCE 0.4 #define EXTERNAL_INFILL_MARGIN 3