#ifndef __part_plate_hpp_ #define __part_plate_hpp_ #include #include #include #include #include #include "libslic3r/ObjectID.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp" #include "libslic3r/Format/bbs_3mf.hpp" #include "libslic3r/Slicing.hpp" #include "libslic3r/Arrange.hpp" #include "Plater.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/Print.hpp" #include "libslic3r/PrintConfig.hpp" #include "GLCanvas3D.hpp" #include "GLTexture.hpp" #include "3DScene.hpp" #include "GLModel.hpp" #include "3DBed.hpp" #include "libslic3r/ParameterUtils.hpp" class GLUquadric; typedef class GLUquadric GLUquadricObject; // use PLATE_CURRENT_IDX stands for using current plate // and use PLATE_ALL_IDX #define PLATE_CURRENT_IDX -1 #define PLATE_ALL_IDX -2 #define MAX_PLATE_COUNT 36 inline int compute_colum_count(int count) { float value = sqrt((float)count); float round_value = round(value); int cols; if (value > round_value) cols = round_value +1; else cols = round_value; return cols; } extern const float WIPE_TOWER_DEFAULT_X_POS; extern const float WIPE_TOWER_DEFAULT_Y_POS; // Max y extern const float I3_WIPE_TOWER_DEFAULT_X_POS; extern const float I3_WIPE_TOWER_DEFAULT_Y_POS; // Max y namespace Slic3r { class Model; class ModelObject; class ModelInstance; class Print; class SLAPrint; namespace GUI { class Plater; class GLCanvas3D; struct Camera; class PartPlateList; using GCodeResult = GCodeProcessorResult; class PartPlate : public ObjectBase { public: enum HeightLimitMode{ HEIGHT_LIMIT_NONE, HEIGHT_LIMIT_BOTTOM, HEIGHT_LIMIT_TOP, HEIGHT_LIMIT_BOTH }; private: PartPlateList* m_partplate_list {nullptr }; Plater* m_plater; //Plater reference, not own it Model* m_model; //Model reference, not own it PrinterTechnology printer_technology; std::set> obj_to_instance_set; std::set> instance_outside_set; int m_plate_index; Vec3d m_origin; int m_width; int m_depth; int m_height; float m_height_to_lid; float m_height_to_rod; bool m_printable; bool m_locked; bool m_ready_for_slice; bool m_slice_result_valid; bool m_apply_invalid {false}; float m_slice_percent; Print *m_print; //Print reference, not own it, no need to serialize GCodeProcessorResult *m_gcode_result; std::vector slice_filaments_info; int m_print_index; std::string m_tmp_gcode_path; //use a temp path to store the gcode std::string m_temp_config_3mf_path; //use a temp path to store the config 3mf std::string m_gcode_path_from_3mf; //use a path to store the gcode loaded from 3mf friend class PartPlateList; Pointfs m_raw_shape; Pointfs m_shape; Pointfs m_exclude_area; BoundingBoxf3 m_bounding_box; BoundingBoxf3 m_extended_bounding_box; mutable std::vector m_exclude_bounding_box; mutable BoundingBoxf3 m_grabber_box; Transform3d m_grabber_trans_matrix; Slic3r::Geometry::Transformation position; std::vector positions; unsigned int m_vbo_id{ 0 }; GeometryBuffer m_triangles; GeometryBuffer m_exclude_triangles; GeometryBuffer m_logo_triangles; GeometryBuffer m_gridlines; GeometryBuffer m_gridlines_bolder; GeometryBuffer m_height_limit_common; GeometryBuffer m_height_limit_bottom; GeometryBuffer m_height_limit_top; GeometryBuffer m_del_icon; GeometryBuffer m_plate_name_edit_icon; //GeometryBuffer m_del_and_background_icon; mutable unsigned int m_del_vbo_id{ 0 }; GeometryBuffer m_arrange_icon; mutable unsigned int m_arrange_vbo_id{ 0 }; GeometryBuffer m_orient_icon; mutable unsigned int m_orient_vbo_id{ 0 }; GeometryBuffer m_lock_icon; mutable unsigned int m_lock_vbo_id{ 0 }; GeometryBuffer m_plate_settings_icon; mutable unsigned int m_plate_settings_vbo_id{ 0 }; GeometryBuffer m_plate_idx_icon; mutable unsigned int m_plate_idx_vbo_id{ 0 }; mutable unsigned int m_plate_name_edit_vbo_id{0}; GLTexture m_texture; mutable float m_grabber_color[4]; float m_scale_factor{ 1.0f }; GLUquadricObject* m_quadric; int m_hover_id; bool m_selected; int m_timelapse_warning_code = 0; // BBS DynamicPrintConfig m_config; // part plate name std::string m_name; // utf8 string bool m_name_change = false; GeometryBuffer m_plate_name_icon; mutable unsigned int m_plate_name_vbo_id{0}; GLTexture m_name_texture; void init(); bool valid_instance(int obj_id, int instance_id); void generate_print_polygon(ExPolygon &print_polygon); void generate_exclude_polygon(ExPolygon &exclude_polygon); void generate_logo_polygon(ExPolygon &logo_polygon); void calc_bounding_boxes() const; void calc_triangles(const ExPolygon& poly); void calc_exclude_triangles(const ExPolygon& poly); void calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox); void calc_height_limit(); void calc_vertex_for_number(int index, bool one_number, GeometryBuffer &buffer); void calc_vertex_for_plate_name(GLTexture& texture, GeometryBuffer &buffer); void calc_vertex_for_plate_name_edit_icon(GLTexture *texture, int index, GeometryBuffer &buffer); void calc_vertex_for_icons(int index, GeometryBuffer &buffer); void calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer); void render_background(bool force_default_color = false) const; void render_logo(bool bottom, bool render_cali = true) const; void render_logo_texture(GLTexture& logo_texture, const GeometryBuffer& logo_buffer, bool bottom, unsigned int vbo_id) const; void render_exclude_area(bool force_default_color) const; //void render_background_for_picking(const float* render_color) const; void render_grid(bool bottom) const; void render_height_limit(PartPlate::HeightLimitMode mode = HEIGHT_LIMIT_BOTH) const; void render_label(GLCanvas3D& canvas) const; void render_grabber(const float* render_color, bool use_lighting) const; void render_face(float x_size, float y_size) const; void render_arrows(const float* render_color, bool use_lighting) const; void render_left_arrow(const float* render_color, bool use_lighting) const; void render_right_arrow(const float* render_color, bool use_lighting) const; void render_icon_texture(int position_id, int tex_coords_id, const GeometryBuffer &buffer, GLTexture &texture, unsigned int &vbo_id) const; void render_plate_name_texture(int position_id, int tex_coords_id); void render_icons(bool bottom, bool only_body = false, int hover_id = -1); void render_only_numbers(bool bottom) const; void render_rectangle_for_picking(const GeometryBuffer &buffer, const float* render_color) const; void on_render_for_picking() const; std::array picking_color_component(int idx) const; void release_opengl_resource(); public: static const unsigned int PLATE_BASE_ID = 255 * 255 * 253; static const unsigned int PLATE_NAME_HOVER_ID = 6; static const unsigned int GRABBER_COUNT = 7; static std::array SELECT_COLOR; static std::array UNSELECT_COLOR; static std::array UNSELECT_DARK_COLOR; static std::array DEFAULT_COLOR; static std::array LINE_BOTTOM_COLOR; static std::array LINE_TOP_COLOR; static std::array LINE_TOP_DARK_COLOR; static std::array LINE_TOP_SEL_COLOR; static std::array LINE_TOP_SEL_DARK_COLOR; static std::array HEIGHT_LIMIT_BOTTOM_COLOR; static std::array HEIGHT_LIMIT_TOP_COLOR; static void update_render_colors(); static void load_render_colors(); PartPlate(); PartPlate(PartPlateList *partplate_list, Vec3d origin, int width, int depth, int height, Plater* platerObj, Model* modelObj, bool printable=true, PrinterTechnology tech = ptFFF); ~PartPlate(); bool operator<(PartPlate&) const; //clear alll the instances in plate void clear(bool clear_sliced_result = true); BedType get_bed_type(bool load_from_project = false) const; void set_bed_type(BedType bed_type); void reset_bed_type(); DynamicPrintConfig* config() { return &m_config; } // set print sequence per plate //bool print_seq_same_global = true; void set_print_seq(PrintSequence print_seq = PrintSequence::ByDefault); PrintSequence get_print_seq() const; // Get the real effective print sequence of current plate. // If curr_plate's print_seq is ByDefault, use the global sequence // @return PrintSequence::{ByLayer,ByObject} PrintSequence get_real_print_seq(bool* plate_same_as_global=nullptr) const; bool has_spiral_mode_config() const; bool get_spiral_vase_mode() const; void set_spiral_vase_mode(bool spiral_mode, bool as_global); //static const int plate_x_offset = 20; //mm //static const double plate_x_gap = 0.2; ThumbnailData thumbnail_data; ThumbnailData no_light_thumbnail_data; static const int plate_thumbnail_width = 512; static const int plate_thumbnail_height = 512; ThumbnailData top_thumbnail_data; ThumbnailData pick_thumbnail_data; //ThumbnailData cali_thumbnail_data; PlateBBoxData cali_bboxes_data; //static const int cali_thumbnail_width = 2560; //static const int cali_thumbnail_height = 2560; //set the plate's index void set_index(int index); // get the plate's index int get_index() { return m_plate_index; } // get the plate's name std::string get_plate_name() const { return m_name; } bool generate_plate_name_texture(); // set the plate's name void set_plate_name(const std::string &name); void set_timelapse_warning_code(int code) { m_timelapse_warning_code = code; } int timelapse_warning_code() { return m_timelapse_warning_code; } //get the print's object, result and index void get_print(PrintBase **print, GCodeResult **result, int *index); //set the print object, result and it's index void set_print(PrintBase *print, GCodeResult* result = nullptr, int index = -1); //get gcode filename std::string get_gcode_filename(); bool is_valid_gcode_file(); //get the plate's center point origin Vec3d get_center_origin(); /* size and position related functions*/ //set position and size void set_pos_and_size(Vec3d& origin, int width, int depth, int height, bool with_instance_move, bool do_clear = true); // BBS Vec2d get_size() const { return Vec2d(m_width, m_depth); } ModelObjectPtrs get_objects() { return m_model->objects; } ModelObjectPtrs get_objects_on_this_plate(); ModelInstance* get_instance(int obj_id, int instance_id); BoundingBoxf3 get_objects_bounding_box(); Vec3d get_origin() { return m_origin; } Vec3d estimate_wipe_tower_size(const DynamicPrintConfig & config, const double w, const double wipe_volume, int plate_extruder_size = 0, bool use_global_objects = false) const; arrangement::ArrangePolygon estimate_wipe_tower_polygon(const DynamicPrintConfig & config, int plate_index, int plate_extruder_size = 0, bool use_global_objects = false) const; std::vector get_extruders(bool conside_custom_gcode = false) const; std::vector get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const; std::vector get_extruders_without_support(bool conside_custom_gcode = false) const; std::vector get_used_extruders(); /* instance related operations*/ //judge whether instance is bound in plate or not bool contain_instance(int obj_id, int instance_id); bool contain_instance_totally(ModelObject* object, int instance_id) const; //judge whether instance is totally included in plate or not bool contain_instance_totally(int obj_id, int instance_id) const; //judge whether the plate's origin is at the left of instance or not bool is_left_top_of(int obj_id, int instance_id); //check whether instance is outside the plate or not bool check_outside(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr); //judge whether instance is intesected with plate or not bool intersect_instance(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr); //add an instance into plate int add_instance(int obj_id, int instance_id, bool move_position, BoundingBoxf3* bounding_box = nullptr); //remove instance from plate int remove_instance(int obj_id, int instance_id); //translate instance on the plate void translate_all_instance(Vec3d position); //duplicate all instance for count void duplicate_all_instance(unsigned int dup_count, bool need_skip, std::map& skip_objects); //update instance exclude state void update_instance_exclude_status(int obj_id, int instance_id, BoundingBoxf3* bounding_box = nullptr); //update object's index caused by original object deleted void update_object_index(int obj_idx_removed, int obj_idx_max); // set objects configs when enabling spiral vase mode. void set_vase_mode_related_object_config(int obj_id = -1); //whether it is empty bool empty() { return obj_to_instance_set.empty(); } int printable_instance_size(); //whether it is has printable instances bool has_printable_instances(); bool is_all_instances_unprintable(); //move instances to left or right PartPlate void move_instances_to(PartPlate& left_plate, PartPlate& right_plate, BoundingBoxf3* bounding_box = nullptr); /*rendering related functions*/ const Pointfs& get_shape() const { return m_shape; } bool set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod); bool contains(const Vec3d& point) const; bool contains(const GLVolume& v) const; bool contains(const BoundingBoxf3& bb) const; bool intersects(const BoundingBoxf3& bb) const; void render(bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false); void render_for_picking() const { on_render_for_picking(); } void set_selected(); void set_unselected(); void set_hover_id(int id) { m_hover_id = id; } const BoundingBoxf3& get_bounding_box(bool extended = false) { return extended ? m_extended_bounding_box : m_bounding_box; } const BoundingBox get_bounding_box_crd(); BoundingBoxf3 get_plate_box() {return get_build_volume();} BoundingBoxf3 get_build_volume() { auto eps=Slic3r::BuildVolume::SceneEpsilon; Vec3d up_point = Vec3d(m_origin.x() + m_width + eps, m_origin.y() + m_depth + eps, m_origin.z() + m_height + eps); Vec3d low_point = Vec3d(m_origin.x() - eps, m_origin.y() - eps, m_origin.z() - eps); if (m_raw_shape.size() > 0) { up_point.x() += m_raw_shape[0].x(); up_point.y() += m_raw_shape[0].y(); low_point.x() += m_raw_shape[0].x(); low_point.y() += m_raw_shape[0].y(); } BoundingBoxf3 plate_box(low_point, up_point); return plate_box; } const std::vector& get_exclude_areas() { return m_exclude_bounding_box; } /*status related functions*/ //update status void update_states(); //is locked or not bool is_locked() const { return m_locked; } void lock(bool state) { m_locked = state; } //is a printable plate or not bool is_printable() const { return m_printable; } //can be sliced or not bool can_slice() const { return m_ready_for_slice && !m_apply_invalid; } void update_slice_ready_status(bool ready_slice) { m_ready_for_slice = ready_slice; } //bedtype mismatch or not bool is_apply_result_invalid() const { return m_apply_invalid; } void update_apply_result_invalid(bool invalid) { m_apply_invalid = invalid; } //is slice result valid or not bool is_slice_result_valid() const { return m_slice_result_valid; } //is slice result ready for print bool is_slice_result_ready_for_print() const { bool result = m_slice_result_valid; if (result) result = m_gcode_result ? (!m_gcode_result->toolpath_outside) : false;// && !m_gcode_result->conflict_result.has_value() gcode conflict can also print return result; } // check whether plate's slice result valid for export to file bool is_slice_result_ready_for_export() { return is_slice_result_ready_for_print() && has_printable_instances(); } //invalid sliced result void update_slice_result_valid_state(bool valid = false); void update_slicing_percent(float percent) { m_slice_percent = percent; } float get_slicing_percent() { return m_slice_percent; } /*slice related functions*/ //update current slice context into backgroud slicing process void update_slice_context(BackgroundSlicingProcess& process); //return the fff print object Print* fff_print() { return m_print; } //return the slice result GCodeProcessorResult* get_slice_result() { return m_gcode_result; } std::string get_tmp_gcode_path(); std::string get_temp_config_3mf_path(); //this API should only be used for command line usage void set_tmp_gcode_path(std::string new_path) { m_tmp_gcode_path = new_path; } //load gcode from file int load_gcode_from_file(const std::string& filename); //load thumbnail data from file int load_thumbnail_data(std::string filename, ThumbnailData& thumb_data); //load pattern thumbnail data from file int load_pattern_thumbnail_data(std::string filename); //load pattern box data from file int load_pattern_box_data(std::string filename); std::vector get_first_layer_print_sequence() const; std::vector get_other_layers_print_sequence() const; void set_first_layer_print_sequence(const std::vector &sorted_filaments); void set_other_layers_print_sequence(const std::vector& layer_seq_list); void update_first_layer_print_sequence(size_t filament_nums); void print() const; std::map get_diff_object_setting(); std::map get_diff_plate_setting(); friend class cereal::access; friend class UndoRedo::StackImpl; template void load(Archive& ar) { std::vector> objects_and_instances; std::vector> instances_outside; ar(m_plate_index, m_print_index, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_apply_invalid, m_printable, m_tmp_gcode_path, objects_and_instances, instances_outside, m_config, m_name); for (std::vector>::iterator it = objects_and_instances.begin(); it != objects_and_instances.end(); ++it) obj_to_instance_set.insert(std::pair(it->first, it->second)); for (std::vector>::iterator it = instances_outside.begin(); it != instances_outside.end(); ++it) instance_outside_set.insert(std::pair(it->first, it->second)); } template void save(Archive& ar) const { std::vector> objects_and_instances; std::vector> instances_outside; for (std::set>::iterator it = instance_outside_set.begin(); it != instance_outside_set.end(); ++it) instances_outside.emplace_back(it->first, it->second); for (std::set>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) objects_and_instances.emplace_back(it->first, it->second); ar(m_plate_index, m_print_index, m_locked, m_selected, m_ready_for_slice, m_slice_result_valid, m_apply_invalid, m_printable,m_tmp_gcode_path, objects_and_instances, instances_outside, m_config, m_name); } /*template void serialize(Archive& ar) { std::vector> objects_and_instances; for (std::set>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) objects_and_instances.emplace_back(it->first, it->second); ar(m_plate_index, m_origin, m_width, m_depth, m_height, m_locked, m_ready_for_slice, m_printable, objects_and_instances); }*/ }; class PartPlateList : public ObjectBase { Plater* m_plater; //Plater reference, not own it Model* m_model; //Model reference, not own it PrinterTechnology printer_technology; std::vector m_plate_list; std::map m_print_list; std::map m_gcode_result_list; std::mutex m_plates_mutex; int m_plate_count; int m_plate_cols; int m_current_plate; int m_print_index; int m_plate_width; int m_plate_depth; int m_plate_height; float m_height_to_lid; float m_height_to_rod; PartPlate::HeightLimitMode m_height_limit_mode{PartPlate::HEIGHT_LIMIT_BOTH}; PartPlate unprintable_plate; Pointfs m_shape; Pointfs m_exclude_areas; BoundingBoxf3 m_bounding_box; bool m_intialized; std::string m_logo_texture_filename; GLTexture m_logo_texture; GLTexture m_del_texture; GLTexture m_del_hovered_texture; GLTexture m_arrange_texture; GLTexture m_arrange_hovered_texture; GLTexture m_orient_texture; GLTexture m_orient_hovered_texture; GLTexture m_locked_texture; GLTexture m_locked_hovered_texture; GLTexture m_lockopen_texture; GLTexture m_lockopen_hovered_texture; GLTexture m_plate_settings_texture; GLTexture m_plate_settings_changed_texture; GLTexture m_plate_settings_hovered_texture; GLTexture m_plate_settings_changed_hovered_texture; GLTexture m_plate_name_edit_texture; GLTexture m_plate_name_edit_hovered_texture; GLTexture m_idx_textures[MAX_PLATE_COUNT]; // set render option bool render_bedtype_logo = true; bool render_plate_settings = true; bool render_cali_logo = true; bool m_is_dark = false; void init(); //compute the origin for printable plate with index i Vec3d compute_origin(int index, int column_count); //compute the origin for unprintable plate Vec3d compute_origin_for_unprintable(); //compute shape position Vec2d compute_shape_position(int index, int cols); //generate icon textures void generate_icon_textures(); void release_icon_textures(); void set_default_wipe_tower_pos_for_plate(int plate_idx); friend class cereal::access; friend class UndoRedo::StackImpl; friend class PartPlate; public: class BedTextureInfo { public: class TexturePart { public: // position float x; float y; float w; float h; unsigned int vbo_id; std::string filename; GLTexture* texture { nullptr }; Vec2d offset; GeometryBuffer* buffer { nullptr }; TexturePart(float xx, float yy, float ww, float hh, std::string file){ x = xx; y = yy; w = ww; h = hh; filename = file; texture = nullptr; buffer = nullptr; vbo_id = 0; offset = Vec2d(0, 0); } TexturePart(const TexturePart& part) { this->x = part.x; this->y = part.y; this->w = part.w; this->h = part.h; this->offset = part.offset; this->buffer = part.buffer; this->filename = part.filename; this->texture = part.texture; this->vbo_id = part.vbo_id; } void update_buffer(); void reset(); private: void release_vbo(); }; std::vector parts; void reset(); }; static const unsigned int MAX_PLATES_COUNT = MAX_PLATE_COUNT; static GLTexture bed_textures[(unsigned int)btCount]; static bool is_load_bedtype_textures; static bool is_load_cali_texture; PartPlateList(int width, int depth, int height, Plater* platerObj, Model* modelObj, PrinterTechnology tech = ptFFF); PartPlateList(Plater* platerObj, Model* modelObj, PrinterTechnology tech = ptFFF); ~PartPlateList(); //this may be happened after machine changed void reset_size(int width, int depth, int height, bool reload_objects = true, bool update_shapes = false); //clear all the instances in the plate, but keep the plates void clear(bool delete_plates = false, bool release_print_list = false, bool except_locked = false, int plate_index = -1); //clear all the instances in the plate, and delete the plates, only keep the first default plate void reset(bool do_init); //compute the origin for printable plate with index i using new width Vec3d compute_origin_using_new_size(int i, int new_width, int new_depth); //reset partplate to init states void reinit(); //get the plate stride double plate_stride_x(); double plate_stride_y(); void get_plate_size(int& width, int& depth, int& height) { width = m_plate_width; depth = m_plate_depth; height = m_plate_height; } /*basic plate operations*/ //create an empty plate and return its index int create_plate(bool adjust_position = true); //destroy print which has the index of print_index int destroy_print(int print_index); //delete a plate by index int delete_plate(int index); //delete a plate by pointer //int delete_plate(PartPlate* plate); void delete_selected_plate(); //get a plate pointer by index PartPlate* get_plate(int index); void get_height_limits(float& height_to_lid, float& height_to_rod) { height_to_lid = m_height_to_lid; height_to_rod = m_height_to_rod; } void set_height_limits_mode(PartPlate::HeightLimitMode mode) { m_height_limit_mode = mode; } int get_curr_plate_index() const { return m_current_plate; } PartPlate* get_curr_plate() { return m_plate_list[m_current_plate]; } const PartPlate *get_curr_plate() const { return m_plate_list[m_current_plate]; } std::vector& get_plate_list() { return m_plate_list; }; PartPlate* get_selected_plate(); std::vector get_nonempty_plate_list(); std::vector get_nonempty_plates_slice_results(); //compute the origin for printable plate with index i Vec3d get_current_plate_origin() { return compute_origin(m_current_plate, m_plate_cols); } Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); } Pointfs get_exclude_area() { return m_exclude_areas; } std::set get_extruders(bool conside_custom_gcode = false) const; //select plate int select_plate(int index); //get the plate counts, not including the invalid plate int get_plate_count() const; //update the plate cols due to plate count change void update_plate_cols(); void update_all_plates_pos_and_size(bool adjust_position = true, bool with_unprintable_move = true, bool switch_plate_type = false, bool do_clear = true); //get the plate cols int get_plate_cols() { return m_plate_cols; } //move the plate to position index int move_plate_to_index(int old_index, int new_index); //lock plate int lock_plate(int index, bool state); //is locked bool is_locked(int index) { return m_plate_list[index]->is_locked();} //find plate by print index, return -1 if not found int find_plate_by_print_index(int index); /*instance related operations*/ //find instance in which plate, return -1 when not found //this function only judges whether it is intersect with plate int find_instance(int obj_id, int instance_id); int find_instance(BoundingBoxf3& bounding_box); //find instance belongs to which plate //this function not only judges whether it is intersect with plate, but also judges whether it is fully included in plate //returns -1 when can not find any plate int find_instance_belongs(int obj_id, int instance_id); //notify instance's update, need to refresh the instance in plates int notify_instance_update(int obj_id, int instance_id, bool is_new = false); //notify instance is removed int notify_instance_removed(int obj_id, int instance_id); //add instance to special plate, need to remove from the original plate int add_to_plate(int obj_id, int instance_id, int plate_id); //reload all objects int reload_all_objects(bool except_locked = false, int plate_index = -1); //reload objects for newly created plate int construct_objects_list_for_new_plate(int plate_index); /* arrangement related functions */ //compute the plate index int compute_plate_index(arrangement::ArrangePolygon& arrange_polygon); //preprocess an arrangement::ArrangePolygon, return true if it is in a locked plate bool preprocess_arrange_polygon(int obj_index, int instance_index, arrangement::ArrangePolygon& arrange_polygon, bool selected); bool preprocess_arrange_polygon_other_locked(int obj_index, int instance_index, arrangement::ArrangePolygon& arrange_polygon, bool selected); bool preprocess_exclude_areas(arrangement::ArrangePolygons& unselected, int num_plates = 16, float inflation = 0); bool preprocess_nonprefered_areas(arrangement::ArrangePolygons& regions, int num_plates = 1, float inflation=0); void postprocess_bed_index_for_selected(arrangement::ArrangePolygon& arrange_polygon); void postprocess_bed_index_for_unselected(arrangement::ArrangePolygon& arrange_polygon); void postprocess_bed_index_for_current_plate(arrangement::ArrangePolygon& arrange_polygon); //postprocess an arrangement:;ArrangePolygon void postprocess_arrange_polygon(arrangement::ArrangePolygon& arrange_polygon, bool selected); /*rendering related functions*/ void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; } void render(bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false); void render_for_picking_pass(); void set_render_option(bool bedtype_texture, bool plate_settings); void set_render_cali(bool value = true) { render_cali_logo = value; } BoundingBoxf3& get_bounding_box() { return m_bounding_box; } //int select_plate_by_hover_id(int hover_id); int select_plate_by_obj(int obj_index, int instance_index); void calc_bounding_boxes(); void select_plate_view(); bool set_shapes(const Pointfs& shape, const Pointfs& exclude_areas, const std::string& custom_texture, float height_to_lid, float height_to_rod); void set_hover_id(int id); void reset_hover_id(); bool intersects(const BoundingBoxf3 &bb); bool contains(const BoundingBoxf3 &bb); const std::string &get_logo_texture_filename() { return m_logo_texture_filename; } void update_logo_texture_filename(const std::string &texture_filename); /*slice related functions*/ //update current slice context into backgroud slicing process void update_slice_context_to_current_plate(BackgroundSlicingProcess& process); //return the current fff print object Print& get_current_fff_print() const; //return the slice result GCodeProcessorResult* get_current_slice_result() const; //will create a plate and load gcode, return the plate index int create_plate_from_gcode_file(const std::string& filename); //invalid all the plater's slice result void invalid_all_slice_result(); //set current plater's slice result to valid void update_current_slice_result_state(bool valid) { m_plate_list[m_current_plate]->update_slice_result_valid_state(valid); } //is slice result valid or not bool is_all_slice_results_valid() const; bool is_all_slice_results_ready_for_print() const; bool is_all_plates_ready_for_slice() const; bool is_all_slice_result_ready_for_export() const; void print() const; //get the all the sliced result void get_sliced_result(std::vector& sliced_result, std::vector& gcode_paths); //retruct plates structures after de-serialize int rebuild_plates_after_deserialize(std::vector& previous_sliced_result, std::vector& previous_gcode_paths); //retruct plates structures after auto-arrangement int rebuild_plates_after_arrangement(bool recycle_plates = true, bool except_locked = false, int plate_index = -1); /* load/store releted functions, with_gcode = true and plate_idx = -1, export all gcode * if with_gcode = true and specify plate_idx, export plate_idx gcode only */ int store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool with_slice_info = true, int plate_idx = -1); int load_from_3mf_structure(PlateDataPtrs& plate_data_list); //load gcode files int load_gcode_files(); template void serialize(Archive& ar) { //ar(cereal::base_class(this)); //Cancel undo/redo for m_shape ,m_plate_width, m_plate_depth, m_plate_height,Because the printing area of different models is different, currently if the grid changes, it cannot correspond to the model on the left ui ar(m_height_to_lid, m_height_to_rod, m_height_limit_mode, m_plate_count, m_current_plate, m_plate_list, unprintable_plate); //ar(m_plate_width, m_plate_depth, m_plate_height, m_plate_count, m_current_plate); } void init_bed_type_info(); void load_bedtype_textures(); void show_cali_texture(bool show = true); void init_cali_texture_info(); void load_cali_textures(); BedTextureInfo bed_texture_info[btCount]; BedTextureInfo cali_texture_info; }; } // namespace GUI } // namespace Slic3r namespace cereal { template struct specialize {}; } #endif //__part_plate_hpp_