mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	ENH: slicing: add cache data load/export for slicing
Change-Id: I88b7c79b6f79ec6bed0f829316b67310cac99b44 (cherry picked from commit 67c1d2e8dd459cc4450ce580632f01e25db038ac)
This commit is contained in:
		
							parent
							
								
									2ffa56633c
								
							
						
					
					
						commit
						c3abc64b61
					
				
					 13 changed files with 1471 additions and 192 deletions
				
			
		|  | @ -91,29 +91,6 @@ using namespace Slic3r; | |||
|     std::string message; | ||||
| }error_message;*/ | ||||
| 
 | ||||
| #define CLI_SUCCESS                 0 | ||||
| #define CLI_ENVIRONMENT_ERROR       -1 | ||||
| #define CLI_INVALID_PARAMS          -2 | ||||
| #define CLI_FILE_NOTFOUND           -3 | ||||
| #define CLI_FILELIST_INVALID_ORDER  -4 | ||||
| #define CLI_CONFIG_FILE_ERROR       -5 | ||||
| #define CLI_DATA_FILE_ERROR         -6 | ||||
| #define CLI_INVALID_PRINTER_TECH    -7 | ||||
| #define CLI_UNSUPPORTED_OPERATION   -8 | ||||
| 
 | ||||
| #define CLI_COPY_OBJECTS_ERROR      -9 | ||||
| #define CLI_SCALE_TO_FIT_ERROR      -10 | ||||
| #define CLI_EXPORT_STL_ERROR        -11 | ||||
| #define CLI_EXPORT_OBJ_ERROR        -12 | ||||
| #define CLI_EXPORT_3MF_ERROR        -13 | ||||
| 
 | ||||
| #define CLI_NO_SUITABLE_OBJECTS     -50 | ||||
| #define CLI_VALIDATE_ERROR          -51 | ||||
| #define CLI_OBJECTS_PARTLY_INSIDE   -52 | ||||
| 
 | ||||
| #define CLI_SLICING_ERROR           -100 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| std::map<int, std::string> cli_errors = { | ||||
|     {CLI_SUCCESS, "Success"}, | ||||
|  | @ -130,9 +107,15 @@ std::map<int, std::string> cli_errors = { | |||
|     {CLI_EXPORT_STL_ERROR, "Export stl error"}, | ||||
|     {CLI_EXPORT_OBJ_ERROR, "Export obj error"}, | ||||
|     {CLI_EXPORT_3MF_ERROR, "Export 3mf error"}, | ||||
|     {CLI_OUT_OF_MEMORY, "Out of memory"}, | ||||
|     {CLI_NO_SUITABLE_OBJECTS, "Found no objects in print volume to slice"}, | ||||
|     {CLI_VALIDATE_ERROR, "Validate print error"}, | ||||
|     {CLI_OBJECTS_PARTLY_INSIDE, "Objects partly inside"}, | ||||
|     {CLI_EXPORT_CACHE_DIRECTORY_CREATE_FAILED, "Objects partly inside"}, | ||||
|     {CLI_EXPORT_CACHE_WRITE_FAILED, "export cached slicedata failed"}, | ||||
|     {CLI_IMPORT_CACHE_NOT_FOUND, "cached slicedata can not be found"}, | ||||
|     {CLI_IMPORT_CACHE_DATA_CAN_NOT_USE, "cached slicedata can not be used"}, | ||||
|     {CLI_IMPORT_CACHE_LOAD_FAILED, "load cached slicedata failed"}, | ||||
|     {CLI_SLICING_ERROR, "Slice error"} | ||||
| }; | ||||
| 
 | ||||
|  | @ -374,12 +357,12 @@ int CLI::run(int argc, char **argv) | |||
|     int debug_argc = 7; | ||||
|     char *debug_argv[] = { | ||||
|         "E:\work\projects\bambu_release\bamboo_slicer\build_debug\src\Debug\bambu-studio.exe", | ||||
|         "--load-slicedata", | ||||
|         "cached_data", | ||||
|         "--slice", | ||||
|         "2", | ||||
|         "0", | ||||
|         "--export-3mf=output.3mf", | ||||
|         "--load-filaments", | ||||
|         "GFSA05.json;GFSA04.json;;GFSA05.json;GFSL23.json", | ||||
|         "majiang.3mf" | ||||
|         "test.3mf" | ||||
|         }; | ||||
|     if (! this->setup(debug_argc, debug_argv))*/ | ||||
|     if (!this->setup(argc, argv)) | ||||
|  | @ -1345,8 +1328,8 @@ int CLI::run(int argc, char **argv) | |||
|                 o->ensure_on_bed(); | ||||
| 
 | ||||
|     // loop through action options
 | ||||
|     bool export_to_3mf = false; | ||||
|     std::string export_3mf_file; | ||||
|     bool export_to_3mf = false, load_slicedata = false, export_slicedata = false, export_slicedata_error = false; | ||||
|     std::string export_3mf_file, load_slice_data_dir, export_slice_data_dir; | ||||
|     std::string outfile_dir = m_config.opt_string("outputdir"); | ||||
|     std::vector<ThumbnailData*> calibration_thumbnails; | ||||
|     for (auto const &opt_key : m_actions) { | ||||
|  | @ -1361,6 +1344,13 @@ int CLI::run(int argc, char **argv) | |||
|             std::string pipe_name = m_config.option<ConfigOptionString>("pipe")->value; | ||||
|             g_cli_callback_mgr.start(pipe_name); | ||||
| #endif | ||||
|         } else if (opt_key == "load_slicedata") { | ||||
|             load_slicedata = true; | ||||
|             load_slice_data_dir = m_config.opt_string(opt_key); | ||||
|             if (export_slicedata) { | ||||
|                 BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl; | ||||
|                 flush_and_exit(CLI_INVALID_PARAMS); | ||||
|             } | ||||
|         } else if (opt_key == "export_settings") { | ||||
|             //FIXME check for mixing the FFF / SLA parameters.
 | ||||
|             // or better save fff_print_config vs. sla_print_config
 | ||||
|  | @ -1377,7 +1367,7 @@ int CLI::run(int argc, char **argv) | |||
|                 model.add_default_instances(); | ||||
|             if (! this->export_models(IO::STL)) | ||||
|                 flush_and_exit(CLI_EXPORT_STL_ERROR); | ||||
|         } else if (opt_key == "expor1t_obj") { | ||||
|         } else if (opt_key == "export_obj") { | ||||
|             for (auto &model : m_models) | ||||
|                 model.add_default_instances(); | ||||
|             if (! this->export_models(IO::OBJ)) | ||||
|  | @ -1389,6 +1379,13 @@ int CLI::run(int argc, char **argv) | |||
|             export_to_3mf = true; | ||||
|             export_3mf_file = m_config.opt_string(opt_key); | ||||
|         //} else if (opt_key == "export_gcode" || opt_key == "export_sla" || opt_key == "slice") {
 | ||||
|         } else if (opt_key == "export_slicedata") { | ||||
|             export_slicedata = true; | ||||
|             export_slice_data_dir = m_config.opt_string(opt_key); | ||||
|             if (load_slicedata) { | ||||
|                 BOOST_LOG_TRIVIAL(error) << "should not set load_slicedata and export_slicedata together." << std::endl; | ||||
|                 flush_and_exit(CLI_INVALID_PARAMS); | ||||
|             } | ||||
|         } else if (opt_key == "slice") { | ||||
|             //BBS: slice 0 means all plates, i means plate i;
 | ||||
|             plate_to_slice = m_config.option<ConfigOptionInt>("slice")->value; | ||||
|  | @ -1530,7 +1527,23 @@ int CLI::run(int argc, char **argv) | |||
|                                 } | ||||
|                             } | ||||
| #endif | ||||
|                             print->process(); | ||||
|                             if (load_slicedata) { | ||||
|                                 std::string plate_dir = load_slice_data_dir+"/"+std::to_string(index+1); | ||||
|                                 int ret = print->load_cached_data(plate_dir); | ||||
|                                 if (ret) { | ||||
|                                     BOOST_LOG_TRIVIAL(warning) << "plate "<< index+1<< ": load Slicing data error, ret=" << ret; | ||||
|                                     BOOST_LOG_TRIVIAL(warning) << "plate "<< index+1<< ": switch normal slicing"; | ||||
|                                     print->process(); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     BOOST_LOG_TRIVIAL(info) << "plate "<< index+1<< ": load cached data success, go on."; | ||||
|                                     print->process(true); | ||||
|                                     BOOST_LOG_TRIVIAL(info) << "plate "<< index+1<< ": finished print::process."; | ||||
|                                 } | ||||
|                             } | ||||
|                             else { | ||||
|                                 print->process(); | ||||
|                             } | ||||
|                             if (printer_technology == ptFFF) { | ||||
|                                 // The outfile is processed by a PlaceholderParser.
 | ||||
|                                 //outfile = part_plate->get_tmp_gcode_path();
 | ||||
|  | @ -1569,6 +1582,18 @@ int CLI::run(int argc, char **argv) | |||
|                                 cli_status_callback(slicing_status); | ||||
|                             } | ||||
| #endif | ||||
|                             if (export_slicedata) { | ||||
|                                 BOOST_LOG_TRIVIAL(info) << "plate "<< index+1<< ":will export Slicing data to " << export_slice_data_dir; | ||||
|                                 std::string plate_dir = export_slice_data_dir+"/"+std::to_string(index+1); | ||||
|                                 bool with_space = (get_logging_level() >= 4)?true:false; | ||||
|                                 int ret = print->export_cached_data(plate_dir, with_space); | ||||
|                                 if (ret) { | ||||
|                                     BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": export Slicing data error, ret=" << ret; | ||||
|                                     export_slicedata_error = true; | ||||
|                                     if (fs::exists(plate_dir)) | ||||
|                                         fs::remove_all(plate_dir); | ||||
|                                 } | ||||
|                             } | ||||
|                         } catch (const std::exception &ex) { | ||||
|                             BOOST_LOG_TRIVIAL(info) << "found slicing or export error for partplate "<<index+1 << std::endl; | ||||
|                             boost::nowide::cerr << ex.what() << std::endl; | ||||
|  | @ -2037,8 +2062,9 @@ bool CLI::setup(int argc, char **argv) | |||
| #if !BBL_RELEASE_TO_PUBLIC | ||||
|     { | ||||
|         const ConfigOptionInt *opt_loglevel = m_config.opt<ConfigOptionInt>("debug"); | ||||
|         if (opt_loglevel != 0) | ||||
|         if (opt_loglevel != 0) { | ||||
|             set_logging_level(opt_loglevel->value); | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -137,6 +137,7 @@ public: | |||
|     // Height of the extrusion, used for visualization purposes.
 | ||||
|     float height; | ||||
| 
 | ||||
|     ExtrusionPath() : mm3_per_mm(-1), width(-1), height(-1), m_role(erNone), m_no_extrusion(false) {} | ||||
|     ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role), m_no_extrusion(false) {} | ||||
|     ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height, bool no_extrusion = false) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role), m_no_extrusion(no_extrusion) {} | ||||
|     ExtrusionPath(int overhang_degree, int curve_degree, ExtrusionRole role, double mm3_per_mm, float width, float height) : overhang_degree(overhang_degree), curve_degree(curve_degree), mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {} | ||||
|  | @ -225,6 +226,8 @@ public: | |||
|     void simplify_by_fitting_arc(double tolerance); | ||||
|     //BBS:
 | ||||
|     bool is_force_no_extrusion() const { return m_no_extrusion; } | ||||
|     void set_force_no_extrusion(bool no_extrusion) { m_no_extrusion = no_extrusion; } | ||||
|     void set_extrusion_role(ExtrusionRole extrusion_role) { m_role = extrusion_role; } | ||||
| 
 | ||||
| private: | ||||
|     void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const; | ||||
|  | @ -241,7 +244,7 @@ class ExtrusionMultiPath : public ExtrusionEntity | |||
| { | ||||
| public: | ||||
|     ExtrusionPaths paths; | ||||
|      | ||||
| 
 | ||||
|     ExtrusionMultiPath() {} | ||||
|     ExtrusionMultiPath(const ExtrusionMultiPath &rhs) : paths(rhs.paths) {} | ||||
|     ExtrusionMultiPath(ExtrusionMultiPath &&rhs) : paths(std::move(rhs.paths)) {} | ||||
|  | @ -278,7 +281,7 @@ public: | |||
|     double min_mm3_per_mm() const override; | ||||
|     Polyline as_polyline() const override; | ||||
|     void   collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); } | ||||
|     void   collect_points(Points &dst) const override {  | ||||
|     void   collect_points(Points &dst) const override { | ||||
|         size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); }); | ||||
|         dst.reserve(dst.size() + n); | ||||
|         for (const ExtrusionPath &p : this->paths) | ||||
|  | @ -292,11 +295,11 @@ class ExtrusionLoop : public ExtrusionEntity | |||
| { | ||||
| public: | ||||
|     ExtrusionPaths paths; | ||||
|      | ||||
| 
 | ||||
|     ExtrusionLoop(ExtrusionLoopRole role = elrDefault) : m_loop_role(role) {} | ||||
|     ExtrusionLoop(const ExtrusionPaths &paths, ExtrusionLoopRole role = elrDefault) : paths(paths), m_loop_role(role) {} | ||||
|     ExtrusionLoop(ExtrusionPaths &&paths, ExtrusionLoopRole role = elrDefault) : paths(std::move(paths)), m_loop_role(role) {} | ||||
|     ExtrusionLoop(const ExtrusionPath &path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role)  | ||||
|     ExtrusionLoop(const ExtrusionPath &path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role) | ||||
|         { this->paths.push_back(path); } | ||||
|     ExtrusionLoop(const ExtrusionPath &&path, ExtrusionLoopRole role = elrDefault) : m_loop_role(role) | ||||
|         { this->paths.emplace_back(std::move(path)); } | ||||
|  | @ -329,6 +332,7 @@ public: | |||
|     bool has_overhang_point(const Point &point) const; | ||||
|     ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); } | ||||
|     ExtrusionLoopRole loop_role() const { return m_loop_role; } | ||||
|     void set_loop_role(ExtrusionLoopRole role) {    m_loop_role = role; } | ||||
|     // Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
 | ||||
|     // Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
 | ||||
|     void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override; | ||||
|  | @ -344,7 +348,7 @@ public: | |||
|     double min_mm3_per_mm() const override; | ||||
|     Polyline as_polyline() const override { return this->polygon().split_at_first_point(); } | ||||
|     void   collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); } | ||||
|     void   collect_points(Points &dst) const override {  | ||||
|     void   collect_points(Points &dst) const override { | ||||
|         size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); }); | ||||
|         dst.reserve(dst.size() + n); | ||||
|         for (const ExtrusionPath &p : this->paths) | ||||
|  |  | |||
|  | @ -245,6 +245,7 @@ static constexpr const char* PATTERN_FILE_ATTR = "pattern_file"; | |||
| static constexpr const char* PATTERN_BBOX_FILE_ATTR = "pattern_bbox_file"; | ||||
| static constexpr const char* OBJECT_ID_ATTR = "object_id"; | ||||
| static constexpr const char* INSTANCEID_ATTR = "instance_id"; | ||||
| static constexpr const char* ARRANGE_ORDER_ATTR = "arrange_order"; | ||||
| static constexpr const char* PLATERID_ATTR = "plater_id"; | ||||
| static constexpr const char* PLATE_IDX_ATTR = "index"; | ||||
| static constexpr const char* SLICE_PREDICTION_ATTR = "prediction"; | ||||
|  | @ -604,6 +605,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|         { | ||||
|             int object_id; | ||||
|             int instance_id; | ||||
|             int arrange_order; | ||||
|         }; | ||||
| 
 | ||||
|         struct Instance | ||||
|  | @ -1123,6 +1125,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|         m_plater_data.clear(); | ||||
|         m_curr_instance.object_id = -1; | ||||
|         m_curr_instance.instance_id = -1; | ||||
|         m_curr_instance.arrange_order = 0; | ||||
|         clear_errors(); | ||||
| 
 | ||||
|         // restore
 | ||||
|  | @ -1570,7 +1573,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|                 return false; | ||||
|             } | ||||
|             if (current_plate_data) { | ||||
|                 std::map<int, int>::iterator it = current_plate_data->obj_inst_map.find(object.first.second); | ||||
|                 std::map<int, std::pair<int, int>>::iterator it = current_plate_data->obj_inst_map.find(object.first.second); | ||||
|                 if (it == current_plate_data->obj_inst_map.end()) { | ||||
|                     //not in current plate, skip
 | ||||
|                     BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", could not find object %1% in plate %2%, skip it\n")%object.first.second %plate_id; | ||||
|  | @ -1769,8 +1772,46 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|             plate_data_list[it->first-1]->pattern_file = (m_load_restore || it->second->pattern_file.empty()) ? it->second->pattern_file : m_backup_path + "/" + it->second->pattern_file; | ||||
|             plate_data_list[it->first-1]->pattern_bbox_file = (m_load_restore || it->second->pattern_bbox_file.empty()) ? it->second->pattern_bbox_file : m_backup_path + "/" + it->second->pattern_bbox_file; | ||||
|             plate_data_list[it->first-1]->config = it->second->config; | ||||
|             current_plate_data = plate_data_list[it->first - 1]; | ||||
|             BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate %1%, thumbnail_file=%2%")%it->first %plate_data_list[it->first-1]->thumbnail_file; | ||||
|             it++; | ||||
| 
 | ||||
|             //update the arrange order
 | ||||
|             std::map<int, std::pair<int, int>>::iterator map_it = current_plate_data->obj_inst_map.begin(); | ||||
|             while (map_it != current_plate_data->obj_inst_map.end()) { | ||||
|                 int obj_index, obj_id = map_it->first, inst_index = map_it->second.first; | ||||
|                 IndexToPathMap::iterator index_iter = m_index_paths.find(obj_id); | ||||
|                 if (index_iter == m_index_paths.end()) { | ||||
|                     BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ | ||||
|                         << boost::format(", can not find object from plate's obj_map, id=%1%, skip this object")%obj_id; | ||||
|                     map_it++; | ||||
|                     continue; | ||||
|                 } | ||||
|                 Id temp_id = std::make_pair(index_iter->second, index_iter->first); | ||||
|                 IdToModelObjectMap::iterator object_item = m_objects.find(temp_id); | ||||
|                 if (object_item == m_objects.end()) { | ||||
|                     BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ | ||||
|                         << boost::format(", can not find object from plate's obj_map, ID <%1%, %2%>, skip this object")%index_iter->second %index_iter->first; | ||||
|                     map_it++; | ||||
|                     continue; | ||||
|                 } | ||||
|                 obj_index = object_item->second; | ||||
| 
 | ||||
|                 if (obj_index >= m_model->objects.size()) { | ||||
|                     BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ << boost::format("invalid object id %1%\n")%obj_index; | ||||
|                     map_it++; | ||||
|                     continue; | ||||
|                 } | ||||
|                 ModelObject* obj =  m_model->objects[obj_index]; | ||||
|                 if (inst_index >= obj->instances.size()) { | ||||
|                     BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ << boost::format("invalid instance id %1%\n")%inst_index; | ||||
|                     map_it++; | ||||
|                     continue; | ||||
|                 } | ||||
|                 ModelInstance* inst =  obj->instances[inst_index]; | ||||
|                 inst->arrange_order = map_it->second.second; | ||||
|                 map_it++; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if ((plate_id > 0) && (plate_id <= m_plater_data.size())) { | ||||
|  | @ -3417,6 +3458,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|             { | ||||
|                 m_curr_instance.instance_id = atoi(value.c_str()); | ||||
|             } | ||||
|             else if (key == ARRANGE_ORDER_ATTR) | ||||
|             { | ||||
|                 m_curr_instance.arrange_order = atoi(value.c_str()); | ||||
|             } | ||||
|             else if (key == OBJECT_ID_ATTR) | ||||
|             { | ||||
|                 m_curr_instance.object_id = atoi(value.c_str()); | ||||
|  | @ -3570,11 +3615,13 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|             //add_error("invalid object id/instance id");
 | ||||
|             //skip this instance
 | ||||
|             m_curr_instance.object_id = m_curr_instance.instance_id = -1; | ||||
|             m_curr_instance.arrange_order = 0; | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         m_curr_plater->obj_inst_map.emplace(m_curr_instance.object_id, m_curr_instance.instance_id); | ||||
|         m_curr_plater->obj_inst_map.emplace(m_curr_instance.object_id, std::make_pair(m_curr_instance.instance_id, m_curr_instance.arrange_order)); | ||||
|         m_curr_instance.object_id = m_curr_instance.instance_id = -1; | ||||
|         m_curr_instance.arrange_order = 0; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|  | @ -6360,14 +6407,32 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) | |||
|                         stream << "    <" << INSTANCE_TAG << ">\n"; | ||||
|                         int obj_id = plate_data->objects_and_instances[j].first; | ||||
|                         int inst_id = plate_data->objects_and_instances[j].second; | ||||
|                         if (m_skip_static) { | ||||
|                             obj_id = model.objects[obj_id]->get_backup_id(); | ||||
|                         int arrange_o = 0; | ||||
|                         ModelObject* obj = NULL; | ||||
|                         ModelInstance* inst = NULL; | ||||
|                         if (obj_id >= model.objects.size()) { | ||||
|                             BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ << boost::format("invalid object id %1%\n")%obj_id; | ||||
|                         } | ||||
|                         else | ||||
|                             obj =  model.objects[obj_id]; | ||||
| 
 | ||||
|                         if (obj && (inst_id >= obj->instances.size())) { | ||||
|                             BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ":" << __LINE__ << boost::format("invalid instance id %1%\n")%inst_id; | ||||
|                         } | ||||
|                         else if (obj){ | ||||
|                             inst =  obj->instances[inst_id]; | ||||
|                             arrange_o = inst->arrange_order; | ||||
|                         } | ||||
|                         if (m_skip_static && obj) { | ||||
|                             obj_id = obj->get_backup_id(); | ||||
|                         } else { | ||||
|                             //inst_id = convert_instance_id_to_resource_id(model, obj_id, inst_id);
 | ||||
|                             obj_id = convert_instance_id_to_resource_id(model, obj_id, 0); | ||||
|                         } | ||||
| 
 | ||||
|                         stream << "      <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OBJECT_ID_ATTR << "\" " << VALUE_ATTR << "=\"" << obj_id << "\"/>\n"; | ||||
|                         stream << "      <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << INSTANCEID_ATTR << "\" " << VALUE_ATTR << "=\"" << inst_id << "\"/>\n"; | ||||
|                         stream << "      <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << ARRANGE_ORDER_ATTR << "\" " << VALUE_ATTR << "=\"" << arrange_o << "\"/>\n"; | ||||
|                         stream << "    </" << INSTANCE_TAG << ">\n"; | ||||
|                     } | ||||
|                 } | ||||
|  |  | |||
|  | @ -57,7 +57,7 @@ struct PlateData | |||
| 
 | ||||
|     int plate_index; | ||||
|     std::vector<std::pair<int, int>> objects_and_instances; | ||||
|     std::map<int, int> obj_inst_map; | ||||
|     std::map<int, std::pair<int, int>> obj_inst_map; | ||||
|     std::string     gcode_file; | ||||
|     std::string     gcode_file_md5; | ||||
|     std::string     thumbnail_file; | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ public: | |||
|     // ordered collection of extrusion paths to fill surfaces
 | ||||
|     // (this collection contains only ExtrusionEntityCollection objects)
 | ||||
|     ExtrusionEntityCollection   fills; | ||||
|      | ||||
| 
 | ||||
|     Flow    flow(FlowRole role) const; | ||||
|     Flow    flow(FlowRole role, double layer_height) const; | ||||
|     Flow    bridging_flow(FlowRole role, bool thick_bridge = false) const; | ||||
|  | @ -110,7 +110,7 @@ private: | |||
|     const PrintRegion *m_region; | ||||
| }; | ||||
| 
 | ||||
| class Layer  | ||||
| class Layer | ||||
| { | ||||
| public: | ||||
|     // Sequential index of this layer in PrintObject::m_layers, offsetted by the number of raft layers.
 | ||||
|  | @ -132,7 +132,7 @@ public: | |||
|     mutable ExPolygons          cantilevers; | ||||
|     mutable std::map<const ExPolygon*, float> sharp_tails_height; | ||||
| 
 | ||||
|     // Collection of expolygons generated by slicing the possibly multiple meshes of the source geometry 
 | ||||
|     // Collection of expolygons generated by slicing the possibly multiple meshes of the source geometry
 | ||||
|     // (with possibly differing extruder ID and slicing parameters) and merged.
 | ||||
|     // For the first layer, if the Elephant foot compensation is applied, this lslice is uncompensated, therefore
 | ||||
|     // it includes the Elephant foot effect, thus it corresponds to the shape of the printed 1st layer.
 | ||||
|  | @ -149,7 +149,7 @@ public: | |||
|     LayerRegion*            add_region(const PrintRegion *print_region); | ||||
|     const LayerRegionPtrs&  regions() const { return m_regions; } | ||||
|     // Test whether whether there are any slices assigned to this layer.
 | ||||
|     bool                    empty() const;     | ||||
|     bool                    empty() const; | ||||
|     void                    make_slices(); | ||||
|     // Backup and restore raw sliced regions if needed.
 | ||||
|     //FIXME Review whether not to simplify the code by keeping the raw_slices all the time.
 | ||||
|  | @ -209,7 +209,7 @@ private: | |||
|     LayerRegionPtrs     m_regions; | ||||
| }; | ||||
| 
 | ||||
| class SupportLayer : public Layer  | ||||
| class SupportLayer : public Layer | ||||
| { | ||||
| public: | ||||
|     // Polygons covered by the supports: base, interface and contact areas.
 | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -628,10 +628,13 @@ public: | |||
| 
 | ||||
|     ApplyStatus         apply(const Model &model, DynamicPrintConfig config) override; | ||||
| 
 | ||||
|     void                process() override; | ||||
|     void                process(bool use_cache = false) override; | ||||
|     // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file.
 | ||||
|     // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r).
 | ||||
|     std::string         export_gcode(const std::string& path_template, GCodeProcessorResult* result, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); | ||||
|     //return 0 means successful
 | ||||
|     int                 export_cached_data(const std::string& dir_path, bool with_space=false); | ||||
|     int                 load_cached_data(const std::string& directory); | ||||
| 
 | ||||
|     // methods for handling state
 | ||||
|     bool                is_step_done(PrintStep step) const { return Inherited::is_step_done(step); } | ||||
|  | @ -788,6 +791,7 @@ public: | |||
|     static float min_skirt_length; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } /* slic3r_Print_hpp_ */ | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -419,7 +419,9 @@ public: | |||
|     // After calling the apply() function, call set_task() to limit the task to be processed by process().
 | ||||
|     virtual void            set_task(const TaskParams ¶ms) {} | ||||
|     // Perform the calculation. This is the only method that is to be called at a worker thread.
 | ||||
|     virtual void            process() = 0; | ||||
|     virtual void            process(bool use_cache = false) = 0; | ||||
|     virtual int             export_cached_data(const std::string& dir_path, bool with_space=false) { return 0;} | ||||
|     virtual int            load_cached_data(const std::string& directory) { return 0;} | ||||
|     // Clean up after process() finished, either with success, error or if canceled.
 | ||||
|     // The adjustments on the Print / PrintObject data due to set_task() are to be reverted here.
 | ||||
|     virtual void            finalize() {} | ||||
|  |  | |||
|  | @ -4333,6 +4333,18 @@ CLIActionsConfigDef::CLIActionsConfigDef() | |||
|     def->cli_params = "filename.3mf"; | ||||
|     def->set_default_value(new ConfigOptionString("output.3mf")); | ||||
| 
 | ||||
|     def = this->add("export_slicedata", coString); | ||||
|     def->label = L("Export slicing data"); | ||||
|     def->tooltip = L("Export slicing data to a folder."); | ||||
|     def->cli_params = "slicing_data_directory"; | ||||
|     def->set_default_value(new ConfigOptionString("cached_data")); | ||||
| 
 | ||||
|     def = this->add("load_slicedata", coStrings); | ||||
|     def->label = L("Load slicing data"); | ||||
|     def->tooltip = L("Load cached slicing data from directory"); | ||||
|     def->cli_params = "slicing_data_directory"; | ||||
|     def->set_default_value(new ConfigOptionString("cached_data")); | ||||
| 
 | ||||
|     /*def = this->add("export_amf", coBool);
 | ||||
|     def->label = L("Export AMF"); | ||||
|     def->tooltip = L("Export the model(s) as AMF."); | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ bool is_zero_elevation(const SLAPrintObjectConfig &c) | |||
| sla::SupportTreeConfig make_support_cfg(const SLAPrintObjectConfig& c) | ||||
| { | ||||
|     sla::SupportTreeConfig scfg; | ||||
|      | ||||
| 
 | ||||
|     scfg.enabled = c.supports_enable.getBool(); | ||||
|     scfg.head_front_radius_mm = 0.5*c.support_head_front_diameter.getFloat(); | ||||
|     double pillar_r = 0.5 * c.support_pillar_diameter.getFloat(); | ||||
|  | @ -66,18 +66,18 @@ sla::SupportTreeConfig make_support_cfg(const SLAPrintObjectConfig& c) | |||
|     scfg.pillar_base_safety_distance_mm = | ||||
|         c.support_base_safety_distance.getFloat() < EPSILON ? | ||||
|             scfg.safety_distance_mm : c.support_base_safety_distance.getFloat(); | ||||
|      | ||||
| 
 | ||||
|     scfg.max_bridges_on_pillar = unsigned(c.support_max_bridges_on_pillar.getInt()); | ||||
|      | ||||
| 
 | ||||
|     return scfg; | ||||
| } | ||||
| 
 | ||||
| sla::PadConfig::EmbedObject builtin_pad_cfg(const SLAPrintObjectConfig& c) | ||||
| { | ||||
|     sla::PadConfig::EmbedObject ret; | ||||
|      | ||||
| 
 | ||||
|     ret.enabled = is_zero_elevation(c); | ||||
|      | ||||
| 
 | ||||
|     if(ret.enabled) { | ||||
|         ret.everywhere           = c.pad_around_object_everywhere.getBool(); | ||||
|         ret.object_gap_mm        = c.pad_object_gap.getFloat(); | ||||
|  | @ -86,24 +86,24 @@ sla::PadConfig::EmbedObject builtin_pad_cfg(const SLAPrintObjectConfig& c) | |||
|         ret.stick_penetration_mm = c.pad_object_connector_penetration | ||||
|                                        .getFloat(); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| sla::PadConfig make_pad_cfg(const SLAPrintObjectConfig& c) | ||||
| { | ||||
|     sla::PadConfig pcfg; | ||||
|      | ||||
| 
 | ||||
|     pcfg.wall_thickness_mm = c.pad_wall_thickness.getFloat(); | ||||
|     pcfg.wall_slope = c.pad_wall_slope.getFloat() * PI / 180.0; | ||||
|      | ||||
| 
 | ||||
|     pcfg.max_merge_dist_mm = c.pad_max_merge_distance.getFloat(); | ||||
|     pcfg.wall_height_mm = c.pad_wall_height.getFloat(); | ||||
|     pcfg.brim_size_mm = c.pad_brim_size.getFloat(); | ||||
|      | ||||
| 
 | ||||
|     // set builtin pad implicitly ON
 | ||||
|     pcfg.embed_object = builtin_pad_cfg(c); | ||||
|      | ||||
| 
 | ||||
|     return pcfg; | ||||
| } | ||||
| 
 | ||||
|  | @ -174,8 +174,8 @@ static std::vector<SLAPrintObject::Instance> sla_instances(const ModelObject &mo | |||
|     return instances; | ||||
| } | ||||
| 
 | ||||
| std::vector<ObjectID> SLAPrint::print_object_ids() const  | ||||
| {  | ||||
| std::vector<ObjectID> SLAPrint::print_object_ids() const | ||||
| { | ||||
|     std::vector<ObjectID> out; | ||||
|     // Reserve one more for the caller to append the ID of the Print itself.
 | ||||
|     out.reserve(m_objects.size() + 1); | ||||
|  | @ -238,7 +238,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con | |||
|     m_material_config.apply_only(config, material_diff, true); | ||||
|     // Handle changes to object config defaults
 | ||||
|     m_default_object_config.apply_only(config, object_diff, true); | ||||
|      | ||||
| 
 | ||||
|     if (m_printer) m_printer->apply(m_printer_config); | ||||
| 
 | ||||
|     struct ModelObjectStatus { | ||||
|  | @ -429,7 +429,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con | |||
|                     model_object.sla_support_points = model_object_new.sla_support_points; | ||||
|                 } | ||||
|                 model_object.sla_points_status = model_object_new.sla_points_status; | ||||
|                  | ||||
| 
 | ||||
|                 // Invalidate hollowing if drain holes have changed
 | ||||
|                 if (model_object.sla_drain_holes != model_object_new.sla_drain_holes) | ||||
|                 { | ||||
|  | @ -629,15 +629,15 @@ StringObjectException SLAPrint::validate(StringObjectException *exception, Polyg | |||
|         sla::SupportTreeConfig cfg = make_support_cfg(po->config()); | ||||
| 
 | ||||
|         double elv = cfg.object_elevation_mm; | ||||
|          | ||||
| 
 | ||||
|         sla::PadConfig padcfg = make_pad_cfg(po->config()); | ||||
|         sla::PadConfig::EmbedObject &builtinpad = padcfg.embed_object; | ||||
|          | ||||
| 
 | ||||
|         if(supports_en && !builtinpad.enabled && elv < cfg.head_fullwidth()) | ||||
|             return {L( | ||||
|                 "Elevation is too low for object. Use the \"Pad around " | ||||
|                 "object\" feature to print the object without elevation."), po}; | ||||
|          | ||||
| 
 | ||||
|         if(supports_en && builtinpad.enabled && | ||||
|            cfg.pillar_base_safety_distance_mm < builtinpad.object_gap_mm) { | ||||
|             return {L( | ||||
|  | @ -646,7 +646,7 @@ StringObjectException SLAPrint::validate(StringObjectException *exception, Polyg | |||
|                 "distance' has to be greater than the 'Pad object gap' " | ||||
|                 "parameter to avoid this."), po}; | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         std::string pval = padcfg.validate(); | ||||
|         if (!pval.empty()) return {pval, po}; | ||||
|     } | ||||
|  | @ -686,7 +686,7 @@ bool SLAPrint::invalidate_step(SLAPrintStep step) | |||
|     return invalidated; | ||||
| } | ||||
| 
 | ||||
| void SLAPrint::process() | ||||
| void SLAPrint::process(bool use_cache) | ||||
| { | ||||
|     if (m_objects.empty()) | ||||
|         return; | ||||
|  | @ -695,7 +695,7 @@ void SLAPrint::process() | |||
| 
 | ||||
|     // Assumption: at this point the print objects should be populated only with
 | ||||
|     // the model objects we have to process and the instances are also filtered
 | ||||
|      | ||||
| 
 | ||||
|     Steps printsteps(this); | ||||
| 
 | ||||
|     // We want to first process all objects...
 | ||||
|  | @ -709,7 +709,7 @@ void SLAPrint::process() | |||
|     }; | ||||
| 
 | ||||
|     SLAPrintStep print_steps[] = { slapsMergeSlicesAndEval, slapsRasterize }; | ||||
|      | ||||
| 
 | ||||
|     double st = Steps::min_objstatus; | ||||
| 
 | ||||
|     BOOST_LOG_TRIVIAL(info) << "Start slicing process."; | ||||
|  | @ -749,7 +749,7 @@ void SLAPrint::process() | |||
|                     throw_if_canceled(); | ||||
|                     po->set_done(step); | ||||
|                 } | ||||
|                  | ||||
| 
 | ||||
|                 incr = printsteps.progressrange(step); | ||||
|             } | ||||
|         } | ||||
|  | @ -760,7 +760,7 @@ void SLAPrint::process() | |||
| 
 | ||||
|     // this would disable the rasterization step
 | ||||
|     // std::fill(m_stepmask.begin(), m_stepmask.end(), false);
 | ||||
|      | ||||
| 
 | ||||
|     st = Steps::max_objstatus; | ||||
|     for(SLAPrintStep currentstep : print_steps) { | ||||
|         throw_if_canceled(); | ||||
|  | @ -774,7 +774,7 @@ void SLAPrint::process() | |||
|             throw_if_canceled(); | ||||
|             set_done(currentstep); | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         st += printsteps.progressrange(currentstep); | ||||
|     } | ||||
| 
 | ||||
|  | @ -1132,7 +1132,7 @@ const TriangleMesh& SLAPrintObject::support_mesh() const | |||
| { | ||||
|     if(m_config.supports_enable.getBool() && m_supportdata) | ||||
|         return m_supportdata->tree_mesh; | ||||
|      | ||||
| 
 | ||||
|     return EMPTY_MESH; | ||||
| } | ||||
| 
 | ||||
|  | @ -1149,7 +1149,7 @@ const indexed_triangle_set &SLAPrintObject::hollowed_interior_mesh() const | |||
|     if (m_hollowing_data && m_hollowing_data->interior && | ||||
|         m_config.hollowing_enable.getBool()) | ||||
|         return sla::get_mesh(*m_hollowing_data->interior); | ||||
|      | ||||
| 
 | ||||
|     return EMPTY_TRIANGLE_SET; | ||||
| } | ||||
| 
 | ||||
|  | @ -1174,7 +1174,7 @@ sla::SupportPoints SLAPrintObject::transformed_support_points() const | |||
|     for (sla::SupportPoint& suppt : spts) { | ||||
|         suppt.pos = tr * suppt.pos; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     return spts; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ public: | |||
|     // Get a pad mesh centered around origin in XY, and with zero rotation around Z applied.
 | ||||
|     // Support mesh is only valid if this->is_step_done(slaposPad) is true.
 | ||||
|     const TriangleMesh&     pad_mesh() const; | ||||
|      | ||||
| 
 | ||||
|     // Ready after this->is_step_done(slaposDrillHoles) is true
 | ||||
|     const indexed_triangle_set &hollowed_interior_mesh() const; | ||||
| 
 | ||||
|  | @ -201,7 +201,7 @@ private: | |||
|         { | ||||
|             return level<T>(r1) < level<T>(r2); | ||||
|         }); | ||||
|          | ||||
| 
 | ||||
|         if(it == cont.end()) return it; | ||||
| 
 | ||||
|         T diff = std::abs(level<T>(*it) - lvl); | ||||
|  | @ -307,18 +307,18 @@ private: | |||
| 
 | ||||
|     // Caching the transformed (m_trafo) raw mesh of the object
 | ||||
|     mutable CachedObject<TriangleMesh>      m_transformed_rmesh; | ||||
|      | ||||
| 
 | ||||
|     class SupportData : public sla::SupportableMesh | ||||
|     { | ||||
|     public: | ||||
|         sla::SupportTree::UPtr  support_tree_ptr; // the supports
 | ||||
|         std::vector<ExPolygons> support_slices;   // sliced supports
 | ||||
|         TriangleMesh tree_mesh, pad_mesh, full_mesh; | ||||
|          | ||||
| 
 | ||||
|         inline SupportData(const TriangleMesh &t) | ||||
|             : sla::SupportableMesh{t.its, {}, {}} | ||||
|         {} | ||||
|          | ||||
| 
 | ||||
|         sla::SupportTree::UPtr &create_support_tree(const sla::JobController &ctl) | ||||
|         { | ||||
|             support_tree_ptr = sla::SupportTree::create(*this, ctl); | ||||
|  | @ -335,9 +335,9 @@ private: | |||
|             pad_mesh = TriangleMesh{support_tree_ptr->retrieve_mesh(sla::MeshType::Pad)}; | ||||
|         } | ||||
|     }; | ||||
|      | ||||
| 
 | ||||
|     std::unique_ptr<SupportData> m_supportdata; | ||||
|      | ||||
| 
 | ||||
|     class HollowingData | ||||
|     { | ||||
|     public: | ||||
|  | @ -346,7 +346,7 @@ private: | |||
|         mutable TriangleMesh hollow_mesh_with_holes; // caching the complete hollowed mesh
 | ||||
|         mutable TriangleMesh hollow_mesh_with_holes_trimmed; | ||||
|     }; | ||||
|      | ||||
| 
 | ||||
|     std::unique_ptr<HollowingData> m_hollowing_data; | ||||
| }; | ||||
| 
 | ||||
|  | @ -390,15 +390,15 @@ struct SLAPrintStatistics | |||
| class SLAArchive { | ||||
| protected: | ||||
|     std::vector<sla::EncodedRaster> m_layers; | ||||
|      | ||||
| 
 | ||||
|     virtual std::unique_ptr<sla::RasterBase> create_raster() const = 0; | ||||
|     virtual sla::RasterEncoder get_encoder() const = 0; | ||||
|      | ||||
| 
 | ||||
| public: | ||||
|     virtual ~SLAArchive() = default; | ||||
|      | ||||
| 
 | ||||
|     virtual void apply(const SLAPrinterConfig &cfg) = 0; | ||||
|      | ||||
| 
 | ||||
|     // Fn have to be thread safe: void(sla::RasterBase& raster, size_t lyrid);
 | ||||
|     template<class Fn, class CancelFn, class EP = ExecutionTBB> | ||||
|     void draw_layers( | ||||
|  | @ -434,9 +434,9 @@ class SLAPrint : public PrintBaseWithState<SLAPrintStep, slapsCount> | |||
| { | ||||
| private: // Prevents erroneous use by other classes.
 | ||||
|     typedef PrintBaseWithState<SLAPrintStep, slapsCount> Inherited; | ||||
|      | ||||
| 
 | ||||
|     class Steps; // See SLAPrintSteps.cpp
 | ||||
|      | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     SLAPrint(): m_stepmask(slapsCount, true) {} | ||||
|  | @ -451,7 +451,7 @@ public: | |||
|     std::vector<ObjectID> print_object_ids() const override; | ||||
|     ApplyStatus         apply(const Model &model, DynamicPrintConfig config) override; | ||||
|     void                set_task(const TaskParams ¶ms) override; | ||||
|     void                process() override; | ||||
|     void                process(bool use_cache = false) override; | ||||
|     void                finalize() override; | ||||
|     // Returns true if an object step is done on all objects and there's at least one object.
 | ||||
|     bool                is_step_done(SLAPrintObjectStep step) const; | ||||
|  | @ -501,11 +501,11 @@ public: | |||
|         { | ||||
|             m_transformed_slices = std::forward<Container>(c); | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         friend class SLAPrint::Steps; | ||||
| 
 | ||||
|     public: | ||||
|          | ||||
| 
 | ||||
|         explicit PrintLayer(coord_t lvl) : m_level(lvl) {} | ||||
| 
 | ||||
|         // for being sorted in their container (see m_printer_input)
 | ||||
|  | @ -527,11 +527,11 @@ public: | |||
|     // The aggregated and leveled print records from various objects.
 | ||||
|     // TODO: use this structure for the preview in the future.
 | ||||
|     const std::vector<PrintLayer>& print_layers() const { return m_printer_input; } | ||||
|      | ||||
| 
 | ||||
|     void set_printer(SLAArchive *archiver); | ||||
|      | ||||
| 
 | ||||
| private: | ||||
|      | ||||
| 
 | ||||
|     // Implement same logic as in SLAPrintObject
 | ||||
|     bool invalidate_step(SLAPrintStep st); | ||||
| 
 | ||||
|  | @ -548,24 +548,24 @@ private: | |||
| 
 | ||||
|     // Ready-made data for rasterization.
 | ||||
|     std::vector<PrintLayer>         m_printer_input; | ||||
|      | ||||
| 
 | ||||
|     // The archive object which collects the raster images after slicing
 | ||||
|     SLAArchive                     *m_printer = nullptr; | ||||
|      | ||||
| 
 | ||||
|     // Estimated print time, material consumed.
 | ||||
|     SLAPrintStatistics              m_print_statistics; | ||||
|      | ||||
| 
 | ||||
|     class StatusReporter | ||||
|     { | ||||
|         double m_st = 0; | ||||
|          | ||||
| 
 | ||||
|     public: | ||||
|         void operator()(SLAPrint &         p, | ||||
|                         double             st, | ||||
|                         const std::string &msg, | ||||
|                         unsigned           flags = SlicingStatus::DEFAULT, | ||||
|                         const std::string &logmsg = ""); | ||||
|          | ||||
| 
 | ||||
|         double status() const { return m_st; } | ||||
|     } m_report_status; | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| enum SurfaceType {  | ||||
| enum SurfaceType { | ||||
|     // Top horizontal surface, visible from the top.
 | ||||
|     stTop, | ||||
|     // Bottom horizontal surface, visible from the bottom, printed with a normal extrusion flow.
 | ||||
|  | @ -39,10 +39,14 @@ public: | |||
|     unsigned short  thickness_layers;   // in layers
 | ||||
|     double          bridge_angle;       // in radians, ccw, 0 = East, only 0+ (negative means undefined)
 | ||||
|     unsigned short  extra_perimeters; | ||||
|      | ||||
| 
 | ||||
|     Surface(SurfaceType _surface_type = stInternal) | ||||
|         : surface_type(_surface_type), | ||||
|             thickness(-1), thickness_layers(1), bridge_angle(-1), extra_perimeters(0) | ||||
|         {}; | ||||
|     Surface(const Slic3r::Surface &rhs) | ||||
|         : surface_type(rhs.surface_type), expolygon(rhs.expolygon), | ||||
|             thickness(rhs.thickness), thickness_layers(rhs.thickness_layers),  | ||||
|             thickness(rhs.thickness), thickness_layers(rhs.thickness_layers), | ||||
|             bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters) | ||||
|         {}; | ||||
| 
 | ||||
|  | @ -52,12 +56,12 @@ public: | |||
|         {}; | ||||
|     Surface(const Surface &other, const ExPolygon &_expolygon) | ||||
|         : surface_type(other.surface_type), expolygon(_expolygon), | ||||
|             thickness(other.thickness), thickness_layers(other.thickness_layers),  | ||||
|             thickness(other.thickness), thickness_layers(other.thickness_layers), | ||||
|             bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters) | ||||
|         {}; | ||||
|     Surface(Surface &&rhs) | ||||
|         : surface_type(rhs.surface_type), expolygon(std::move(rhs.expolygon)), | ||||
|             thickness(rhs.thickness), thickness_layers(rhs.thickness_layers),  | ||||
|             thickness(rhs.thickness), thickness_layers(rhs.thickness_layers), | ||||
|             bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters) | ||||
|         {}; | ||||
|     Surface(SurfaceType _surface_type, const ExPolygon &&_expolygon) | ||||
|  | @ -66,7 +70,7 @@ public: | |||
|         {}; | ||||
|     Surface(const Surface &other, const ExPolygon &&_expolygon) | ||||
|         : surface_type(other.surface_type), expolygon(std::move(_expolygon)), | ||||
|             thickness(other.thickness), thickness_layers(other.thickness_layers),  | ||||
|             thickness(other.thickness), thickness_layers(other.thickness_layers), | ||||
|             bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters) | ||||
|         {}; | ||||
| 
 | ||||
|  | @ -194,8 +198,8 @@ inline size_t number_polygons(const SurfacesPtr &surfaces) | |||
| } | ||||
| 
 | ||||
| // Append a vector of Surfaces at the end of another vector of polygons.
 | ||||
| inline void polygons_append(Polygons &dst, const Surfaces &src)  | ||||
| {  | ||||
| inline void polygons_append(Polygons &dst, const Surfaces &src) | ||||
| { | ||||
|     dst.reserve(dst.size() + number_polygons(src)); | ||||
|     for (Surfaces::const_iterator it = src.begin(); it != src.end(); ++ it) { | ||||
|         dst.emplace_back(it->expolygon.contour); | ||||
|  | @ -203,8 +207,8 @@ inline void polygons_append(Polygons &dst, const Surfaces &src) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| inline void polygons_append(Polygons &dst, Surfaces &&src)  | ||||
| {  | ||||
| inline void polygons_append(Polygons &dst, Surfaces &&src) | ||||
| { | ||||
|     dst.reserve(dst.size() + number_polygons(src)); | ||||
|     for (Surfaces::iterator it = src.begin(); it != src.end(); ++ it) { | ||||
|         dst.emplace_back(std::move(it->expolygon.contour)); | ||||
|  | @ -214,8 +218,8 @@ inline void polygons_append(Polygons &dst, Surfaces &&src) | |||
| } | ||||
| 
 | ||||
| // Append a vector of Surfaces at the end of another vector of polygons.
 | ||||
| inline void polygons_append(Polygons &dst, const SurfacesPtr &src)  | ||||
| {  | ||||
| inline void polygons_append(Polygons &dst, const SurfacesPtr &src) | ||||
| { | ||||
|     dst.reserve(dst.size() + number_polygons(src)); | ||||
|     for (SurfacesPtr::const_iterator it = src.begin(); it != src.end(); ++ it) { | ||||
|         dst.emplace_back((*it)->expolygon.contour); | ||||
|  | @ -223,8 +227,8 @@ inline void polygons_append(Polygons &dst, const SurfacesPtr &src) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| inline void polygons_append(Polygons &dst, SurfacesPtr &&src)  | ||||
| {  | ||||
| inline void polygons_append(Polygons &dst, SurfacesPtr &&src) | ||||
| { | ||||
|     dst.reserve(dst.size() + number_polygons(src)); | ||||
|     for (SurfacesPtr::const_iterator it = src.begin(); it != src.end(); ++ it) { | ||||
|         dst.emplace_back(std::move((*it)->expolygon.contour)); | ||||
|  | @ -234,41 +238,41 @@ inline void polygons_append(Polygons &dst, SurfacesPtr &&src) | |||
| } | ||||
| 
 | ||||
| // Append a vector of Surfaces at the end of another vector of polygons.
 | ||||
| inline void surfaces_append(Surfaces &dst, const ExPolygons &src, SurfaceType surfaceType)  | ||||
| {  | ||||
| inline void surfaces_append(Surfaces &dst, const ExPolygons &src, SurfaceType surfaceType) | ||||
| { | ||||
|     dst.reserve(dst.size() + src.size()); | ||||
|     for (const ExPolygon &expoly : src) | ||||
|         dst.emplace_back(Surface(surfaceType, expoly)); | ||||
| } | ||||
| inline void surfaces_append(Surfaces &dst, const ExPolygons &src, const Surface &surfaceTempl)  | ||||
| {  | ||||
| inline void surfaces_append(Surfaces &dst, const ExPolygons &src, const Surface &surfaceTempl) | ||||
| { | ||||
|     dst.reserve(dst.size() + number_polygons(src)); | ||||
|     for (const ExPolygon &expoly : src) | ||||
|         dst.emplace_back(Surface(surfaceTempl, expoly)); | ||||
| } | ||||
| inline void surfaces_append(Surfaces &dst, const Surfaces &src)  | ||||
| {  | ||||
| inline void surfaces_append(Surfaces &dst, const Surfaces &src) | ||||
| { | ||||
|     dst.insert(dst.end(), src.begin(), src.end()); | ||||
| } | ||||
| 
 | ||||
| inline void surfaces_append(Surfaces &dst, ExPolygons &&src, SurfaceType surfaceType)  | ||||
| {  | ||||
| inline void surfaces_append(Surfaces &dst, ExPolygons &&src, SurfaceType surfaceType) | ||||
| { | ||||
|     dst.reserve(dst.size() + src.size()); | ||||
|     for (ExPolygon &expoly : src) | ||||
|         dst.emplace_back(Surface(surfaceType, std::move(expoly))); | ||||
|     src.clear(); | ||||
| } | ||||
| 
 | ||||
| inline void surfaces_append(Surfaces &dst, ExPolygons &&src, const Surface &surfaceTempl)  | ||||
| {  | ||||
| inline void surfaces_append(Surfaces &dst, ExPolygons &&src, const Surface &surfaceTempl) | ||||
| { | ||||
|     dst.reserve(dst.size() + number_polygons(src)); | ||||
|     for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++ it) | ||||
|         dst.emplace_back(Surface(surfaceTempl, std::move(*it))); | ||||
|     src.clear(); | ||||
| } | ||||
| 
 | ||||
| inline void surfaces_append(Surfaces &dst, Surfaces &&src)  | ||||
| {  | ||||
| inline void surfaces_append(Surfaces &dst, Surfaces &&src) | ||||
| { | ||||
|     if (dst.empty()) { | ||||
|         dst = std::move(src); | ||||
|     } else { | ||||
|  | @ -283,7 +287,7 @@ extern BoundingBox get_extents(const SurfacesPtr &surfaces); | |||
| 
 | ||||
| inline bool surfaces_could_merge(const Surface &s1, const Surface &s2) | ||||
| { | ||||
|     return  | ||||
|     return | ||||
|         s1.surface_type      == s2.surface_type     && | ||||
|         s1.thickness         == s2.thickness        && | ||||
|         s1.thickness_layers  == s2.thickness_layers && | ||||
|  |  | |||
|  | @ -13,6 +13,38 @@ | |||
| 
 | ||||
| #include "libslic3r.h" | ||||
| 
 | ||||
| //define CLI errors
 | ||||
| 
 | ||||
| #define CLI_SUCCESS                 0 | ||||
| #define CLI_ENVIRONMENT_ERROR       -1 | ||||
| #define CLI_INVALID_PARAMS          -2 | ||||
| #define CLI_FILE_NOTFOUND           -3 | ||||
| #define CLI_FILELIST_INVALID_ORDER  -4 | ||||
| #define CLI_CONFIG_FILE_ERROR       -5 | ||||
| #define CLI_DATA_FILE_ERROR         -6 | ||||
| #define CLI_INVALID_PRINTER_TECH    -7 | ||||
| #define CLI_UNSUPPORTED_OPERATION   -8 | ||||
| 
 | ||||
| #define CLI_COPY_OBJECTS_ERROR      -9 | ||||
| #define CLI_SCALE_TO_FIT_ERROR      -10 | ||||
| #define CLI_EXPORT_STL_ERROR        -11 | ||||
| #define CLI_EXPORT_OBJ_ERROR        -12 | ||||
| #define CLI_EXPORT_3MF_ERROR        -13 | ||||
| #define CLI_OUT_OF_MEMORY           -14 | ||||
| 
 | ||||
| #define CLI_NO_SUITABLE_OBJECTS     -50 | ||||
| #define CLI_VALIDATE_ERROR          -51 | ||||
| #define CLI_OBJECTS_PARTLY_INSIDE   -52 | ||||
| #define CLI_EXPORT_CACHE_DIRECTORY_CREATE_FAILED   -53 | ||||
| #define CLI_EXPORT_CACHE_WRITE_FAILED   -54 | ||||
| #define CLI_IMPORT_CACHE_NOT_FOUND      -55 | ||||
| #define CLI_IMPORT_CACHE_DATA_CAN_NOT_USE -56 | ||||
| #define CLI_IMPORT_CACHE_LOAD_FAILED      -57 | ||||
| 
 | ||||
| 
 | ||||
| #define CLI_SLICING_ERROR           -100 | ||||
| 
 | ||||
| 
 | ||||
| namespace boost { namespace filesystem { class directory_entry; }} | ||||
| 
 | ||||
| namespace Slic3r { | ||||
|  | @ -161,11 +193,11 @@ namespace PerlUtils { | |||
| 
 | ||||
| std::string string_printf(const char *format, ...); | ||||
| 
 | ||||
| // Standard "generated by Slic3r version xxx timestamp xxx" header string, 
 | ||||
| // Standard "generated by Slic3r version xxx timestamp xxx" header string,
 | ||||
| // to be placed at the top of Slic3r generated files.
 | ||||
| std::string header_slic3r_generated(); | ||||
| 
 | ||||
| // Standard "generated by PrusaGCodeViewer version xxx timestamp xxx" header string, 
 | ||||
| // Standard "generated by PrusaGCodeViewer version xxx timestamp xxx" header string,
 | ||||
| // to be placed at the top of Slic3r generated files.
 | ||||
| std::string header_gcodeviewer_generated(); | ||||
| 
 | ||||
|  | @ -247,38 +279,38 @@ inline INDEX_TYPE next_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count) | |||
| } | ||||
| 
 | ||||
| template<typename CONTAINER_TYPE> | ||||
| inline typename CONTAINER_TYPE::size_type prev_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container)  | ||||
| {  | ||||
| inline typename CONTAINER_TYPE::size_type prev_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) | ||||
| { | ||||
| 	return prev_idx_modulo(idx, container.size()); | ||||
| } | ||||
| 
 | ||||
| template<typename CONTAINER_TYPE> | ||||
| inline typename CONTAINER_TYPE::size_type next_idx_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) | ||||
| {  | ||||
| { | ||||
| 	return next_idx_modulo(idx, container.size()); | ||||
| } | ||||
| 
 | ||||
| template<typename CONTAINER_TYPE> | ||||
| inline const typename CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) | ||||
| {  | ||||
| { | ||||
| 	return container[prev_idx_modulo(idx, container.size())]; | ||||
| } | ||||
| 
 | ||||
| template<typename CONTAINER_TYPE> | ||||
| inline typename CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container)  | ||||
| {  | ||||
| inline typename CONTAINER_TYPE::value_type& prev_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container) | ||||
| { | ||||
| 	return container[prev_idx_modulo(idx, container.size())]; | ||||
| } | ||||
| 
 | ||||
| template<typename CONTAINER_TYPE> | ||||
| inline const typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER_TYPE::size_type idx, const CONTAINER_TYPE &container) | ||||
| {  | ||||
| { | ||||
| 	return container[next_idx_modulo(idx, container.size())]; | ||||
| } | ||||
| 
 | ||||
| template<typename CONTAINER_TYPE> | ||||
| inline typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER_TYPE::size_type idx, CONTAINER_TYPE &container) | ||||
| {  | ||||
| { | ||||
| 	return container[next_idx_modulo(idx, container.size())]; | ||||
| } | ||||
| 
 | ||||
|  | @ -300,7 +332,7 @@ template<typename T> struct IsTriviallyCopyable : public std::is_trivially_copya | |||
| struct FilePtr { | ||||
|     FilePtr(FILE *f) : f(f) {} | ||||
|     ~FilePtr() { this->close(); } | ||||
|     void close() {  | ||||
|     void close() { | ||||
|         if (this->f) { | ||||
|             ::fclose(this->f); | ||||
|             this->f = nullptr; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 lane.wei
						lane.wei