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

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libslic3r/Model.hpp')
-rw-r--r--src/libslic3r/Model.hpp372
1 files changed, 372 insertions, 0 deletions
diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp
new file mode 100644
index 000000000..4c2356429
--- /dev/null
+++ b/src/libslic3r/Model.hpp
@@ -0,0 +1,372 @@
+#ifndef slic3r_Model_hpp_
+#define slic3r_Model_hpp_
+
+#include "libslic3r.h"
+#include "PrintConfig.hpp"
+#include "Layer.hpp"
+#include "Point.hpp"
+#include "TriangleMesh.hpp"
+#include "Slicing.hpp"
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace Slic3r {
+
+class Model;
+class ModelInstance;
+class ModelMaterial;
+class ModelObject;
+class ModelVolume;
+class PresetBundle;
+
+typedef std::string t_model_material_id;
+typedef std::string t_model_material_attribute;
+typedef std::map<t_model_material_attribute,std::string> t_model_material_attributes;
+
+typedef std::map<t_model_material_id,ModelMaterial*> ModelMaterialMap;
+typedef std::vector<ModelObject*> ModelObjectPtrs;
+typedef std::vector<ModelVolume*> ModelVolumePtrs;
+typedef std::vector<ModelInstance*> ModelInstancePtrs;
+
+// 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 m_model; }
+ void apply(const t_model_material_attributes &attributes)
+ { this->attributes.insert(attributes.begin(), attributes.end()); }
+
+private:
+ // Parent, owning this material.
+ Model *m_model;
+
+ ModelMaterial(Model *model) : m_model(model) {}
+ ModelMaterial(Model *model, const ModelMaterial &other) : attributes(other.attributes), config(other.config), m_model(model) {}
+};
+
+// 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;
+ // Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers.
+ // The pairs of <z, layer_height> are packed into a 1D array to simplify handling by the Perl XS.
+ std::vector<coordf_t> layer_height_profile;
+ // layer_height_profile is initialized when the layer editing mode is entered.
+ // Only if the user really modified the layer height, layer_height_profile_valid is set
+ // and used subsequently by the PrintObject.
+ bool layer_height_profile_valid;
+
+ /* 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
+ when user expects that. */
+ Vec3d origin_translation;
+
+ Model* get_model() const { return m_model; };
+
+ ModelVolume* add_volume(const TriangleMesh &mesh);
+ ModelVolume* add_volume(TriangleMesh &&mesh);
+ ModelVolume* add_volume(const ModelVolume &volume);
+ void delete_volume(size_t idx);
+ void clear_volumes();
+
+ ModelInstance* add_instance();
+ ModelInstance* add_instance(const ModelInstance &instance);
+ void delete_instance(size_t idx);
+ void delete_last_instance();
+ void clear_instances();
+
+ // Returns the bounding box of the transformed instances.
+ // This bounding box is approximate and not snug.
+ // This bounding box is being cached.
+ const BoundingBoxf3& bounding_box() const;
+ void invalidate_bounding_box() { m_bounding_box_valid = false; }
+
+ // A mesh containing all transformed instances of this object.
+ TriangleMesh mesh() const;
+ // Non-transformed (non-rotated, non-scaled, non-translated) sum of non-modifier object volumes.
+ // Currently used by ModelObject::mesh() and to calculate the 2D envelope for 2D platter.
+ TriangleMesh raw_mesh() const;
+ // A transformed snug bounding box around the non-modifier object volumes, without the translation applied.
+ // This bounding box is only used for the actual slicing.
+ BoundingBoxf3 raw_bounding_box() const;
+ // A snug bounding box around the transformed non-modifier object volumes.
+ BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const;
+ void center_around_origin();
+ void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
+ void translate(coordf_t x, coordf_t y, coordf_t z);
+ void scale(const Vec3d &versor);
+ void rotate(float angle, const Axis &axis);
+ void rotate(float angle, const Vec3d& axis);
+ void mirror(const Axis &axis);
+ size_t materials_count() const;
+ size_t facets_count() const;
+ bool needed_repair() const;
+ void cut(coordf_t z, Model* model) const;
+ void split(ModelObjectPtrs* new_objects);
+
+ // Called by Print::validate() from the UI thread.
+ void check_instances_print_volume_state(const BoundingBoxf3& print_volume);
+
+ // Print object statistics to console.
+ void print_info() const;
+
+private:
+ ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false) {}
+ ModelObject(Model *model, const ModelObject &other, bool copy_volumes = true);
+ ModelObject& operator= (ModelObject other);
+ void swap(ModelObject &other);
+ ~ModelObject();
+
+ // Parent object, owning this ModelObject.
+ Model *m_model;
+ // Bounding box, cached.
+
+ mutable BoundingBoxf3 m_bounding_box;
+ mutable bool m_bounding_box_valid;
+};
+
+// 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;
+
+ // The convex hull of this model's mesh.
+ TriangleMesh m_convex_hull;
+
+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;
+
+ enum Type {
+ MODEL_TYPE_INVALID = -1,
+ MODEL_PART = 0,
+ PARAMETER_MODIFIER,
+ SUPPORT_ENFORCER,
+ SUPPORT_BLOCKER,
+ };
+
+ // A parent object owning this modifier volume.
+ ModelObject* get_object() const { return this->object; };
+ Type type() const { return m_type; }
+ void set_type(const Type t) { m_type = t; }
+ bool is_model_part() const { return m_type == MODEL_PART; }
+ bool is_modifier() const { return m_type == PARAMETER_MODIFIER; }
+ bool is_support_enforcer() const { return m_type == SUPPORT_ENFORCER; }
+ bool is_support_blocker() const { return m_type == SUPPORT_BLOCKER; }
+ t_model_material_id material_id() const { return this->_material_id; }
+ void material_id(t_model_material_id material_id);
+ ModelMaterial* material() const;
+ void set_material(t_model_material_id material_id, const ModelMaterial &material);
+ // Split this volume, append the result to the object owning this volume.
+ // Return the number of volumes created from this one.
+ // This is useful to assign different materials to different volumes of an object.
+ size_t split(unsigned int max_extruders);
+
+ ModelMaterial* assign_unique_material();
+
+ void calculate_convex_hull();
+ const TriangleMesh& get_convex_hull() const;
+
+ // Helpers for loading / storing into AMF / 3MF files.
+ static Type type_from_string(const std::string &s);
+ static std::string type_to_string(const Type t);
+
+private:
+ // Parent object owning this ModelVolume.
+ ModelObject* object;
+ // Is it an object to be printed, or a modifier volume?
+ Type m_type;
+ t_model_material_id _material_id;
+
+ ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), m_type(MODEL_PART), object(object)
+ {
+ if (mesh.stl.stats.number_of_facets > 1)
+ calculate_convex_hull();
+ }
+ ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) : mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), m_type(MODEL_PART), object(object) {}
+ ModelVolume(ModelObject *object, const ModelVolume &other) :
+ name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), config(other.config), m_type(other.m_type), object(object)
+ {
+ this->material_id(other.material_id());
+ }
+ ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) :
+ name(other.name), mesh(std::move(mesh)), config(other.config), m_type(other.m_type), object(object)
+ {
+ this->material_id(other.material_id());
+ if (mesh.stl.stats.number_of_facets > 1)
+ calculate_convex_hull();
+ }
+};
+
+// A single instance of a ModelObject.
+// Knows the affine transformation of an object.
+class ModelInstance
+{
+public:
+ enum EPrintVolumeState : unsigned char
+ {
+ PVS_Inside,
+ PVS_Partly_Outside,
+ PVS_Fully_Outside,
+ Num_BedStates
+ };
+
+ friend class ModelObject;
+
+#if ENABLE_MODELINSTANCE_3D_OFFSET
+private:
+ Vec3d m_offset; // in unscaled coordinates
+
+public:
+#endif // ENABLE_MODELINSTANCE_3D_OFFSET
+
+ double rotation; // Rotation around the Z axis, in radians around mesh center point
+ double scaling_factor;
+#if !ENABLE_MODELINSTANCE_3D_OFFSET
+ Vec2d offset; // in unscaled coordinates
+#endif // !ENABLE_MODELINSTANCE_3D_OFFSET
+
+ // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state())
+ EPrintVolumeState print_volume_state;
+
+ ModelObject* get_object() const { return this->object; }
+
+#if ENABLE_MODELINSTANCE_3D_OFFSET
+ const Vec3d& get_offset() const { return m_offset; }
+ double get_offset(Axis axis) const { return m_offset(axis); }
+
+ void set_offset(const Vec3d& offset) { m_offset = offset; }
+ void set_offset(Axis axis, double offset) { m_offset(axis) = offset; }
+#endif // ENABLE_MODELINSTANCE_3D_OFFSET
+
+ // To be called on an external mesh
+ void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const;
+ // Calculate a bounding box of a transformed mesh. To be called on an external mesh.
+ BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate = false) const;
+ // Transform an external bounding box.
+ BoundingBoxf3 transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate = false) const;
+ // Transform an external vector.
+ Vec3d transform_vector(const Vec3d& v, 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;
+
+ Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const;
+
+ bool is_printable() const { return print_volume_state == PVS_Inside; }
+
+private:
+ // Parent object, owning this instance.
+ ModelObject* object;
+
+#if ENABLE_MODELINSTANCE_3D_OFFSET
+ ModelInstance(ModelObject *object) : rotation(0), scaling_factor(1), m_offset(Vec3d::Zero()), object(object), print_volume_state(PVS_Inside) {}
+ ModelInstance(ModelObject *object, const ModelInstance &other) :
+ rotation(other.rotation), scaling_factor(other.scaling_factor), m_offset(other.m_offset), object(object), print_volume_state(PVS_Inside) {}
+#else
+ ModelInstance(ModelObject *object) : rotation(0), scaling_factor(1), offset(Vec2d::Zero()), object(object), print_volume_state(PVS_Inside) {}
+ ModelInstance(ModelObject *object, const ModelInstance &other) :
+ rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset), object(object), print_volume_state(PVS_Inside) {}
+#endif // ENABLE_MODELINSTANCE_3D_OFFSET
+};
+
+
+// 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
+{
+ static unsigned int s_auto_extruder_id;
+
+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() {}
+ Model(const Model &other);
+ Model& operator= (Model other);
+ void swap(Model &other);
+ ~Model() { this->clear_objects(); this->clear_materials(); }
+
+ static Model read_from_file(const std::string &input_file, bool add_default_instances = true);
+ static Model read_from_archive(const std::string &input_file, PresetBundle* bundle, bool add_default_instances = true);
+
+ ModelObject* add_object();
+ ModelObject* add_object(const char *name, const char *path, const TriangleMesh &mesh);
+ ModelObject* add_object(const char *name, const char *path, TriangleMesh &&mesh);
+ ModelObject* add_object(const ModelObject &other, bool copy_volumes = true);
+ void delete_object(size_t idx);
+ void delete_object(ModelObject* object);
+ void clear_objects();
+
+ ModelMaterial* add_material(t_model_material_id material_id);
+ ModelMaterial* add_material(t_model_material_id material_id, const ModelMaterial &other);
+ ModelMaterial* get_material(t_model_material_id material_id) {
+ ModelMaterialMap::iterator i = this->materials.find(material_id);
+ return (i == this->materials.end()) ? nullptr : i->second;
+ }
+
+ void delete_material(t_model_material_id material_id);
+ void clear_materials();
+ bool add_default_instances();
+ // Returns approximate axis aligned bounding box of this model
+ BoundingBoxf3 bounding_box() const;
+ void center_instances_around_point(const Vec2d &point);
+ void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
+ TriangleMesh mesh() const;
+ bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL);
+ // Croaks if the duplicated objects do not fit the print bed.
+ void duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL);
+ void duplicate_objects(size_t copies_num, coordf_t dist, const BoundingBoxf* bb = NULL);
+ void duplicate_objects_grid(size_t x, size_t y, coordf_t dist);
+
+ bool looks_like_multipart_object() const;
+ void convert_multipart_object(unsigned int max_extruders);
+
+ // Ensures that the min z of the model is not negative
+ void adjust_min_z();
+
+ void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
+
+ static unsigned int get_auto_extruder_id(unsigned int max_extruders);
+ static std::string get_auto_extruder_id_as_string(unsigned int max_extruders);
+ static void reset_auto_extruder_id();
+};
+
+}
+
+#endif