diff --git a/lib/Slic3r/Model.pm b/lib/Slic3r/Model.pm index efd331f1..d51d183e 100644 --- a/lib/Slic3r/Model.pm +++ b/lib/Slic3r/Model.pm @@ -20,18 +20,6 @@ sub read_from_file { return $model; } -sub merge { - my $class = shift; - my @models = @_; - - my $new_model = ref($class) - ? $class - : $class->new; - - $new_model->add_object($_) for map @{$_->objects}, @models; - return $new_model; -} - sub add_object { my $self = shift; diff --git a/xs/src/Model.cpp b/xs/src/Model.cpp new file mode 100644 index 00000000..a4f5b9b2 --- /dev/null +++ b/xs/src/Model.cpp @@ -0,0 +1,84 @@ +#include "Model.hpp" + +namespace Slic3r { + +Model::~Model() +{ + for (t_model_materials::iterator it = this->materials.begin(); it != this->materials.end(); ++it) + delete it->second; + for (t_model_objects::iterator it = this->objects.begin(); it != this->objects.end(); ++it) + delete *it; +} + +ModelObject* +Model::add_object() +{ + ModelObject* retval = new ModelObject(this); + this->objects.push_back(retval); + return retval; +} + +ModelObject* +Model::add_object(const ModelObject &object) +{ + ModelObject* retval = new ModelObject(this, object); + this->objects.push_back(retval); + return retval; +} + +void +Model::delete_object(size_t obj_idx) +{ + this->objects.erase(this->objects.begin() + obj_idx); +} + +void +Model::delete_all_objects() +{ + this->objects.clear(); +} + +ModelMaterial* +Model::set_material(t_model_material_id material_id, const t_model_material_attributes &attributes) +{ + ModelMaterial* material; + + // create material if it does not exist + t_model_materials::iterator itm = this->materials.find(material_id); + if (itm == this->materials.end()) { + material = new ModelMaterial(this); + this->materials[material_id] = material; + } else { + material = *itm; + } + + // apply attributes + for (t_model_material_attributes::const_iterator it = attributes.begin(); it != attributes.end(); ++it) { + material->attributes[it->first] = it->second; + } + + return material; +} + +void +Model::duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance) +{ + if (this->objects.size() > 1) throw "Grid duplication is not supported with multiple objects"; + + ModelObject* object = this->objects.front(); + object->instances.clear(); + + BoundingBoxf3 bb; + object->bounding_box(&bb); + Sizef3 size = bb.size(); + + for (unsigned int x_copy = 1; x_copy <= x; ++x_copy) { + for (unsigned int y_copy = 1; y_copy <= y; ++y_copy) { + ModelInstance* instance = object->add_instance(); + instance->offset.x = (size.x + distance) * (x_copy-1); + instance->offset.y = (size.y + distance) * (y_copy-1); + } + } +} + +} diff --git a/xs/src/Model.hpp b/xs/src/Model.hpp index 6e16e8fa..cfd35adb 100644 --- a/xs/src/Model.hpp +++ b/xs/src/Model.hpp @@ -24,22 +24,26 @@ typedef std::map t_model_material_attrib class Model { - public: - std::map materials; - std::vector objects; + typedef std::map t_model_materials; + typedef std::vector t_model_objects; - Model(); + public: + t_model_materials materials; + t_model_objects objects; + + Model() {}; ~Model(); + ModelObject* add_object(); ModelObject* add_object(const ModelObject &object); void delete_object(size_t obj_idx); void delete_all_objects(); - void set_material(t_model_material_id material_id, const t_model_material_attributes &attributes); - void duplicate_objects_grid(coordf_t x, coordf_t y, coordf_t distance); - void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBox &bb); - void arrange_objects(coordf_t distance, const BoundingBox &bb); - void duplicate(size_t copies_num, coordf_t distance, const BoundingBox &bb); + ModelMaterial* set_material(t_model_material_id material_id, const t_model_material_attributes &attributes); + void duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance); + void duplicate_objects(size_t copies_num, coordf_t distance, const BoundingBoxf &bb); + void arrange_objects(coordf_t distance, const BoundingBoxf &bb); + void duplicate(size_t copies_num, coordf_t distance, const BoundingBoxf &bb); bool has_objects_with_no_instances() const; - void bounding_box(BoundingBox* bb) const; + void bounding_box(BoundingBoxf3* bb) const; void align_to_origin(); void center_instances_around_point(const Pointf &point); void translate(coordf_t x, coordf_t y, coordf_t z); @@ -48,35 +52,44 @@ class Model std::string get_material_name(t_model_material_id material_id); private: - void _arrange(const std::vector &sizes, coordf_t distance, const BoundingBox &bb) const; + void _arrange(const std::vector &sizes, coordf_t distance, const BoundingBoxf &bb, Pointfs* positions) const; }; class ModelMaterial { public: - Model* model; + ModelMaterial(Model* _model) : model(_model) {}; t_model_material_attributes attributes; DynamicConfig config; + Model* getModel() const; + + private: + Model* model; }; class ModelObject { public: - Model* model; std::string input_file; std::vector instances; std::vector volumes; DynamicConfig config; t_layer_height_ranges layer_height_ranges; + Vector origin_translation; // translation vector applied by center_around_origin() - ModelObject(); + ModelObject(Model* _model) : model(_model) {}; + ModelObject(Model* _model, const ModelObject &object); ~ModelObject(); + ModelInstance* add_instance(); ModelInstance* add_instance(const ModelInstance &instance); + ModelVolume* add_volume(); ModelVolume* add_volume(const ModelVolume &volume); + void delete_volume(size_t volume_idx); void delete_last_instance(); void raw_mesh(TriangleMesh* mesh) const; void mesh(TriangleMesh* mesh) const; - void instance_bounding_box(size_t instance_idx, BoundingBox* bb) const; + void bounding_box(BoundingBoxf3* bb); + void instance_bounding_box(size_t instance_idx, BoundingBoxf3* bb) const; void center_around_origin(); void translate(coordf_t x, coordf_t y, coordf_t z); size_t materials_count() const; @@ -85,28 +98,38 @@ class ModelObject bool needed_repair() const; private: - BoundingBox bb; + Model* model; + BoundingBoxf bb; void update_bounding_box(); }; class ModelVolume { public: - ModelObject* object; + ModelVolume(ModelObject* _object) : object(_object), modifier(false) {}; t_model_material_id material_id; TriangleMesh mesh; + bool modifier; + + ModelMaterial* assign_unique_material(); + + private: + ModelObject* object; }; class ModelInstance { public: - ModelObject* object; double rotation; double scaling_factor; Pointf offset; + ModelInstance(ModelObject* _object) : object(_object), rotation(0), scaling_factor(1) {}; void transform_mesh(TriangleMesh* mesh, bool dont_translate) const; void transform_polygon(Polygon* polygon) const; + + private: + ModelObject* object; }; }