diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 5f11dd9acf..822d5f3ded 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -374,18 +374,18 @@ int CLI::run(int argc, char **argv) /*BOOST_LOG_TRIVIAL(info) << "begin to setup params, argc=" << argc << std::endl; for (int index=0; index < argc; index++) BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <setup(debug_argc, debug_argv))*/ if (!this->setup(argc, argv)) @@ -2179,7 +2179,6 @@ int CLI::run(int argc, char **argv) if (export_to_3mf) { //BBS: export as bbl 3mf - Slic3r::GUI::OpenGLManager opengl_mgr; std::vector thumbnails, top_thumbnails, pick_thumbnails; std::vector plate_bboxes; PlateDataPtrs plate_data_list; @@ -2312,195 +2311,200 @@ int CLI::run(int argc, char **argv) else glfwMakeContextCurrent(window); } - bool opengl_valid = opengl_mgr.init_gl(); - if (!opengl_valid) { - BOOST_LOG_TRIVIAL(error) << "init opengl failed! skip thumbnail generating" << std::endl; - } - else { - BOOST_LOG_TRIVIAL(info) << "glewInit Sucess." << std::endl; - GLVolumeCollection glvolume_collection; - Model &model = m_models[0]; - int extruder_id = 1; - for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model.objects.size(); ++ obj_idx) { - const ModelObject &model_object = *model.objects[obj_idx]; - const ConfigOption* option = model_object.config.option("extruder"); - if (option) - extruder_id = (dynamic_cast(option))->getInt(); - for (int volume_idx = 0; volume_idx < (int)model_object.volumes.size(); ++ volume_idx) { - const ModelVolume &model_volume = *model_object.volumes[volume_idx]; - option = model_volume.config.option("extruder"); - if (option) extruder_id = (dynamic_cast(option))->getInt(); - //if (!model_volume.is_model_part()) - // continue; - for (int instance_idx = 0; instance_idx < (int)model_object.instances.size(); ++ instance_idx) { - const ModelInstance &model_instance = *model_object.instances[instance_idx]; - glvolume_collection.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, "volume", true, false, true); - //glvolume_collection.volumes.back()->geometry_id = key.geometry_id; - std::string color = filament_color?filament_color->get_at(extruder_id - 1):"#00FF00"; - unsigned char rgb_color[3] = {}; - Slic3r::GUI::BitmapCache::parse_color(color, rgb_color); - glvolume_collection.volumes.back()->set_render_color( float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, 1.f); - - std::array new_color; - new_color[0] = float(rgb_color[0]) / 255.f; - new_color[1] = float(rgb_color[1]) / 255.f; - new_color[2] = float(rgb_color[2]) / 255.f; - new_color[3] = 1.f; - glvolume_collection.volumes.back()->set_color(new_color); - glvolume_collection.volumes.back()->printable = model_instance.printable; - } - } - } - - ThumbnailsParams thumbnail_params; - GLShaderProgram* shader = opengl_mgr.get_shader("gouraud_light"); - if (!shader) { - BOOST_LOG_TRIVIAL(error) << boost::format("can not get shader for rendering thumbnail"); + //opengl manager related logic + { + Slic3r::GUI::OpenGLManager opengl_mgr; + bool opengl_valid = opengl_mgr.init_gl(); + if (!opengl_valid) { + BOOST_LOG_TRIVIAL(error) << "init opengl failed! skip thumbnail generating" << std::endl; } else { - for (int i = 0; i < partplate_list.get_plate_count(); i++) { - Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(i); - PlateData *plate_data = plate_data_list[i]; - if (plate_data->plate_thumbnail.is_valid()) { - if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { - BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, reset plate %2%'s thumbnail.")%__LINE__%(i+1); - plate_data->plate_thumbnail.reset(); - } - else - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has a valid thumbnail, width %2%, height %3%, directly using it")%(i+1) %plate_data->plate_thumbnail.width %plate_data->plate_thumbnail.height; - } - else if (!plate_data->thumbnail_file.empty() && (boost::filesystem::exists(plate_data->thumbnail_file))) - { - if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { - BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, clear plate %2%'s thumbnail file path to empty.")%__LINE__%(i+1); - plate_data->thumbnail_file.clear(); - } - else - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has a valid thumbnail %2% extracted from 3mf, directly using it")%(i+1) %plate_data->thumbnail_file; - } - else { - ThumbnailData* thumbnail_data = &plate_data->plate_thumbnail; + BOOST_LOG_TRIVIAL(info) << "glewInit Sucess." << std::endl; + GLVolumeCollection glvolume_collection; + Model &model = m_models[0]; + int extruder_id = 1; + for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model.objects.size(); ++ obj_idx) { + const ModelObject &model_object = *model.objects[obj_idx]; + const ConfigOption* option = model_object.config.option("extruder"); + if (option) + extruder_id = (dynamic_cast(option))->getInt(); + for (int volume_idx = 0; volume_idx < (int)model_object.volumes.size(); ++ volume_idx) { + const ModelVolume &model_volume = *model_object.volumes[volume_idx]; + option = model_volume.config.option("extruder"); + if (option) extruder_id = (dynamic_cast(option))->getInt(); + //if (!model_volume.is_model_part()) + // continue; + for (int instance_idx = 0; instance_idx < (int)model_object.instances.size(); ++ instance_idx) { + const ModelInstance &model_instance = *model_object.instances[instance_idx]; + glvolume_collection.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, "volume", true, false, true); + //glvolume_collection.volumes.back()->geometry_id = key.geometry_id; + std::string color = filament_color?filament_color->get_at(extruder_id - 1):"#00FF00"; - if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { - BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1); - } - else { - unsigned int thumbnail_width = 512, thumbnail_height = 512; - const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i}; + unsigned char rgb_color[3] = {}; + Slic3r::GUI::BitmapCache::parse_color(color, rgb_color); + glvolume_collection.volumes.back()->set_render_color( float(rgb_color[0]) / 255.f, float(rgb_color[1]) / 255.f, float(rgb_color[2]) / 255.f, 1.f); - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s thumbnail, need to regenerate")%(i+1); - switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type()) - { - case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb: - { - BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB"); - Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*thumbnail_data, - thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho); - break; - } - case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext: - { - BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT"); - Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*thumbnail_data, - thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho); - break; - } - default: - BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown"); - break; + std::array new_color; + new_color[0] = float(rgb_color[0]) / 255.f; + new_color[1] = float(rgb_color[1]) / 255.f; + new_color[2] = float(rgb_color[2]) / 255.f; + new_color[3] = 1.f; + glvolume_collection.volumes.back()->set_color(new_color); + glvolume_collection.volumes.back()->printable = model_instance.printable; + } + } + } + + ThumbnailsParams thumbnail_params; + GLShaderProgram* shader = opengl_mgr.get_shader("gouraud_light"); + if (!shader) { + BOOST_LOG_TRIVIAL(error) << boost::format("can not get shader for rendering thumbnail"); + } + else { + for (int i = 0; i < partplate_list.get_plate_count(); i++) { + Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(i); + PlateData *plate_data = plate_data_list[i]; + if (plate_data->plate_thumbnail.is_valid()) { + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, reset plate %2%'s thumbnail.")%__LINE__%(i+1); + plate_data->plate_thumbnail.reset(); } - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s thumbnail,finished rendering")%(i+1); + else + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has a valid thumbnail, width %2%, height %3%, directly using it")%(i+1) %plate_data->plate_thumbnail.width %plate_data->plate_thumbnail.height; } - } - if (need_create_thumbnail_group) { - thumbnails.push_back(&plate_data->plate_thumbnail); - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data into group")%(i+1); - } - - //top thumbnails - /*if (part_plate->top_thumbnail_data.is_valid() && part_plate->pick_thumbnail_data.is_valid()) { - if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { - BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, reset plate %2%'s top/pick thumbnail.")%__LINE__%(i+1); - part_plate->top_thumbnail_data.reset(); - part_plate->pick_thumbnail_data.reset(); - plate_data->top_file.clear(); - plate_data->pick_file.clear(); - } - else { - plate_data->top_file = "valid_top"; - plate_data->pick_file = "valid_pick"; - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has a valid top/pick thumbnail data, directly using it")%(i+1); - } - } - else*/ - if ((!plate_data->top_file.empty() && (boost::filesystem::exists(plate_data->top_file))) - &&(!plate_data->pick_file.empty() && (boost::filesystem::exists(plate_data->pick_file)))) - { - if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { - BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, clear plate %2%'s top/pick thumbnail file path to empty.")%__LINE__%(i+1); - plate_data->top_file.clear(); - plate_data->pick_file.clear(); - } - else - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has valid top/pick thumbnail extracted from 3mf, directly using it")%(i+1); - } - else{ - ThumbnailData* top_thumbnail = &part_plate->top_thumbnail_data; - ThumbnailData* picking_thumbnail = &part_plate->pick_thumbnail_data; - if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { - BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1); - part_plate->top_thumbnail_data.reset(); - part_plate->pick_thumbnail_data.reset(); - plate_data->top_file.clear(); - plate_data->pick_file.clear(); - } - else { - unsigned int thumbnail_width = 512, thumbnail_height = 512; - const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i }; - - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s top/pick thumbnail missed, need to regenerate")%(i+1); - - switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type()) - { - case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb: - { - BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB"); - Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*top_thumbnail, - thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, false); - Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*picking_thumbnail, - thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, true); - break; - } - case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext: - { - BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT"); - Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*top_thumbnail, - thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, false); - Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*picking_thumbnail, - thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, true); - break; - } - default: - BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown"); - break; + else if (!plate_data->thumbnail_file.empty() && (boost::filesystem::exists(plate_data->thumbnail_file))) + { + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, clear plate %2%'s thumbnail file path to empty.")%__LINE__%(i+1); + plate_data->thumbnail_file.clear(); } - plate_data->top_file = "valid_top"; - plate_data->pick_file = "valid_pick"; - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s top_thumbnail,finished rendering")%(i+1); + else + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has a valid thumbnail %2% extracted from 3mf, directly using it")%(i+1) %plate_data->thumbnail_file; } - } + else { + ThumbnailData* thumbnail_data = &plate_data->plate_thumbnail; - if (need_create_top_group) { - top_thumbnails.push_back(&part_plate->top_thumbnail_data); - pick_thumbnails.push_back(&part_plate->pick_thumbnail_data); - BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for top and pick into group")%(i+1); + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1); + } + else { + unsigned int thumbnail_width = 512, thumbnail_height = 512; + const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i}; + + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s thumbnail, need to regenerate")%(i+1); + switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type()) + { + case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb: + { + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB"); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*thumbnail_data, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho); + break; + } + case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext: + { + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT"); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*thumbnail_data, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho); + break; + } + default: + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown"); + break; + } + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s thumbnail,finished rendering")%(i+1); + } + } + if (need_create_thumbnail_group) { + thumbnails.push_back(&plate_data->plate_thumbnail); + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data into group")%(i+1); + } + + //top thumbnails + /*if (part_plate->top_thumbnail_data.is_valid() && part_plate->pick_thumbnail_data.is_valid()) { + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, reset plate %2%'s top/pick thumbnail.")%__LINE__%(i+1); + part_plate->top_thumbnail_data.reset(); + part_plate->pick_thumbnail_data.reset(); + plate_data->top_file.clear(); + plate_data->pick_file.clear(); + } + else { + plate_data->top_file = "valid_top"; + plate_data->pick_file = "valid_pick"; + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has a valid top/pick thumbnail data, directly using it")%(i+1); + } + } + else*/ + if ((!plate_data->top_file.empty() && (boost::filesystem::exists(plate_data->top_file))) + &&(!plate_data->pick_file.empty() && (boost::filesystem::exists(plate_data->pick_file)))) + { + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, clear plate %2%'s top/pick thumbnail file path to empty.")%__LINE__%(i+1); + plate_data->top_file.clear(); + plate_data->pick_file.clear(); + } + else + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1% has valid top/pick thumbnail extracted from 3mf, directly using it")%(i+1); + } + else{ + ThumbnailData* top_thumbnail = &part_plate->top_thumbnail_data; + ThumbnailData* picking_thumbnail = &part_plate->pick_thumbnail_data; + if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) { + BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1); + part_plate->top_thumbnail_data.reset(); + part_plate->pick_thumbnail_data.reset(); + plate_data->top_file.clear(); + plate_data->pick_file.clear(); + } + else { + unsigned int thumbnail_width = 512, thumbnail_height = 512; + const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i }; + + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s top/pick thumbnail missed, need to regenerate")%(i+1); + + switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type()) + { + case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb: + { + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB"); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*top_thumbnail, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, false); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*picking_thumbnail, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, true); + break; + } + case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext: + { + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT"); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*top_thumbnail, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, false); + Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*picking_thumbnail, + thumbnail_width, thumbnail_height, thumbnail_params, + partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, true); + break; + } + default: + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown"); + break; + } + plate_data->top_file = "valid_top"; + plate_data->pick_file = "valid_pick"; + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s top_thumbnail,finished rendering")%(i+1); + } + } + + if (need_create_top_group) { + top_thumbnails.push_back(&part_plate->top_thumbnail_data); + pick_thumbnails.push_back(&part_plate->pick_thumbnail_data); + BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for top and pick into group")%(i+1); + } } } } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 315965a65d..5a327ee3ba 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2261,7 +2261,11 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co #define JSON_SUPPORT_LAYERS "support_layers" #define JSON_TREE_SUPPORT_LAYERS "tree_support_layers" #define JSON_LAYER_REGIONS "layer_regions" +#define JSON_FIRSTLAYER_GROUPS "first_layer_groups" +#define JSON_FIRSTLAYER_GROUP_ID "group_id" +#define JSON_FIRSTLAYER_GROUP_VOLUME_IDS "volume_ids" +#define JSON_FIRSTLAYER_GROUP_SLICES "slices" #define JSON_LAYER_PRINT_Z "print_z" #define JSON_LAYER_SLICE_Z "slice_z" @@ -2587,6 +2591,24 @@ static void to_json(json& j, const LayerRegion& layer_region) { return; } +static void to_json(json& j, const groupedVolumeSlices& first_layer_group) { + json volumes_json = json::array(), slices_json = json::array(); + j[JSON_FIRSTLAYER_GROUP_ID] = first_layer_group.groupId; + + for (const ObjectID& obj_id : first_layer_group.volume_ids) + { + volumes_json.push_back(obj_id.id); + } + j[JSON_FIRSTLAYER_GROUP_VOLUME_IDS] = std::move(volumes_json); + + for (const ExPolygon& slice_expolygon : first_layer_group.slices) { + json slice_expolygon_json = slice_expolygon; + + slices_json.push_back(std::move(slice_expolygon_json)); + } + j[JSON_FIRSTLAYER_GROUP_SLICES] = std::move(slices_json); +} + //load apis from json static void from_json(const json& j, Points& p_s) { int array_size = j.size(); @@ -2933,6 +2955,29 @@ void extract_support_layer(const json& support_layer_json, SupportLayer& support return; } +static void from_json(const json& j, groupedVolumeSlices& firstlayer_group) +{ + firstlayer_group.groupId = j[JSON_FIRSTLAYER_GROUP_ID]; + + int volume_count = j[JSON_FIRSTLAYER_GROUP_VOLUME_IDS].size(); + for (int volume_index = 0; volume_index < volume_count; volume_index++) + { + ObjectID obj_id; + + obj_id.id = j[JSON_FIRSTLAYER_GROUP_VOLUME_IDS][volume_index]; + firstlayer_group.volume_ids.push_back(std::move(obj_id)); + } + + int slices_count = j[JSON_FIRSTLAYER_GROUP_SLICES].size(); + for (int slice_index = 0; slice_index < slices_count; slice_index++) + { + ExPolygon polygon; + + polygon = j[JSON_FIRSTLAYER_GROUP_SLICES][slice_index]; + firstlayer_group.slices.push_back(std::move(polygon)); + } +} + int Print::export_cached_data(const std::string& directory, bool with_space) { int ret = 0; @@ -2999,7 +3044,7 @@ int Print::export_cached_data(const std::string& directory, bool with_space) BOOST_LOG_TRIVIAL(info) << boost::format("begin to dump object %1%, identify_id %2% to %3%")%model_obj->name %identify_id %file_name; try { - json root_json, layers_json = json::array(), support_layers_json = json::array(); + json root_json, layers_json = json::array(), support_layers_json = json::array(), first_layer_groups = json::array(); root_json[JSON_OBJECT_NAME] = model_obj->name; root_json[JSON_IDENTIFY_ID] = identify_id; @@ -3108,6 +3153,35 @@ int Print::export_cached_data(const std::string& directory, bool with_space) } // for each layer*/ root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json); + const std::vector &first_layer_obj_groups = obj->firstLayerObjGroups(); + for (size_t s_group_index = 0; s_group_index < first_layer_obj_groups.size(); ++ s_group_index) { + groupedVolumeSlices group = first_layer_obj_groups[s_group_index]; + + //convert the id + for (ObjectID& obj_id : group.volume_ids) + { + const ModelVolume* currentModelVolumePtr = nullptr; + //BBS: support shared object logic + const PrintObject* shared_object = obj->get_shared_object(); + if (!shared_object) + shared_object = obj; + const ModelVolumePtrs& volumes_ptr = shared_object->model_object()->volumes; + size_t volume_count = volumes_ptr.size(); + for (size_t index = 0; index < volume_count; index ++) { + currentModelVolumePtr = volumes_ptr[index]; + if (currentModelVolumePtr->id() == obj_id) { + obj_id.id = index; + break; + } + } + } + + json first_layer_group_json; + + first_layer_group_json = group; + first_layer_groups.push_back(std::move(first_layer_group_json)); + } + root_json[JSON_FIRSTLAYER_GROUPS] = std::move(first_layer_groups); filename_vector.push_back(file_name); json_vector.push_back(std::move(root_json)); @@ -3239,12 +3313,14 @@ int Print::load_cached_data(const std::string& directory) std::string name = root_json.at(JSON_OBJECT_NAME); int identify_id = root_json.at(JSON_IDENTIFY_ID); - int layer_count = 0, support_layer_count = 0; + int layer_count = 0, support_layer_count = 0, firstlayer_group_count = 0; layer_count = root_json[JSON_LAYERS].size(); support_layer_count = root_json[JSON_SUPPORT_LAYERS].size(); + firstlayer_group_count = root_json[JSON_FIRSTLAYER_GROUPS].size(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<& firstlayer_objgroups = obj->firstLayerObjGroupsMod(); + for (int index = 0; index < firstlayer_group_count; index++) + { + json& firstlayer_group_json = root_json[JSON_FIRSTLAYER_GROUPS][index]; + groupedVolumeSlices firstlayer_group = firstlayer_group_json; + //convert the id + for (ObjectID& obj_id : firstlayer_group.volume_ids) + { + ModelVolume* currentModelVolumePtr = nullptr; + ModelVolumePtrs& volumes_ptr = obj->model_object()->volumes; + size_t volume_count = volumes_ptr.size(); + if (obj_id.id < volume_count) { + currentModelVolumePtr = volumes_ptr[obj_id.id]; + obj_id = currentModelVolumePtr->id(); + } + else { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< boost::format(": can not find volume_id %1% from object file %2% in firstlayer groups, volume_count %3%!") + %obj_id.id %object_filenames[obj_index].first %volume_count; + return CLI_IMPORT_CACHE_LOAD_FAILED; + } + } + firstlayer_objgroups.push_back(std::move(firstlayer_group)); + } + count ++; BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first; } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index e11662d9d6..0b737efb27 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -137,14 +137,12 @@ BedType PartPlate::get_bed_type(bool load_from_project) const { std::string bed_type_key = "curr_bed_type"; - // should be called in GUI context - assert(m_plater != nullptr); if (m_config.has(bed_type_key)) { BedType bed_type = m_config.opt_enum(bed_type_key); return bed_type; } - if (!load_from_project || !wxGetApp().preset_bundle) + if (!load_from_project || !m_plater || !wxGetApp().preset_bundle) return btDefault; DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config; @@ -226,9 +224,6 @@ PrintSequence PartPlate::get_print_seq() const { std::string print_seq_key = "print_sequence"; - // should be called in GUI context - assert(m_plater != nullptr); - if (m_config.has(print_seq_key)) { PrintSequence print_seq = m_config.opt_enum(print_seq_key); return print_seq;