2014-01-06 17:29:10 +00:00
# ifndef slic3r_Model_hpp_
# define slic3r_Model_hpp_
2015-12-07 23:39:54 +00:00
# include "libslic3r.h"
2014-04-29 23:04:49 +00:00
# include "PrintConfig.hpp"
2014-01-06 17:29:10 +00:00
# include "Layer.hpp"
# include "Point.hpp"
# include "TriangleMesh.hpp"
2016-12-08 18:02:16 +00:00
# include "Slicing.hpp"
2014-01-06 17:29:10 +00:00
# include <map>
# include <string>
# include <utility>
# include <vector>
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
# include "Geometry.hpp"
# endif // ENABLE_MODELVOLUME_TRANSFORM
2014-01-06 17:29:10 +00:00
namespace Slic3r {
2017-06-13 10:09:49 +00:00
class Model ;
2014-01-06 17:29:10 +00:00
class ModelInstance ;
class ModelMaterial ;
class ModelObject ;
class ModelVolume ;
2018-02-13 14:19:55 +00:00
class PresetBundle ;
2018-10-17 09:12:38 +00:00
class Print ;
2014-01-06 17:29:10 +00:00
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 ;
2014-04-29 23:04:49 +00:00
typedef std : : map < t_model_material_id , ModelMaterial * > ModelMaterialMap ;
typedef std : : vector < ModelObject * > ModelObjectPtrs ;
typedef std : : vector < ModelVolume * > ModelVolumePtrs ;
typedef std : : vector < ModelInstance * > ModelInstancePtrs ;
2018-10-17 09:12:38 +00:00
// Unique identifier of a Model, ModelObject, ModelVolume, ModelInstance or ModelMaterial.
// Used to synchronize the front end (UI) with the back end (BackgroundSlicingProcess / Print / PrintObject)
typedef size_t ModelID ;
// Base for Model, ModelObject, ModelVolume, ModelInstance or ModelMaterial to provide a unique ID
// to synchronize the front end (UI) with the back end (BackgroundSlicingProcess / Print / PrintObject).
2018-10-18 16:06:40 +00:00
// Achtung! The s_last_id counter is not thread safe, so it is expected, that the ModelBase derived instances
// are only instantiated from the main thread.
2018-10-17 09:12:38 +00:00
class ModelBase
{
public :
ModelID id ( ) const { return m_id ; }
protected :
2018-10-30 14:24:36 +00:00
// Constructor to be only called by derived classes.
ModelBase ( ) { }
2018-10-17 09:12:38 +00:00
ModelID m_id = generate_new_id ( ) ;
private :
static inline ModelID generate_new_id ( ) { return s_last_id + + ; }
static ModelID s_last_id ;
} ;
2016-09-13 11:30:00 +00:00
// Material, which may be shared across multiple ModelObjects of a single Model.
2018-10-17 09:12:38 +00:00
class ModelMaterial : public ModelBase
2014-01-06 17:29:10 +00:00
{
2014-05-09 12:24:35 +00:00
friend class Model ;
2016-09-13 11:30:00 +00:00
public :
// Attributes are defined by the AMF file format, but they don't seem to be used by Slic3r for any purpose.
2014-01-06 17:29:10 +00:00
t_model_material_attributes attributes ;
2016-09-13 11:30:00 +00:00
// Dynamic configuration storage for the object specific configuration values, overriding the global configuration.
2014-04-29 23:04:49 +00:00
DynamicPrintConfig config ;
2017-06-13 10:09:49 +00:00
Model * get_model ( ) const { return m_model ; }
2017-06-13 09:35:24 +00:00
void apply ( const t_model_material_attributes & attributes )
{ this - > attributes . insert ( attributes . begin ( ) , attributes . end ( ) ) ; }
2016-09-13 11:30:00 +00:00
private :
// Parent, owning this material.
2017-06-13 09:35:24 +00:00
Model * m_model ;
2014-05-09 12:24:35 +00:00
2017-06-13 09:35:24 +00:00
ModelMaterial ( Model * model ) : m_model ( model ) { }
ModelMaterial ( Model * model , const ModelMaterial & other ) : attributes ( other . attributes ) , config ( other . config ) , m_model ( model ) { }
2018-10-30 14:24:36 +00:00
explicit ModelMaterial ( ModelMaterial & rhs ) = delete ;
ModelMaterial & operator = ( ModelMaterial & rhs ) = delete ;
2014-01-06 17:29:10 +00:00
} ;
2016-09-13 11:30:00 +00:00
// 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.
2018-10-17 09:12:38 +00:00
class ModelObject : public ModelBase
2014-01-06 17:29:10 +00:00
{
2014-05-09 12:24:35 +00:00
friend class Model ;
2016-09-13 11:30:00 +00:00
public :
2017-06-13 09:35:24 +00:00
std : : string name ;
2018-09-17 10:15:11 +00:00
std : : string input_file ; // XXX: consider fs::path
2016-09-13 11:30:00 +00:00
// 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.
2017-06-13 09:35:24 +00:00
ModelInstancePtrs instances ;
2016-09-13 11:30:00 +00:00
// Printable and modifier volumes, each with its material ID and a set of override parameters.
// ModelVolumes are owned by this ModelObject.
2017-06-13 09:35:24 +00:00
ModelVolumePtrs volumes ;
2016-09-13 11:30:00 +00:00
// Configuration parameters specific to a single ModelObject, overriding the global Slic3r settings.
2017-06-13 09:35:24 +00:00
DynamicPrintConfig config ;
2016-09-13 11:30:00 +00:00
// Variation of a layer thickness for spans of Z coordinates.
2017-06-13 09:35:24 +00:00
t_layer_height_ranges layer_height_ranges ;
2017-02-07 17:17:12 +00:00
// 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.
2017-06-13 09:35:24 +00:00
std : : vector < coordf_t > layer_height_profile ;
2017-02-09 13:56:13 +00:00
// 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.
2017-06-13 09:35:24 +00:00
bool layer_height_profile_valid ;
2018-09-19 12:59:57 +00:00
// This vector holds position of selected support points for SLA. The data are
// saved in mesh coordinates to allow using them for several instances.
2018-09-10 10:08:57 +00:00
std : : vector < Vec3f > sla_support_points ;
2016-09-13 11:30:00 +00:00
2014-10-25 09:10:44 +00:00
/* This vector accumulates the total translation applied to the object by the
center_around_origin ( ) method . Callers might want to apply the same translation
2015-01-08 23:47:40 +00:00
to new volumes before adding them to this object in order to preserve alignment
2014-10-25 09:10:44 +00:00
when user expects that . */
2018-08-21 15:43:05 +00:00
Vec3d origin_translation ;
2018-10-17 09:12:38 +00:00
2018-10-30 14:24:36 +00:00
// Assign a ModelObject to this object while keeping the original pointer to the parent Model.
// Make a deep copy.
ModelObject & assign ( const ModelObject * rhs , bool copy_volumes = true ) ;
2018-10-17 09:12:38 +00:00
Model * get_model ( ) const { return m_model ; } ;
2014-01-06 17:29:10 +00:00
2018-10-17 09:12:38 +00:00
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 ( ) ;
2018-10-23 09:26:15 +00:00
bool is_multiparts ( ) const { return volumes . size ( ) > 1 ; }
2018-10-17 09:12:38 +00:00
ModelInstance * add_instance ( ) ;
ModelInstance * add_instance ( const ModelInstance & instance ) ;
ModelInstance * add_instance ( const Vec3d & offset , const Vec3d & scaling_factor , const Vec3d & rotation ) ;
void delete_instance ( size_t idx ) ;
void delete_last_instance ( ) ;
void clear_instances ( ) ;
2014-04-29 23:04:49 +00:00
2017-06-13 09:35:24 +00:00
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
2018-03-14 15:11:57 +00:00
// This bounding box is being cached.
2018-05-25 13:56:14 +00:00
const BoundingBoxf3 & bounding_box ( ) const ;
2017-06-13 09:35:24 +00:00
void invalidate_bounding_box ( ) { m_bounding_box_valid = false ; }
2014-04-29 23:04:49 +00:00
2017-06-13 09:35:24 +00:00
// A mesh containing all transformed instances of this object.
2015-01-19 17:53:04 +00:00
TriangleMesh mesh ( ) const ;
2017-06-13 09:35:24 +00:00
// 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.
2015-01-19 17:53:04 +00:00
TriangleMesh raw_mesh ( ) const ;
2017-06-13 09:35:24 +00:00
// 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.
2015-01-19 17:53:04 +00:00
BoundingBoxf3 raw_bounding_box ( ) const ;
2017-06-13 09:35:24 +00:00
// A snug bounding box around the transformed non-modifier object volumes.
BoundingBoxf3 instance_bounding_box ( size_t instance_idx , bool dont_translate = false ) const ;
2014-09-21 08:51:36 +00:00
void center_around_origin ( ) ;
2018-10-30 15:03:03 +00:00
void ensure_on_bed ( ) ;
void translate_instances ( const Vec3d & vector ) ;
void translate_instance ( size_t instance_idx , const Vec3d & vector ) ;
2018-08-21 15:43:05 +00:00
void translate ( const Vec3d & vector ) { this - > translate ( vector ( 0 ) , vector ( 1 ) , vector ( 2 ) ) ; }
2014-09-21 08:51:36 +00:00
void translate ( coordf_t x , coordf_t y , coordf_t z ) ;
2018-08-21 15:43:05 +00:00
void scale ( const Vec3d & versor ) ;
2018-09-20 14:48:13 +00:00
void scale ( const double s ) { this - > scale ( Vec3d ( s , s , s ) ) ; }
2015-04-16 19:22:04 +00:00
void rotate ( float angle , const Axis & axis ) ;
2018-08-27 12:00:53 +00:00
void rotate ( float angle , const Vec3d & axis ) ;
2015-11-04 22:11:30 +00:00
void mirror ( const Axis & axis ) ;
2014-09-21 08:51:36 +00:00
size_t materials_count ( ) const ;
2014-08-08 19:48:59 +00:00
size_t facets_count ( ) const ;
bool needed_repair ( ) const ;
2014-09-21 08:51:36 +00:00
void cut ( coordf_t z , Model * model ) const ;
2014-11-12 22:50:09 +00:00
void split ( ModelObjectPtrs * new_objects ) ;
2018-09-20 14:48:13 +00:00
void repair ( ) ;
2018-07-18 12:26:42 +00:00
2018-10-30 15:03:03 +00:00
double get_min_z ( ) const ;
double get_instance_min_z ( size_t instance_idx ) const ;
2018-09-14 07:28:00 +00:00
// Called by Print::validate() from the UI thread.
2018-10-23 13:27:31 +00:00
unsigned int check_instances_print_volume_state ( const BoundingBoxf3 & print_volume ) ;
2017-08-02 14:05:18 +00:00
// Print object statistics to console.
void print_info ( ) const ;
2018-10-17 09:12:38 +00:00
protected :
friend class Print ;
// Clone this ModelObject including its volumes and instances, keep the IDs of the copies equal to the original.
// Called by Print::apply() to clone the Model / ModelObject hierarchy to the back end for background processing.
ModelObject * clone ( Model * parent ) ;
void set_model ( Model * model ) { m_model = model ; }
private :
2018-08-21 15:43:05 +00:00
ModelObject ( Model * model ) : layer_height_profile_valid ( false ) , m_model ( model ) , origin_translation ( Vec3d : : Zero ( ) ) , m_bounding_box_valid ( false ) { }
2018-10-30 14:24:36 +00:00
ModelObject ( Model * model , const ModelObject & rhs , bool copy_volumes = true ) ;
explicit ModelObject ( ModelObject & rhs ) = delete ;
2014-05-09 12:24:35 +00:00
~ ModelObject ( ) ;
2018-10-30 14:24:36 +00:00
ModelObject & operator = ( ModelObject & rhs ) = default ;
2017-06-13 09:35:24 +00:00
// Parent object, owning this ModelObject.
2018-10-17 09:12:38 +00:00
Model * m_model ;
2017-06-13 09:35:24 +00:00
// Bounding box, cached.
2018-06-21 06:37:04 +00:00
2018-05-25 13:56:14 +00:00
mutable BoundingBoxf3 m_bounding_box ;
mutable bool m_bounding_box_valid ;
2014-01-06 17:29:10 +00:00
} ;
2016-09-13 11:30:00 +00:00
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.
// ModelVolume instances are owned by a ModelObject.
2018-10-17 09:12:38 +00:00
class ModelVolume : public ModelBase
2014-01-06 17:29:10 +00:00
{
2014-05-09 12:24:35 +00:00
friend class ModelObject ;
2018-08-15 10:50:06 +00:00
// The convex hull of this model's mesh.
2018-10-17 09:12:38 +00:00
TriangleMesh m_convex_hull ;
2018-08-15 10:50:06 +00:00
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
Geometry : : Transformation m_transformation ;
# endif // ENABLE_MODELVOLUME_TRANSFORM
2016-09-13 11:30:00 +00:00
public :
2018-10-17 09:12:38 +00:00
std : : string name ;
2016-09-13 11:30:00 +00:00
// The triangular model.
2018-10-17 09:12:38 +00:00
TriangleMesh mesh ;
2016-09-13 11:30:00 +00:00
// Configuration parameters specific to an object model geometry or a modifier volume,
// overriding the global Slic3r settings and the ModelObject settings.
2018-10-17 09:12:38 +00:00
DynamicPrintConfig config ;
2018-09-06 12:19:20 +00:00
enum Type {
MODEL_TYPE_INVALID = - 1 ,
MODEL_PART = 0 ,
PARAMETER_MODIFIER ,
SUPPORT_ENFORCER ,
SUPPORT_BLOCKER ,
} ;
2018-10-17 09:12:38 +00:00
// Clone this ModelVolume, keep the ID identical, set the parent to the cloned volume.
ModelVolume * clone ( ModelObject * parent ) { return new ModelVolume ( parent , * this ) ; }
2016-09-13 11:30:00 +00:00
// A parent object owning this modifier volume.
2018-09-06 12:19:20 +00:00
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 ; }
2018-10-17 09:12:38 +00:00
bool is_support_modifier ( ) const { return m_type = = SUPPORT_BLOCKER | | m_type = = SUPPORT_ENFORCER ; }
t_model_material_id material_id ( ) const { return m_material_id ; }
void set_material_id ( t_model_material_id material_id ) ;
2018-09-06 12:19:20 +00:00
ModelMaterial * material ( ) const ;
void set_material ( t_model_material_id material_id , const ModelMaterial & material ) ;
2017-06-15 13:38:15 +00:00
// 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.
2018-09-20 14:48:13 +00:00
size_t split ( unsigned int max_extruders ) ;
2018-05-07 14:13:58 +00:00
2018-09-20 14:48:13 +00:00
ModelMaterial * assign_unique_material ( ) ;
2014-08-03 18:33:16 +00:00
2018-09-20 14:48:13 +00:00
void calculate_convex_hull ( ) ;
2018-08-15 10:50:06 +00:00
const TriangleMesh & get_convex_hull ( ) const ;
2018-10-17 09:12:38 +00:00
TriangleMesh & get_convex_hull ( ) ;
2018-08-15 10:50:06 +00:00
2018-09-06 12:19:20 +00:00
// 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 ) ;
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
const Vec3d & get_offset ( ) const { return m_transformation . get_offset ( ) ; }
double get_offset ( Axis axis ) const { return m_transformation . get_offset ( axis ) ; }
void set_offset ( const Vec3d & offset ) { m_transformation . set_offset ( offset ) ; }
void set_offset ( Axis axis , double offset ) { m_transformation . set_offset ( axis , offset ) ; }
const Vec3d & get_rotation ( ) const { return m_transformation . get_rotation ( ) ; }
double get_rotation ( Axis axis ) const { return m_transformation . get_rotation ( axis ) ; }
void set_rotation ( const Vec3d & rotation ) { m_transformation . set_rotation ( rotation ) ; }
void set_rotation ( Axis axis , double rotation ) { m_transformation . set_rotation ( axis , rotation ) ; }
Vec3d get_scaling_factor ( ) const { return m_transformation . get_scaling_factor ( ) ; }
double get_scaling_factor ( Axis axis ) const { return m_transformation . get_scaling_factor ( axis ) ; }
void set_scaling_factor ( const Vec3d & scaling_factor ) { m_transformation . set_scaling_factor ( scaling_factor ) ; }
void set_scaling_factor ( Axis axis , double scaling_factor ) { m_transformation . set_scaling_factor ( axis , scaling_factor ) ; }
const Vec3d & get_mirror ( ) const { return m_transformation . get_mirror ( ) ; }
double get_mirror ( Axis axis ) const { return m_transformation . get_mirror ( axis ) ; }
void set_mirror ( const Vec3d & mirror ) { m_transformation . set_mirror ( mirror ) ; }
void set_mirror ( Axis axis , double mirror ) { m_transformation . set_mirror ( axis , mirror ) ; }
# endif // ENABLE_MODELVOLUME_TRANSFORM
2016-09-13 11:30:00 +00:00
private :
// Parent object owning this ModelVolume.
2018-09-06 12:19:20 +00:00
ModelObject * object ;
// Is it an object to be printed, or a modifier volume?
Type m_type ;
2018-10-17 09:12:38 +00:00
t_model_material_id m_material_id ;
2014-05-09 12:24:35 +00:00
2018-09-06 12:19:20 +00:00
ModelVolume ( ModelObject * object , const TriangleMesh & mesh ) : mesh ( mesh ) , m_type ( MODEL_PART ) , object ( object )
2018-08-15 10:50:06 +00:00
{
if ( mesh . stl . stats . number_of_facets > 1 )
calculate_convex_hull ( ) ;
}
2018-10-17 09:12:38 +00:00
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 ) { }
2018-08-15 10:50:06 +00:00
ModelVolume ( ModelObject * object , const ModelVolume & other ) :
2018-10-17 09:12:38 +00:00
ModelBase ( other ) , // copy the ID
2018-09-06 12:19:20 +00:00
name ( other . name ) , mesh ( other . mesh ) , m_convex_hull ( other . m_convex_hull ) , config ( other . config ) , m_type ( other . m_type ) , object ( object )
2018-08-15 10:50:06 +00:00
{
2018-10-17 09:12:38 +00:00
this - > set_material_id ( other . material_id ( ) ) ;
2018-08-15 10:50:06 +00:00
}
ModelVolume ( ModelObject * object , const ModelVolume & other , const TriangleMesh & & mesh ) :
2018-10-17 09:12:38 +00:00
ModelBase ( other ) , // copy the ID
2018-09-06 12:19:20 +00:00
name ( other . name ) , mesh ( std : : move ( mesh ) ) , config ( other . config ) , m_type ( other . m_type ) , object ( object )
2018-08-15 10:50:06 +00:00
{
2018-10-17 09:12:38 +00:00
this - > set_material_id ( other . material_id ( ) ) ;
2018-08-15 10:50:06 +00:00
if ( mesh . stl . stats . number_of_facets > 1 )
calculate_convex_hull ( ) ;
}
2018-10-30 14:24:36 +00:00
explicit ModelVolume ( ModelVolume & rhs ) = delete ;
ModelVolume & operator = ( ModelVolume & rhs ) = delete ;
2014-01-06 17:29:10 +00:00
} ;
2016-09-13 11:30:00 +00:00
// A single instance of a ModelObject.
// Knows the affine transformation of an object.
2018-10-17 09:12:38 +00:00
class ModelInstance : public ModelBase
2014-01-06 17:29:10 +00:00
{
2016-09-13 11:30:00 +00:00
public :
2018-07-18 12:26:42 +00:00
enum EPrintVolumeState : unsigned char
{
PVS_Inside ,
PVS_Partly_Outside ,
PVS_Fully_Outside ,
Num_BedStates
} ;
friend class ModelObject ;
2018-09-13 13:15:00 +00:00
private :
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
Geometry : : Transformation m_transformation ;
# else
2018-09-13 13:15:00 +00:00
Vec3d m_offset ; // in unscaled coordinates
2018-09-20 13:00:40 +00:00
Vec3d m_rotation ; // Rotation around the three axes, in radians around mesh center point
2018-09-24 13:54:09 +00:00
Vec3d m_scaling_factor ; // Scaling factors along the three axes
2018-10-18 13:50:51 +00:00
Vec3d m_mirror ; // Mirroring along the three axes
2018-10-31 13:56:51 +00:00
# endif // ENABLE_MODELVOLUME_TRANSFORM
2018-09-13 13:15:00 +00:00
public :
2018-07-18 12:26:42 +00:00
// 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 ;
2018-07-18 07:37:25 +00:00
2018-06-28 14:14:17 +00:00
ModelObject * get_object ( ) const { return this - > object ; }
2016-09-13 11:30:00 +00:00
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
const Geometry : : Transformation & get_transformation ( ) const { return m_transformation ; }
void set_transformation ( const Geometry : : Transformation & transformation ) { m_transformation = transformation ; }
const Vec3d & get_offset ( ) const { return m_transformation . get_offset ( ) ; }
double get_offset ( Axis axis ) const { return m_transformation . get_offset ( axis ) ; }
void set_offset ( const Vec3d & offset ) { m_transformation . set_offset ( offset ) ; }
void set_offset ( Axis axis , double offset ) { m_transformation . set_offset ( axis , offset ) ; }
const Vec3d & get_rotation ( ) const { return m_transformation . get_rotation ( ) ; }
double get_rotation ( Axis axis ) const { return m_transformation . get_rotation ( axis ) ; }
void set_rotation ( const Vec3d & rotation ) { m_transformation . set_rotation ( rotation ) ; }
void set_rotation ( Axis axis , double rotation ) { m_transformation . set_rotation ( axis , rotation ) ; }
Vec3d get_scaling_factor ( ) const { return m_transformation . get_scaling_factor ( ) ; }
double get_scaling_factor ( Axis axis ) const { return m_transformation . get_scaling_factor ( axis ) ; }
void set_scaling_factor ( const Vec3d & scaling_factor ) { m_transformation . set_scaling_factor ( scaling_factor ) ; }
void set_scaling_factor ( Axis axis , double scaling_factor ) { m_transformation . set_scaling_factor ( axis , scaling_factor ) ; }
const Vec3d & get_mirror ( ) const { return m_transformation . get_mirror ( ) ; }
double get_mirror ( Axis axis ) const { return m_transformation . get_mirror ( axis ) ; }
void set_mirror ( const Vec3d & mirror ) { m_transformation . set_mirror ( mirror ) ; }
void set_mirror ( Axis axis , double mirror ) { m_transformation . set_mirror ( axis , mirror ) ; }
# else
2018-09-13 13:15:00 +00:00
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 ; }
2018-09-20 13:00:40 +00:00
const Vec3d & get_rotation ( ) const { return m_rotation ; }
double get_rotation ( Axis axis ) const { return m_rotation ( axis ) ; }
void set_rotation ( const Vec3d & rotation ) ;
void set_rotation ( Axis axis , double rotation ) ;
2018-09-24 13:54:09 +00:00
Vec3d get_scaling_factor ( ) const { return m_scaling_factor ; }
double get_scaling_factor ( Axis axis ) const { return m_scaling_factor ( axis ) ; }
2018-10-18 13:50:51 +00:00
void set_scaling_factor ( const Vec3d & scaling_factor ) ;
void set_scaling_factor ( Axis axis , double scaling_factor ) ;
const Vec3d & get_mirror ( ) const { return m_mirror ; }
double get_mirror ( Axis axis ) const { return m_mirror ( axis ) ; }
void set_mirror ( const Vec3d & mirror ) ;
void set_mirror ( Axis axis , double mirror ) ;
2018-10-31 13:56:51 +00:00
# endif // ENABLE_MODELVOLUME_TRANSFORM
2018-09-20 13:00:40 +00:00
2016-09-13 11:30:00 +00:00
// To be called on an external mesh
2014-08-03 18:33:16 +00:00
void transform_mesh ( TriangleMesh * mesh , bool dont_translate = false ) const ;
2016-11-16 10:53:29 +00:00
// 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 ;
2018-09-06 07:16:32 +00:00
// Transform an external vector.
Vec3d transform_vector ( const Vec3d & v , bool dont_translate = false ) const ;
2016-09-13 11:30:00 +00:00
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
2014-01-06 17:29:10 +00:00
void transform_polygon ( Polygon * polygon ) const ;
2018-07-18 12:26:42 +00:00
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
2018-11-01 07:46:44 +00:00
const Transform3d & world_matrix ( bool dont_translate = false , bool dont_rotate = false , bool dont_scale = false , bool dont_mirror = false ) const { return m_transformation . get_matrix ( dont_translate , dont_rotate , dont_scale , dont_mirror ) ; }
2018-10-31 13:56:51 +00:00
# else
2018-10-18 13:50:51 +00:00
Transform3d world_matrix ( bool dont_translate = false , bool dont_rotate = false , bool dont_scale = false , bool dont_mirror = false ) const ;
2018-10-31 13:56:51 +00:00
# endif // ENABLE_MODELVOLUME_TRANSFORM
2018-09-04 12:42:14 +00:00
2018-07-18 12:26:42 +00:00
bool is_printable ( ) const { return print_volume_state = = PVS_Inside ; }
2016-09-13 11:30:00 +00:00
private :
// Parent object, owning this instance.
2014-05-09 12:24:35 +00:00
ModelObject * object ;
2017-06-13 09:35:24 +00:00
2018-10-31 13:56:51 +00:00
# if ENABLE_MODELVOLUME_TRANSFORM
ModelInstance ( ModelObject * object ) : object ( object ) , print_volume_state ( PVS_Inside ) { }
ModelInstance ( ModelObject * object , const ModelInstance & other ) :
m_transformation ( other . m_transformation ) , object ( object ) , print_volume_state ( PVS_Inside ) { }
# else
2018-10-18 13:50:51 +00:00
ModelInstance ( ModelObject * object ) : m_offset ( Vec3d : : Zero ( ) ) , m_rotation ( Vec3d : : Zero ( ) ) , m_scaling_factor ( Vec3d : : Ones ( ) ) , m_mirror ( Vec3d : : Ones ( ) ) , object ( object ) , print_volume_state ( PVS_Inside ) { }
2018-09-13 13:15:00 +00:00
ModelInstance ( ModelObject * object , const ModelInstance & other ) :
2018-10-18 13:50:51 +00:00
m_offset ( other . m_offset ) , m_rotation ( other . m_rotation ) , m_scaling_factor ( other . m_scaling_factor ) , m_mirror ( other . m_mirror ) , object ( object ) , print_volume_state ( PVS_Inside ) { }
2018-10-31 13:56:51 +00:00
# endif // ENABLE_MODELVOLUME_TRANSFORM
2017-06-13 09:35:24 +00:00
2018-10-30 14:24:36 +00:00
explicit ModelInstance ( ModelInstance & rhs ) = delete ;
ModelInstance & operator = ( ModelInstance & rhs ) = delete ;
} ;
2017-06-13 09:35:24 +00:00
// 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.
2018-10-17 09:12:38 +00:00
class Model : public ModelBase
2017-06-13 09:35:24 +00:00
{
2018-04-10 10:17:55 +00:00
static unsigned int s_auto_extruder_id ;
2017-06-13 09:35:24 +00:00
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 ( ) { }
2018-10-18 16:06:40 +00:00
Model ( const Model & rhs ) ;
Model & operator = ( const Model & rhs ) ;
2017-08-02 14:05:18 +00:00
~ Model ( ) { this - > clear_objects ( ) ; this - > clear_materials ( ) ; }
2018-09-17 10:15:11 +00:00
// XXX: use fs::path ?
2018-09-25 09:53:05 +00:00
static Model read_from_file ( const std : : string & input_file , DynamicPrintConfig * config = nullptr , bool add_default_instances = true ) ;
static Model read_from_archive ( const std : : string & input_file , DynamicPrintConfig * config , bool add_default_instances = true ) ;
2017-08-02 14:05:18 +00:00
2018-09-20 14:48:13 +00:00
/// Repair the ModelObjects of the current Model.
/// This function calls repair function on each TriangleMesh of each model object volume
void repair ( ) ;
2017-08-02 14:05:18 +00:00
2017-06-13 09:35:24 +00:00
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 ) ;
2018-01-30 08:27:10 +00:00
void delete_object ( ModelObject * object ) ;
2017-06-13 09:35:24 +00:00
void clear_objects ( ) ;
2014-05-09 12:24:35 +00:00
2017-06-13 09:35:24 +00:00
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 ( ) ;
2018-03-09 09:40:42 +00:00
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box ( ) const ;
2018-10-23 13:27:31 +00:00
// Set the print_volume_state of PrintObject::instances,
// return total number of printable objects.
unsigned int update_print_volume_state ( const BoundingBoxf3 & print_volume ) ;
2018-08-21 19:05:24 +00:00
void center_instances_around_point ( const Vec2d & point ) ;
2017-06-13 09:35:24 +00:00
void translate ( coordf_t x , coordf_t y , coordf_t z ) { for ( ModelObject * o : this - > objects ) o - > translate ( x , y , z ) ; }
TriangleMesh mesh ( ) const ;
2018-07-30 14:41:35 +00:00
bool arrange_objects ( coordf_t dist , const BoundingBoxf * bb = NULL ) ;
2017-06-13 09:35:24 +00:00
// 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 ) ;
2017-08-02 14:05:18 +00:00
bool looks_like_multipart_object ( ) const ;
2018-05-07 14:13:58 +00:00
void convert_multipart_object ( unsigned int max_extruders ) ;
2017-08-02 14:05:18 +00:00
2018-03-06 09:26:39 +00:00
// Ensures that the min z of the model is not negative
void adjust_min_z ( ) ;
2017-08-02 14:05:18 +00:00
void print_info ( ) const { for ( const ModelObject * o : this - > objects ) o - > print_info ( ) ; }
2018-04-10 10:17:55 +00:00
2018-05-07 14:13:58 +00:00
static unsigned int get_auto_extruder_id ( unsigned int max_extruders ) ;
static std : : string get_auto_extruder_id_as_string ( unsigned int max_extruders ) ;
2018-04-10 10:17:55 +00:00
static void reset_auto_extruder_id ( ) ;
2014-01-06 17:29:10 +00:00
} ;
}
# endif