From 1d827bd96845dfb2cad2484a15f44b62968cbfb2 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Thu, 1 Dec 2022 21:34:04 +0800 Subject: [PATCH] ENH: optimize the cli slicing performance load/store json files in parallel Change-Id: I5b30463b06c922a83f84e525d6b1cd0c0555e911 (cherry picked from commit 41120270ea9bd562517aec08fbca87a9e39781ef) --- src/libslic3r/Print.cpp | 217 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d681ba1d1..ae1a7e8a0 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2937,6 +2937,8 @@ int Print::export_cached_data(const std::string& directory, bool with_space) } int count = 0; + std::vector filename_vector; + std::vector json_vector; for (PrintObject *obj : m_objects) { const ModelObject* model_obj = obj->model_object(); if (obj->get_shared_object()) { @@ -2957,17 +2959,77 @@ int Print::export_cached_data(const std::string& directory, bool with_space) root_json[JSON_ARRANGE_ORDER] = arrange_order; //export the layers - for (const Layer *layer : obj->layers()) { + std::vector layers_json_vector(obj->layer_count()); + tbb::parallel_for( + tbb::blocked_range(0, obj->layer_count()), + [&layers_json_vector, obj, convert_layer_to_json](const tbb::blocked_range& layer_range) { + for (size_t layer_index = layer_range.begin(); layer_index < layer_range.end(); ++ layer_index) { + const Layer *layer = obj->get_layer(layer_index); + json layer_json; + convert_layer_to_json(layer_json, layer); + layers_json_vector[layer_index] = std::move(layer_json); + } + } + ); + for (int l_index = 0; l_index < layers_json_vector.size(); l_index++) { + layers_json.push_back(std::move(layers_json_vector[l_index])); + } + layers_json_vector.clear(); + /*for (const Layer *layer : obj->layers()) { + // for each layer json layer_json; convert_layer_to_json(layer_json, layer); layers_json.push_back(std::move(layer_json)); - } // for each layer + }*/ + root_json[JSON_LAYERS] = std::move(layers_json); //export the support layers - for (const SupportLayer *support_layer : obj->support_layers()) { + std::vector support_layers_json_vector(obj->support_layer_count()); + tbb::parallel_for( + tbb::blocked_range(0, obj->support_layer_count()), + [&support_layers_json_vector, obj, convert_layer_to_json](const tbb::blocked_range& support_layer_range) { + for (size_t s_layer_index = support_layer_range.begin(); s_layer_index < support_layer_range.end(); ++ s_layer_index) { + const SupportLayer *support_layer = obj->get_support_layer(s_layer_index); + json support_layer_json, support_islands_json = json::array(), support_fills_json, supportfills_entities_json = json::array(); + + convert_layer_to_json(support_layer_json, support_layer); + + support_layer_json[JSON_SUPPORT_LAYER_INTERFACE_ID] = support_layer->interface_id(); + + //support_islands + for (const ExPolygon& support_island : support_layer->support_islands.expolygons) { + json support_island_json = support_island; + support_islands_json.push_back(std::move(support_island_json)); + } + support_layer_json[JSON_SUPPORT_LAYER_ISLANDS] = std::move(support_islands_json); + + //support_fills + support_fills_json[JSON_EXTRUSION_NO_SORT] = support_layer->support_fills.no_sort; + support_fills_json[JSON_EXTRUSION_ENTITY_TYPE] = JSON_EXTRUSION_TYPE_COLLECTION; + for (const ExtrusionEntity* extrusion_entity : support_layer->support_fills.entities) { + json supportfill_entity_json, supportfill_entity_paths_json = json::array(); + bool ret = convert_extrusion_to_json(supportfill_entity_json, supportfill_entity_paths_json, extrusion_entity); + if (!ret) + continue; + + supportfills_entities_json.push_back(std::move(supportfill_entity_json)); + } + support_fills_json[JSON_EXTRUSION_ENTITIES] = std::move(supportfills_entities_json); + support_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(support_fills_json); + + support_layers_json_vector[s_layer_index] = std::move(support_layer_json); + } + } + ); + for (int s_index = 0; s_index < support_layers_json_vector.size(); s_index++) { + support_layers_json.push_back(std::move(support_layers_json_vector[s_index])); + } + support_layers_json_vector.clear(); + + /*for (const SupportLayer *support_layer : obj->support_layers()) { json support_layer_json, support_islands_json = json::array(), support_fills_json, supportfills_entities_json = json::array(); convert_layer_to_json(support_layer_json, support_layer); @@ -2996,10 +3058,80 @@ int Print::export_cached_data(const std::string& directory, bool with_space) support_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(support_fills_json); support_layers_json.push_back(std::move(support_layer_json)); - } // for each layer + } // for each layer*/ root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json); //export the tree support layers + std::vector tree_support_layers_json_vector(obj->tree_support_layer_count()); + tbb::parallel_for( + tbb::blocked_range(0, obj->tree_support_layer_count()), + [&tree_support_layers_json_vector, obj, convert_layer_to_json](const tbb::blocked_range& tree_support_layer_range) { + for (size_t ts_layer_index = tree_support_layer_range.begin(); ts_layer_index < tree_support_layer_range.end(); ++ ts_layer_index) { + const TreeSupportLayer *tree_support_layer = obj->get_tree_support_layer(ts_layer_index); + json treesupport_layer_json, treesupport_fills_json, treesupportfills_entities_json = json::array(); + //json overhang_areas_json = json::array(), roof_areas_json = json::array(), roof_1st_layer_json = json::array(), floor_areas_json = json::array(), base_areas_json = json::array(); + + convert_layer_to_json(treesupport_layer_json, tree_support_layer); + + //tree_support_fills + treesupport_fills_json[JSON_EXTRUSION_NO_SORT] = tree_support_layer->support_fills.no_sort; + treesupport_fills_json[JSON_EXTRUSION_ENTITY_TYPE] = JSON_EXTRUSION_TYPE_COLLECTION; + for (const ExtrusionEntity* extrusion_entity : tree_support_layer->support_fills.entities) { + json treesupportfill_entity_json, treesupportfill_entity_paths_json = json::array(); + bool ret = convert_extrusion_to_json(treesupportfill_entity_json, treesupportfill_entity_paths_json, extrusion_entity); + if (!ret) + continue; + + treesupportfills_entities_json.push_back(std::move(treesupportfill_entity_json)); + } + treesupport_fills_json[JSON_EXTRUSION_ENTITIES] = std::move(treesupportfills_entities_json); + treesupport_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(treesupport_fills_json); + + //following data are not needed in the later stage + //overhang_areas + /*for (const ExPolygon& overhang_area : tree_support_layer->overhang_areas) { + json overhang_area_json = overhang_area; + overhang_areas_json.push_back(std::move(overhang_area_json)); + } + treesupport_layer_json["overhang_areas"] = std::move(overhang_areas_json); + + //roof_areas + for (const ExPolygon& roof_area : tree_support_layer->roof_areas) { + json roof_area_json = roof_area; + roof_areas_json.push_back(std::move(roof_area_json)); + } + treesupport_layer_json["roof_areas"] = std::move(roof_areas_json); + + //roof_1st_layer + for (const ExPolygon& layer_poly : tree_support_layer->roof_1st_layer) { + json layer_poly_json = layer_poly; + roof_1st_layer_json.push_back(std::move(layer_poly_json)); + } + treesupport_layer_json["roof_1st_layer"] = std::move(roof_1st_layer_json); + + //floor_areas + for (const ExPolygon& floor_area : tree_support_layer->floor_areas) { + json floor_area_json = floor_area; + floor_areas_json.push_back(std::move(floor_area_json)); + } + treesupport_layer_json["floor_areas"] = std::move(floor_areas_json); + + //base_areas + for (const ExPolygon& base_area : tree_support_layer->base_areas) { + json base_area_json = base_area; + base_areas_json.push_back(std::move(base_area_json)); + } + treesupport_layer_json["base_areas"] = std::move(base_areas_json);*/ + + tree_support_layers_json_vector[ts_layer_index] = std::move(treesupport_layer_json); + } + } + ); + for (int ts_index = 0; ts_index < tree_support_layers_json_vector.size(); ts_index++) { + tree_support_layers_json.push_back(std::move(tree_support_layers_json_vector[ts_index])); + } + tree_support_layers_json_vector.clear(); +#if 0 for (const TreeSupportLayer *tree_support_layer : obj->tree_support_layers()) { json treesupport_layer_json, treesupport_fills_json, treesupportfills_entities_json = json::array(); json overhang_areas_json = json::array(), roof_areas_json = json::array(), roof_1st_layer_json = json::array(), floor_areas_json = json::array(), base_areas_json = json::array(); @@ -3057,17 +3189,20 @@ int Print::export_cached_data(const std::string& directory, bool with_space) tree_support_layers_json.push_back(std::move(treesupport_layer_json)); } // for each layer +#endif root_json[JSON_TREE_SUPPORT_LAYERS] = std::move(tree_support_layers_json); - boost::nowide::ofstream c; + filename_vector.push_back(file_name); + json_vector.push_back(std::move(root_json)); + /*boost::nowide::ofstream c; c.open(file_name, std::ios::out | std::ios::trunc); if (with_space) c << std::setw(4) << root_json << std::endl; else c << root_json.dump(0) << std::endl; - c.close(); + c.close();*/ count ++; - BOOST_LOG_TRIVIAL(info) << boost::format("dump object %1% to %2% successfully.")%model_obj->name%file_name; + BOOST_LOG_TRIVIAL(info) << boost::format("will dump object %1%'s json to %2%.")%model_obj->name%file_name; } catch(std::exception &err) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": save to "<> object_filenames; for (PrintObject *obj : m_objects) { const ModelObject* model_obj = obj->model_object(); const PrintInstance &print_instance = obj->instances()[0]; @@ -3123,12 +3282,42 @@ int Print::load_cached_data(const std::string& directory) BOOST_LOG_TRIVIAL(info) << __FUNCTION__< object_jsons(object_filenames.size()); + tbb::parallel_for( + tbb::blocked_range(0, object_filenames.size()), + [object_filenames, &ret, &object_jsons, &mutex](const tbb::blocked_range& filename_range) { + for (size_t filename_index = filename_range.begin(); filename_index < filename_range.end(); ++ filename_index) { + try { + json root_json; + boost::nowide::ifstream ifs(object_filenames[filename_index].first); + ifs >> root_json; + object_jsons[filename_index] = std::move(root_json); + } + catch(std::exception &err) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": load from "<> root_json; + //boost::nowide::ifstream ifs(file_name); + //ifs >> root_json; std::string name = root_json.at(JSON_OBJECT_NAME); int order = root_json.at(JSON_ARRANGE_ORDER); @@ -3249,18 +3438,20 @@ int Print::load_cached_data(const std::string& directory) ); count ++; - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format("load object %1% from %2% successfully.")%model_obj->name%file_name; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first; } catch(nlohmann::detail::parse_error &err) { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<