ENH: CLI: add the cache logic of brim data
1. cache the first layer group cache data for brim 2. fix some crash under debug mode when app exits Change-Id: I81d716564af414353e9dfeed42e5f4eef08b2d6f (cherry picked from commit a6ecdaed6f63f1c5c41fd343f72165fe27fda9d3)
This commit is contained in:
parent
f3aa76e4c2
commit
b30644c84d
3 changed files with 294 additions and 194 deletions
|
@ -374,18 +374,18 @@ int CLI::run(int argc, char **argv)
|
||||||
/*BOOST_LOG_TRIVIAL(info) << "begin to setup params, argc=" << argc << std::endl;
|
/*BOOST_LOG_TRIVIAL(info) << "begin to setup params, argc=" << argc << std::endl;
|
||||||
for (int index=0; index < argc; index++)
|
for (int index=0; index < argc; index++)
|
||||||
BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <<std::endl;
|
BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <<std::endl;
|
||||||
int debug_argc = 6;
|
int debug_argc = 7;
|
||||||
char *debug_argv[] = {
|
char *debug_argv[] = {
|
||||||
"E:\work\projects\bambu_debug\bamboo_slicer\build_debug\src\Debug\bambu-studio.exe",
|
"E:\work\projects\bambu_debug\bamboo_slicer\build_debug\src\Debug\bambu-studio.exe",
|
||||||
"--uptodate",
|
//"--uptodate",
|
||||||
//"--load-settings",
|
//"--load-settings",
|
||||||
//"machine.json;process.json",
|
//"machine.json;process.json",
|
||||||
//"--load-filaments",
|
"--load-slicedata",
|
||||||
//"filament.json",
|
"cached_data",
|
||||||
"--export-3mf=output.3mf",
|
"--export-3mf=output.3mf",
|
||||||
"--slice",
|
"--slice",
|
||||||
"0",
|
"0",
|
||||||
"Cube2.3mf"
|
"Cube.3mf"
|
||||||
};
|
};
|
||||||
if (! this->setup(debug_argc, debug_argv))*/
|
if (! this->setup(debug_argc, debug_argv))*/
|
||||||
if (!this->setup(argc, argv))
|
if (!this->setup(argc, argv))
|
||||||
|
@ -2179,7 +2179,6 @@ int CLI::run(int argc, char **argv)
|
||||||
|
|
||||||
if (export_to_3mf) {
|
if (export_to_3mf) {
|
||||||
//BBS: export as bbl 3mf
|
//BBS: export as bbl 3mf
|
||||||
Slic3r::GUI::OpenGLManager opengl_mgr;
|
|
||||||
std::vector<ThumbnailData *> thumbnails, top_thumbnails, pick_thumbnails;
|
std::vector<ThumbnailData *> thumbnails, top_thumbnails, pick_thumbnails;
|
||||||
std::vector<PlateBBoxData*> plate_bboxes;
|
std::vector<PlateBBoxData*> plate_bboxes;
|
||||||
PlateDataPtrs plate_data_list;
|
PlateDataPtrs plate_data_list;
|
||||||
|
@ -2312,195 +2311,200 @@ int CLI::run(int argc, char **argv)
|
||||||
else
|
else
|
||||||
glfwMakeContextCurrent(window);
|
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<const ConfigOptionInt *>(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<const ConfigOptionInt *>(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] = {};
|
//opengl manager related logic
|
||||||
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);
|
Slic3r::GUI::OpenGLManager opengl_mgr;
|
||||||
|
bool opengl_valid = opengl_mgr.init_gl();
|
||||||
std::array<float, 4> new_color;
|
if (!opengl_valid) {
|
||||||
new_color[0] = float(rgb_color[0]) / 255.f;
|
BOOST_LOG_TRIVIAL(error) << "init opengl failed! skip thumbnail generating" << std::endl;
|
||||||
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 {
|
else {
|
||||||
for (int i = 0; i < partplate_list.get_plate_count(); i++) {
|
BOOST_LOG_TRIVIAL(info) << "glewInit Sucess." << std::endl;
|
||||||
Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(i);
|
GLVolumeCollection glvolume_collection;
|
||||||
PlateData *plate_data = plate_data_list[i];
|
Model &model = m_models[0];
|
||||||
if (plate_data->plate_thumbnail.is_valid()) {
|
int extruder_id = 1;
|
||||||
if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) {
|
for (unsigned int obj_idx = 0; obj_idx < (unsigned int)model.objects.size(); ++ obj_idx) {
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, reset plate %2%'s thumbnail.")%__LINE__%(i+1);
|
const ModelObject &model_object = *model.objects[obj_idx];
|
||||||
plate_data->plate_thumbnail.reset();
|
const ConfigOption* option = model_object.config.option("extruder");
|
||||||
}
|
if (option)
|
||||||
else
|
extruder_id = (dynamic_cast<const ConfigOptionInt *>(option))->getInt();
|
||||||
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;
|
for (int volume_idx = 0; volume_idx < (int)model_object.volumes.size(); ++ volume_idx) {
|
||||||
}
|
const ModelVolume &model_volume = *model_object.volumes[volume_idx];
|
||||||
else if (!plate_data->thumbnail_file.empty() && (boost::filesystem::exists(plate_data->thumbnail_file)))
|
option = model_volume.config.option("extruder");
|
||||||
{
|
if (option) extruder_id = (dynamic_cast<const ConfigOptionInt *>(option))->getInt();
|
||||||
if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) {
|
//if (!model_volume.is_model_part())
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, clear plate %2%'s thumbnail file path to empty.")%__LINE__%(i+1);
|
// continue;
|
||||||
plate_data->thumbnail_file.clear();
|
for (int instance_idx = 0; instance_idx < (int)model_object.instances.size(); ++ instance_idx) {
|
||||||
}
|
const ModelInstance &model_instance = *model_object.instances[instance_idx];
|
||||||
else
|
glvolume_collection.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, "volume", true, false, true);
|
||||||
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;
|
//glvolume_collection.volumes.back()->geometry_id = key.geometry_id;
|
||||||
}
|
std::string color = filament_color?filament_color->get_at(extruder_id - 1):"#00FF00";
|
||||||
else {
|
|
||||||
ThumbnailData* thumbnail_data = &plate_data->plate_thumbnail;
|
|
||||||
|
|
||||||
if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) {
|
unsigned char rgb_color[3] = {};
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1);
|
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);
|
||||||
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);
|
std::array<float, 4> new_color;
|
||||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
new_color[0] = float(rgb_color[0]) / 255.f;
|
||||||
{
|
new_color[1] = float(rgb_color[1]) / 255.f;
|
||||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
new_color[2] = float(rgb_color[2]) / 255.f;
|
||||||
{
|
new_color[3] = 1.f;
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB");
|
glvolume_collection.volumes.back()->set_color(new_color);
|
||||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*thumbnail_data,
|
glvolume_collection.volumes.back()->printable = model_instance.printable;
|
||||||
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:
|
ThumbnailsParams thumbnail_params;
|
||||||
{
|
GLShaderProgram* shader = opengl_mgr.get_shader("gouraud_light");
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT");
|
if (!shader) {
|
||||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*thumbnail_data,
|
BOOST_LOG_TRIVIAL(error) << boost::format("can not get shader for rendering thumbnail");
|
||||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
}
|
||||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
else {
|
||||||
break;
|
for (int i = 0; i < partplate_list.get_plate_count(); i++) {
|
||||||
}
|
Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(i);
|
||||||
default:
|
PlateData *plate_data = plate_data_list[i];
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown");
|
if (plate_data->plate_thumbnail.is_valid()) {
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
}
|
else if (!plate_data->thumbnail_file.empty() && (boost::filesystem::exists(plate_data->thumbnail_file)))
|
||||||
if (need_create_thumbnail_group) {
|
{
|
||||||
thumbnails.push_back(&plate_data->plate_thumbnail);
|
if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) {
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data into group")%(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();
|
||||||
|
|
||||||
//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";
|
else
|
||||||
plate_data->pick_file = "valid_pick";
|
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;
|
||||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s top_thumbnail,finished rendering")%(i+1);
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
ThumbnailData* thumbnail_data = &plate_data->plate_thumbnail;
|
||||||
|
|
||||||
if (need_create_top_group) {
|
if ((plate_to_slice != 0) && (plate_to_slice != (i + 1))) {
|
||||||
top_thumbnails.push_back(&part_plate->top_thumbnail_data);
|
BOOST_LOG_TRIVIAL(info) << boost::format("Line %1%: regenerate thumbnail, Skip plate %2%.")%__LINE__%(i+1);
|
||||||
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2261,7 +2261,11 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
|
||||||
#define JSON_SUPPORT_LAYERS "support_layers"
|
#define JSON_SUPPORT_LAYERS "support_layers"
|
||||||
#define JSON_TREE_SUPPORT_LAYERS "tree_support_layers"
|
#define JSON_TREE_SUPPORT_LAYERS "tree_support_layers"
|
||||||
#define JSON_LAYER_REGIONS "layer_regions"
|
#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_PRINT_Z "print_z"
|
||||||
#define JSON_LAYER_SLICE_Z "slice_z"
|
#define JSON_LAYER_SLICE_Z "slice_z"
|
||||||
|
@ -2587,6 +2591,24 @@ static void to_json(json& j, const LayerRegion& layer_region) {
|
||||||
return;
|
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
|
//load apis from json
|
||||||
static void from_json(const json& j, Points& p_s) {
|
static void from_json(const json& j, Points& p_s) {
|
||||||
int array_size = j.size();
|
int array_size = j.size();
|
||||||
|
@ -2933,6 +2955,29 @@ void extract_support_layer(const json& support_layer_json, SupportLayer& support
|
||||||
return;
|
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 Print::export_cached_data(const std::string& directory, bool with_space)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
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;
|
BOOST_LOG_TRIVIAL(info) << boost::format("begin to dump object %1%, identify_id %2% to %3%")%model_obj->name %identify_id %file_name;
|
||||||
|
|
||||||
try {
|
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_OBJECT_NAME] = model_obj->name;
|
||||||
root_json[JSON_IDENTIFY_ID] = identify_id;
|
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*/
|
} // for each layer*/
|
||||||
root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json);
|
root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json);
|
||||||
|
|
||||||
|
const std::vector<groupedVolumeSlices> &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);
|
filename_vector.push_back(file_name);
|
||||||
json_vector.push_back(std::move(root_json));
|
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);
|
std::string name = root_json.at(JSON_OBJECT_NAME);
|
||||||
int identify_id = root_json.at(JSON_IDENTIFY_ID);
|
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();
|
layer_count = root_json[JSON_LAYERS].size();
|
||||||
support_layer_count = root_json[JSON_SUPPORT_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__<<boost::format(":will load %1%, identify_id %2%, layer_count %3%, support_layer_count %4%")%name %identify_id %layer_count %support_layer_count;
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<<boost::format(":will load %1%, identify_id %2%, layer_count %3%, support_layer_count %4%, firstlayer_group_count %5%")
|
||||||
|
%name %identify_id %layer_count %support_layer_count %firstlayer_group_count;
|
||||||
|
|
||||||
Layer* previous_layer = NULL;
|
Layer* previous_layer = NULL;
|
||||||
//create layer and layer regions
|
//create layer and layer regions
|
||||||
|
@ -3325,6 +3401,31 @@ int Print::load_cached_data(const std::string& directory)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//load first group volumes
|
||||||
|
std::vector<groupedVolumeSlices>& 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 ++;
|
count ++;
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first;
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,14 +137,12 @@ BedType PartPlate::get_bed_type(bool load_from_project) const
|
||||||
{
|
{
|
||||||
std::string bed_type_key = "curr_bed_type";
|
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)) {
|
if (m_config.has(bed_type_key)) {
|
||||||
BedType bed_type = m_config.opt_enum<BedType>(bed_type_key);
|
BedType bed_type = m_config.opt_enum<BedType>(bed_type_key);
|
||||||
return bed_type;
|
return bed_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!load_from_project || !wxGetApp().preset_bundle)
|
if (!load_from_project || !m_plater || !wxGetApp().preset_bundle)
|
||||||
return btDefault;
|
return btDefault;
|
||||||
|
|
||||||
DynamicConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
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";
|
std::string print_seq_key = "print_sequence";
|
||||||
|
|
||||||
// should be called in GUI context
|
|
||||||
assert(m_plater != nullptr);
|
|
||||||
|
|
||||||
if (m_config.has(print_seq_key)) {
|
if (m_config.has(print_seq_key)) {
|
||||||
PrintSequence print_seq = m_config.opt_enum<PrintSequence>(print_seq_key);
|
PrintSequence print_seq = m_config.opt_enum<PrintSequence>(print_seq_key);
|
||||||
return print_seq;
|
return print_seq;
|
||||||
|
|
Loading…
Reference in a new issue