mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-19 23:01:22 -06:00
ENH: thumbnail: add top_view thumbnails and picking thumbnails
1. add top view thumbnail for each plate 2. add picking thumbnails for each plate 3. save model object id for picking Change-Id: I1d7f6ade22726ff12c282cb12e4a78e6b444a070
This commit is contained in:
parent
9f3a89320b
commit
c65a5f8bf5
15 changed files with 716 additions and 195 deletions
|
@ -1044,7 +1044,8 @@ int GLVolumeCollection::load_object_volume(
|
|||
int instance_idx,
|
||||
const std::string &color_by,
|
||||
bool opengl_initialized,
|
||||
bool in_assemble_view)
|
||||
bool in_assemble_view,
|
||||
bool use_loaded_id)
|
||||
{
|
||||
const ModelVolume *model_volume = model_object->volumes[volume_idx];
|
||||
const int extruder_id = model_volume->extruder_id();
|
||||
|
@ -1079,6 +1080,11 @@ int GLVolumeCollection::load_object_volume(
|
|||
else
|
||||
v.set_instance_transformation(instance->get_transformation());
|
||||
v.set_volume_transformation(model_volume->get_transformation());
|
||||
//use object's instance id
|
||||
if (use_loaded_id && (instance->loaded_id > 0))
|
||||
v.model_object_ID = instance->loaded_id;
|
||||
else
|
||||
v.model_object_ID = instance->id().id;
|
||||
|
||||
return int(this->volumes.size() - 1);
|
||||
}
|
||||
|
|
|
@ -357,6 +357,8 @@ public:
|
|||
// An ID containing the extruder ID (used to select color).
|
||||
int extruder_id;
|
||||
|
||||
size_t model_object_ID{0};
|
||||
|
||||
// Various boolean flags.
|
||||
struct {
|
||||
// Is this object selected?
|
||||
|
@ -634,7 +636,8 @@ public:
|
|||
int instance_idx,
|
||||
const std::string &color_by,
|
||||
bool opengl_initialized,
|
||||
bool in_assemble_view = false);
|
||||
bool in_assemble_view = false,
|
||||
bool use_loaded_id = false);
|
||||
|
||||
// Load SLA auxiliary GLVolumes (for support trees or pad).
|
||||
void load_object_auxiliary(
|
||||
|
|
|
@ -1971,12 +1971,13 @@ void GLCanvas3D::render(bool only_init)
|
|||
m_render_stats.increment_fps_counter();
|
||||
}
|
||||
|
||||
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type)
|
||||
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
render_thumbnail(thumbnail_data, w, h, thumbnail_params, m_volumes, camera_type);
|
||||
render_thumbnail(thumbnail_data, w, h, thumbnail_params, m_volumes, camera_type, use_top_view, for_picking);
|
||||
}
|
||||
|
||||
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, const GLVolumeCollection& volumes, Camera::EType camera_type)
|
||||
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects;
|
||||
|
@ -1985,10 +1986,10 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w,
|
|||
{
|
||||
case OpenGLManager::EFramebufferType::Arb:
|
||||
{ render_thumbnail_framebuffer(thumbnail_data, w, h, thumbnail_params,
|
||||
wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type); break; }
|
||||
wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, use_top_view, for_picking); break; }
|
||||
case OpenGLManager::EFramebufferType::Ext:
|
||||
{ render_thumbnail_framebuffer_ext(thumbnail_data, w, h, thumbnail_params,
|
||||
wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type); break; }
|
||||
wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, use_top_view, for_picking); break; }
|
||||
default:
|
||||
{ render_thumbnail_legacy(thumbnail_data, w, h, thumbnail_params,
|
||||
wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type); break; }
|
||||
|
@ -5375,7 +5376,9 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data)
|
|||
}
|
||||
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
|
||||
|
||||
void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type)
|
||||
void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params,
|
||||
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
|
||||
GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
//BBS modify visible calc function
|
||||
int plate_idx = thumbnail_params.plate_id;
|
||||
|
@ -5418,7 +5421,7 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail: plate_idx %1% volumes size %2%, shader %3%") % plate_idx % visible_volumes.size() %shader;
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail: plate_idx %1% volumes size %2%, shader %3%, use_top_view=%4%, for_picking=%5%") % plate_idx % visible_volumes.size() %shader %use_top_view %for_picking;
|
||||
//BoundingBoxf3 volumes_box = plate_build_volume;
|
||||
BoundingBoxf3 volumes_box;
|
||||
volumes_box.min.z() = 0;
|
||||
|
@ -5448,11 +5451,29 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
//BoundingBoxf3 plate_box = plate->get_bounding_box(false);
|
||||
//plate_box.min.z() = 0.0;
|
||||
//plate_box.max.z() = 0.0;
|
||||
camera.zoom_to_box(volumes_box);
|
||||
const Vec3d& target = camera.get_target();
|
||||
double distance = camera.get_distance();
|
||||
//camera.select_view("topfront");
|
||||
camera.look_at(target - 0.707 * distance * Vec3d::UnitY() + 0.3 * distance * Vec3d::UnitZ(), target, Vec3d::UnitY() + Vec3d::UnitZ());
|
||||
|
||||
if (use_top_view) {
|
||||
float center_x = (plate_build_volume.max(0) + plate_build_volume.min(0))/2;
|
||||
float center_y = (plate_build_volume.max(1) + plate_build_volume.min(1))/2;
|
||||
float distance_z = plate_build_volume.max(2) - plate_build_volume.min(2);
|
||||
Vec3d center(center_x, center_y, 0.f);
|
||||
double zoom_ratio, scale_x, scale_y;
|
||||
|
||||
scale_x = ((double)thumbnail_data.width)/(plate_build_volume.max(0) - plate_build_volume.min(0));
|
||||
scale_y = ((double)thumbnail_data.height)/(plate_build_volume.max(1) - plate_build_volume.min(1));
|
||||
zoom_ratio = (scale_x <= scale_y)?scale_x:scale_y;
|
||||
camera.look_at(center + distance_z * Vec3d::UnitZ(), center, Vec3d::UnitY());
|
||||
camera.set_zoom(zoom_ratio);
|
||||
//camera.select_view("top");
|
||||
}
|
||||
else {
|
||||
camera.zoom_to_box(volumes_box);
|
||||
|
||||
const Vec3d& target = camera.get_target();
|
||||
double distance = camera.get_distance();
|
||||
camera.look_at(target - 0.707 * distance * Vec3d::UnitY() + 0.3 * distance * Vec3d::UnitZ(), target, Vec3d::UnitY() + Vec3d::UnitZ());
|
||||
}
|
||||
|
||||
camera.apply_view_matrix();
|
||||
|
||||
camera.apply_projection(plate_build_volume);
|
||||
|
@ -5462,44 +5483,94 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
//camera.apply_projection(volumes_box, near_z, far_z);
|
||||
|
||||
//GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail: shader is null, return directly");
|
||||
if (!for_picking && (shader == nullptr)) {
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail with no picking: shader is null, return directly");
|
||||
return;
|
||||
}
|
||||
|
||||
//if (thumbnail_params.transparent_background)
|
||||
glsafe(::glClearColor(0.906f, 0.906f, 0.906f, 1.0f));
|
||||
if (for_picking)
|
||||
glsafe(::glClearColor(0.f, 0.f, 0.f, 0.f));
|
||||
else
|
||||
glsafe(::glClearColor(0.906f, 0.906f, 0.906f, 1.0f));
|
||||
|
||||
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
if (for_picking) {
|
||||
//if (OpenGLManager::can_multisample())
|
||||
// This flag is often ignored by NVIDIA drivers if rendering into a screen buffer.
|
||||
// glsafe(::glDisable(GL_MULTISAMPLE));
|
||||
|
||||
for (GLVolume* vol : visible_volumes) {
|
||||
//BBS set render color for thumbnails
|
||||
curr_color[0] = vol->color[0];
|
||||
curr_color[1] = vol->color[1];
|
||||
curr_color[2] = vol->color[2];
|
||||
curr_color[3] = vol->color[3];
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
|
||||
shader->set_uniform("uniform_color", curr_color);
|
||||
//BBS set all volume to orange
|
||||
//shader->set_uniform("uniform_color", orange);
|
||||
/*if (plate_idx > 0) {
|
||||
shader->set_uniform("uniform_color", orange);
|
||||
static const GLfloat INV_255 = 1.0f / 255.0f;
|
||||
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
|
||||
//glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
//glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
for (GLVolume* vol : visible_volumes) {
|
||||
// Object picking mode. Render the object with a color encoding the object index.
|
||||
// we reserve color = (0,0,0) for occluders (as the printbed)
|
||||
// so we shift volumes' id by 1 to get the proper color
|
||||
//BBS: remove the bed picking logic
|
||||
unsigned int id = vol->model_object_ID;
|
||||
//unsigned int id = 1 + volume.second.first;
|
||||
unsigned int r = (id & (0x000000FF << 0)) >> 0;
|
||||
unsigned int g = (id & (0x000000FF << 8)) >> 8;
|
||||
unsigned int b = (id & (0x000000FF << 16)) >> 16;
|
||||
unsigned int a = 0xFF;
|
||||
glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255));
|
||||
/*curr_color[0] = (GLfloat)r * INV_255;
|
||||
curr_color[1] = (GLfloat)g * INV_255;
|
||||
curr_color[2] = (GLfloat)b * INV_255;
|
||||
curr_color[3] = (GLfloat)a * INV_255;
|
||||
shader->set_uniform("uniform_color", curr_color);*/
|
||||
|
||||
bool is_active = vol->is_active;
|
||||
vol->is_active = true;
|
||||
vol->simple_render(nullptr, model_objects, extruder_colors);
|
||||
vol->is_active = is_active;
|
||||
}
|
||||
else {
|
||||
shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray);
|
||||
}*/
|
||||
// the volume may have been deactivated by an active gizmo
|
||||
bool is_active = vol->is_active;
|
||||
vol->is_active = true;
|
||||
vol->simple_render(shader, model_objects, extruder_colors);
|
||||
vol->is_active = is_active;
|
||||
}
|
||||
|
||||
shader->stop_using();
|
||||
//glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
//glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
|
||||
//if (OpenGLManager::can_multisample())
|
||||
// glsafe(::glEnable(GL_MULTISAMPLE));
|
||||
}
|
||||
else {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.0f);
|
||||
for (GLVolume* vol : visible_volumes) {
|
||||
//BBS set render color for thumbnails
|
||||
curr_color[0] = vol->color[0];
|
||||
curr_color[1] = vol->color[1];
|
||||
curr_color[2] = vol->color[2];
|
||||
curr_color[3] = vol->color[3];
|
||||
|
||||
shader->set_uniform("uniform_color", curr_color);
|
||||
//BBS set all volume to orange
|
||||
//shader->set_uniform("uniform_color", orange);
|
||||
/*if (plate_idx > 0) {
|
||||
shader->set_uniform("uniform_color", orange);
|
||||
}
|
||||
else {
|
||||
shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? orange : gray);
|
||||
}*/
|
||||
// the volume may have been deactivated by an active gizmo
|
||||
bool is_active = vol->is_active;
|
||||
vol->is_active = true;
|
||||
vol->simple_render(shader, model_objects, extruder_colors);
|
||||
vol->is_active = is_active;
|
||||
}
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
|
@ -5512,7 +5583,9 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
|||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail: finished");
|
||||
}
|
||||
|
||||
void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type)
|
||||
void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
|
||||
GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
thumbnail_data.set(w, h);
|
||||
if (!thumbnail_data.is_valid())
|
||||
|
@ -5563,7 +5636,7 @@ void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, uns
|
|||
glsafe(::glDrawBuffers(1, drawBufs));
|
||||
|
||||
if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
|
||||
render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type);
|
||||
render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, use_top_view, for_picking);
|
||||
|
||||
if (multisample) {
|
||||
GLuint resolve_fbo;
|
||||
|
@ -5616,7 +5689,9 @@ void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, uns
|
|||
BOOST_LOG_TRIVIAL(info) << boost::format("render_thumbnail prepare: finished");
|
||||
}
|
||||
|
||||
void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type)
|
||||
void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
|
||||
GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
thumbnail_data.set(w, h);
|
||||
if (!thumbnail_data.is_valid())
|
||||
|
@ -5666,7 +5741,7 @@ void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data,
|
|||
glsafe(::glDrawBuffers(1, drawBufs));
|
||||
|
||||
if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type);
|
||||
render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, use_top_view, for_picking);
|
||||
|
||||
if (multisample) {
|
||||
GLuint resolve_fbo;
|
||||
|
@ -7339,7 +7414,7 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar()
|
|||
if (item->selected) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, button_active);
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_active);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(128.0f, 128.0f, 128.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.42f, 0.42f, 0.42f, 1.0f));
|
||||
|
@ -7615,7 +7690,7 @@ void GLCanvas3D::_render_paint_toolbar() const
|
|||
Slic3r::GUI::BitmapCache::parse_color(colors[i], rgb);
|
||||
float gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
|
||||
ImVec4 text_color = gray < 80 ? ImVec4(255, 255, 255, 255) : ImVec4(0, 0, 0, 255);
|
||||
|
||||
|
||||
ImVec2 number_label_size = ImGui::CalcTextSize(std::to_string(i + 1).c_str());
|
||||
ImGui::SetCursorPosY(cursor_y + text_offset_y);
|
||||
ImGui::SetCursorPosX(item_spacing + i * (item_spacing + button_size) + (button_size - number_label_size.x) / 2);
|
||||
|
|
|
@ -832,13 +832,21 @@ public:
|
|||
|
||||
// printable_only == false -> render also non printable volumes as grayed
|
||||
// parts_only == false -> render also sla support and pad
|
||||
void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type);
|
||||
void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, const GLVolumeCollection& volumes, Camera::EType camera_type);
|
||||
static void render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type);
|
||||
void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
Camera::EType camera_type, bool use_top_view = false, bool for_picking = false);
|
||||
void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
const GLVolumeCollection& volumes, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false);
|
||||
static void render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects,
|
||||
const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
|
||||
GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false);
|
||||
// render thumbnail using an off-screen framebuffer
|
||||
static void render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type);
|
||||
static void render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
|
||||
GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false);
|
||||
// render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported
|
||||
static void render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type);
|
||||
static void render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector<std::array<float, 4>>& extruder_colors,
|
||||
GLShaderProgram* shader, Camera::EType camera_type, bool use_top_view = false, bool for_picking = false);
|
||||
|
||||
//BBS use gcoder viewer render calibration thumbnails
|
||||
void render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params);
|
||||
|
|
|
@ -2348,7 +2348,7 @@ int PartPlate::load_gcode_from_file(const std::string& filename)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int PartPlate::load_thumbnail_data(std::string filename)
|
||||
int PartPlate::load_thumbnail_data(std::string filename, ThumbnailData& thumb_data)
|
||||
{
|
||||
bool result = true;
|
||||
wxImage img;
|
||||
|
@ -2357,11 +2357,11 @@ int PartPlate::load_thumbnail_data(std::string filename)
|
|||
img = img.Mirror(false);
|
||||
}
|
||||
if (result) {
|
||||
thumbnail_data.set(img.GetWidth(), img.GetHeight());
|
||||
thumb_data.set(img.GetWidth(), img.GetHeight());
|
||||
for (int i = 0; i < img.GetWidth() * img.GetHeight(); i++) {
|
||||
memcpy(&thumbnail_data.pixels[4 * i], (unsigned char*)(img.GetData() + 3 * i), 3);
|
||||
memcpy(&thumb_data.pixels[4 * i], (unsigned char*)(img.GetData() + 3 * i), 3);
|
||||
if (img.HasAlpha()) {
|
||||
thumbnail_data.pixels[4 * i + 3] = *(unsigned char*)(img.GetAlpha() + i);
|
||||
thumb_data.pixels[4 * i + 3] = *(unsigned char*)(img.GetAlpha() + i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2372,7 +2372,7 @@ int PartPlate::load_thumbnail_data(std::string filename)
|
|||
|
||||
int PartPlate::load_pattern_thumbnail_data(std::string filename)
|
||||
{
|
||||
bool result = true;
|
||||
/*bool result = true;
|
||||
wxImage img;
|
||||
result = load_image(filename, img);
|
||||
if (result) {
|
||||
|
@ -2386,7 +2386,7 @@ int PartPlate::load_pattern_thumbnail_data(std::string filename)
|
|||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3428,6 +3428,8 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id)
|
|||
PartPlate* plate = m_plate_list[obj_id - 1000];
|
||||
plate->update_slice_result_valid_state( false );
|
||||
plate->thumbnail_data.reset();
|
||||
plate->top_thumbnail_data.reset();
|
||||
plate->pick_thumbnail_data.reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3456,10 +3458,14 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id)
|
|||
plate->update_states();
|
||||
plate->update_slice_result_valid_state();
|
||||
plate->thumbnail_data.reset();
|
||||
plate->top_thumbnail_data.reset();
|
||||
plate->pick_thumbnail_data.reset();
|
||||
return 0;
|
||||
}
|
||||
plate->update_slice_result_valid_state();
|
||||
plate->thumbnail_data.reset();
|
||||
plate->top_thumbnail_data.reset();
|
||||
plate->pick_thumbnail_data.reset();
|
||||
}
|
||||
else if (unprintable_plate.contain_instance(obj_id, instance_id))
|
||||
{
|
||||
|
@ -3490,6 +3496,8 @@ int PartPlateList::notify_instance_update(int obj_id, int instance_id)
|
|||
plate->add_instance(obj_id, instance_id, false, &boundingbox);
|
||||
plate->update_slice_result_valid_state();
|
||||
plate->thumbnail_data.reset();
|
||||
plate->top_thumbnail_data.reset();
|
||||
plate->pick_thumbnail_data.reset();
|
||||
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": add it to new plate %1%") % i;
|
||||
return 0;
|
||||
}
|
||||
|
@ -3525,6 +3533,8 @@ int PartPlateList::notify_instance_removed(int obj_id, int instance_id)
|
|||
plate->remove_instance(obj_id, instance_to_delete);
|
||||
plate->update_slice_result_valid_state();
|
||||
plate->thumbnail_data.reset();
|
||||
plate->top_thumbnail_data.reset();
|
||||
plate->pick_thumbnail_data.reset();
|
||||
}
|
||||
|
||||
if (unprintable_plate.contain_instance(obj_id, instance_to_delete))
|
||||
|
@ -4416,6 +4426,11 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w
|
|||
%(i+1) %plate_data_item->plate_thumbnail.width %plate_data_item->plate_thumbnail.height %plate_data_item->plate_thumbnail.pixels.size();
|
||||
plate_data_item->config.apply(*m_plate_list[i]->config());
|
||||
|
||||
if (m_plate_list[i]->top_thumbnail_data.is_valid())
|
||||
plate_data_item->top_file = "valid_top";
|
||||
if (m_plate_list[i]->pick_thumbnail_data.is_valid())
|
||||
plate_data_item->pick_file = "valid_pick";
|
||||
|
||||
if (m_plate_list[i]->obj_to_instance_set.size() > 0)
|
||||
{
|
||||
for (std::set<std::pair<int, int>>::iterator it = m_plate_list[i]->obj_to_instance_set.begin(); it != m_plate_list[i]->obj_to_instance_set.end(); ++it)
|
||||
|
@ -4430,8 +4445,8 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w
|
|||
// BBS only include current palte_idx
|
||||
if (plate_idx == i || plate_idx == PLATE_CURRENT_IDX || plate_idx == PLATE_ALL_IDX) {
|
||||
//load calibration thumbnail
|
||||
if (m_plate_list[i]->cali_thumbnail_data.is_valid())
|
||||
plate_data_item->pattern_file = "valid_pattern";
|
||||
//if (m_plate_list[i]->cali_thumbnail_data.is_valid())
|
||||
// plate_data_item->pattern_file = "valid_pattern";
|
||||
if (m_plate_list[i]->cali_bboxes_data.is_valid())
|
||||
plate_data_item->pattern_bbox_file = "valid_pattern_bbox";
|
||||
plate_data_item->gcode_file = m_plate_list[i]->m_gcode_result->filename;
|
||||
|
@ -4513,17 +4528,29 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list)
|
|||
if (m_plater && !plate_data_list[i]->thumbnail_file.empty()) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1%, load thumbnail from %2%.")%(i+1) %plate_data_list[i]->thumbnail_file;
|
||||
if (boost::filesystem::exists(plate_data_list[i]->thumbnail_file)) {
|
||||
m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->thumbnail_file);
|
||||
m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->thumbnail_file, m_plate_list[index]->thumbnail_data);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ <<boost::format(": plate %1% after load, width %2%, height %3%, size %4%!")
|
||||
%(i+1) %m_plate_list[index]->thumbnail_data.width %m_plate_list[index]->thumbnail_data.height %m_plate_list[index]->thumbnail_data.pixels.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_plater && !plate_data_list[i]->pattern_file.empty()) {
|
||||
/*if (m_plater && !plate_data_list[i]->pattern_file.empty()) {
|
||||
if (boost::filesystem::exists(plate_data_list[i]->pattern_file)) {
|
||||
//no need to load pattern data currently
|
||||
//m_plate_list[index]->load_pattern_thumbnail_data(plate_data_list[i]->pattern_file);
|
||||
}
|
||||
}*/
|
||||
if (m_plater && !plate_data_list[i]->top_file.empty()) {
|
||||
if (boost::filesystem::exists(plate_data_list[i]->top_file)) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1%, load top_thumbnail from %2%.")%(i+1) %plate_data_list[i]->top_file;
|
||||
m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->top_file, m_plate_list[index]->top_thumbnail_data);
|
||||
}
|
||||
}
|
||||
if (m_plater && !plate_data_list[i]->pick_file.empty()) {
|
||||
if (boost::filesystem::exists(plate_data_list[i]->pick_file)) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1%, load pick_thumbnail from %2%.")%(i+1) %plate_data_list[i]->pick_file;
|
||||
m_plate_list[index]->load_thumbnail_data(plate_data_list[i]->pick_file, m_plate_list[index]->pick_thumbnail_data);
|
||||
}
|
||||
}
|
||||
if (m_plater && !plate_data_list[i]->pattern_bbox_file.empty()) {
|
||||
if (boost::filesystem::exists(plate_data_list[i]->pattern_bbox_file)) {
|
||||
|
|
|
@ -231,10 +231,13 @@ public:
|
|||
static const int plate_thumbnail_width = 512;
|
||||
static const int plate_thumbnail_height = 512;
|
||||
|
||||
ThumbnailData cali_thumbnail_data;
|
||||
ThumbnailData top_thumbnail_data;
|
||||
ThumbnailData pick_thumbnail_data;
|
||||
|
||||
//ThumbnailData cali_thumbnail_data;
|
||||
PlateBBoxData cali_bboxes_data;
|
||||
static const int cali_thumbnail_width = 2560;
|
||||
static const int cali_thumbnail_height = 2560;
|
||||
//static const int cali_thumbnail_width = 2560;
|
||||
//static const int cali_thumbnail_height = 2560;
|
||||
|
||||
//set the plate's index
|
||||
void set_index(int index);
|
||||
|
@ -410,7 +413,7 @@ public:
|
|||
//load gcode from file
|
||||
int load_gcode_from_file(const std::string& filename);
|
||||
//load thumbnail data from file
|
||||
int load_thumbnail_data(std::string filename);
|
||||
int load_thumbnail_data(std::string filename, ThumbnailData& thumb_data);
|
||||
//load pattern thumbnail data from file
|
||||
int load_pattern_thumbnail_data(std::string filename);
|
||||
//load pattern box data from file
|
||||
|
|
|
@ -2109,7 +2109,8 @@ struct Plater::priv
|
|||
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
||||
|
||||
//BBS: add plate_id for thumbnail
|
||||
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type);
|
||||
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
Camera::EType camera_type, bool use_top_view = false, bool for_picking = false);
|
||||
ThumbnailsList generate_thumbnails(const ThumbnailsParams& params, Camera::EType camera_type);
|
||||
//BBS
|
||||
void generate_calibration_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params);
|
||||
|
@ -6440,9 +6441,10 @@ void Plater::priv::on_3dcanvas_mouse_dragging_finished(SimpleEvent&)
|
|||
}
|
||||
|
||||
//BBS: add plate id for thumbnail generate param
|
||||
void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type)
|
||||
void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params,
|
||||
Camera::EType camera_type, bool use_top_view, bool for_picking)
|
||||
{
|
||||
view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type);
|
||||
view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type, use_top_view, for_picking);
|
||||
}
|
||||
|
||||
//BBS: add plate id for thumbnail generate param
|
||||
|
@ -9523,6 +9525,7 @@ void Plater::export_stl(bool extended, bool selection_only)
|
|||
// BBS: backup
|
||||
int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy strategy, int export_plate_idx, Export3mfProgressFn proFn)
|
||||
{
|
||||
int ret = 0;
|
||||
//if (p->model.objects.empty()) {
|
||||
// MessageDialog dialog(nullptr, _L("No objects to export."), _L("Save project"), wxYES);
|
||||
// if (dialog.ShowModal() == wxYES)
|
||||
|
@ -9548,6 +9551,8 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
|
|||
//BBS: add plate logic for thumbnail generate
|
||||
std::vector<ThumbnailData*> thumbnails;
|
||||
std::vector<ThumbnailData*> calibration_thumbnails;
|
||||
std::vector<ThumbnailData*> top_thumbnails;
|
||||
std::vector<ThumbnailData*> picking_thumbnails;
|
||||
std::vector<PlateBBoxData*> plate_bboxes;
|
||||
// BBS: backup
|
||||
if (!(strategy & SaveStrategy::Backup)) {
|
||||
|
@ -9560,22 +9565,50 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
|
|||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate thumbnail for plate %1%") % i;
|
||||
const ThumbnailsParams thumbnail_params = { {}, false, true, true, true, i };
|
||||
p->generate_thumbnail(p->partplate_list.get_plate(i)->thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, Camera::EType::Ortho);
|
||||
p->generate_thumbnail(p->partplate_list.get_plate(i)->thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second,
|
||||
thumbnail_params, Camera::EType::Ortho);
|
||||
}
|
||||
thumbnails.push_back(thumbnail_data);
|
||||
|
||||
ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data;
|
||||
calibration_thumbnails.push_back(calibration_data);
|
||||
//ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data;
|
||||
//calibration_thumbnails.push_back(calibration_data);
|
||||
PlateBBoxData* plate_bbox_data = &p->partplate_list.get_plate(i)->cali_bboxes_data;
|
||||
plate_bboxes.push_back(plate_bbox_data);
|
||||
|
||||
//generate top and picking thumbnails
|
||||
ThumbnailData* top_thumbnail = &p->partplate_list.get_plate(i)->top_thumbnail_data;
|
||||
if (top_thumbnail->is_valid() && using_exported_file()) {
|
||||
//no need to generate thumbnail
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate top_thumbnail for gcode/exported mode of plate %1%")%i;
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate top_thumbnail for plate %1%") % i;
|
||||
const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i };
|
||||
p->generate_thumbnail(p->partplate_list.get_plate(i)->top_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second,
|
||||
thumbnail_params, Camera::EType::Ortho, true, false);
|
||||
}
|
||||
top_thumbnails.push_back(top_thumbnail);
|
||||
|
||||
ThumbnailData* picking_thumbnail = &p->partplate_list.get_plate(i)->pick_thumbnail_data;
|
||||
if (picking_thumbnail->is_valid() && using_exported_file()) {
|
||||
//no need to generate thumbnail
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": non need to re-generate pick_thumbnail for gcode/exported mode of plate %1%")%i;
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": re-generate pick_thumbnail for plate %1%") % i;
|
||||
const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i };
|
||||
p->generate_thumbnail(p->partplate_list.get_plate(i)->pick_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second,
|
||||
thumbnail_params, Camera::EType::Ortho, true, true);
|
||||
}
|
||||
picking_thumbnails.push_back(picking_thumbnail);
|
||||
}
|
||||
|
||||
if (p->partplate_list.get_curr_plate()->is_slice_result_valid()) {
|
||||
//BBS generate BBS calibration thumbnails
|
||||
int index = p->partplate_list.get_curr_plate_index();
|
||||
ThumbnailData* calibration_data = calibration_thumbnails[index];
|
||||
const ThumbnailsParams calibration_params = { {}, false, true, true, true, p->partplate_list.get_curr_plate_index() };
|
||||
p->generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params);
|
||||
//ThumbnailData* calibration_data = calibration_thumbnails[index];
|
||||
//const ThumbnailsParams calibration_params = { {}, false, true, true, true, p->partplate_list.get_curr_plate_index() };
|
||||
//p->generate_calibration_thumbnail(*calibration_data, PartPlate::cali_thumbnail_width, PartPlate::cali_thumbnail_height, calibration_params);
|
||||
if (using_exported_file()) {
|
||||
//do nothing
|
||||
}
|
||||
|
@ -9600,6 +9633,8 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
|
|||
store_params.project_presets = project_presets;
|
||||
store_params.config = export_config ? &cfg : nullptr;
|
||||
store_params.thumbnail_data = thumbnails;
|
||||
store_params.top_thumbnail_data = top_thumbnails;
|
||||
store_params.pick_thumbnail_data = picking_thumbnails;
|
||||
store_params.calibration_thumbnail_data = calibration_thumbnails;
|
||||
store_params.proFn = proFn;
|
||||
store_params.id_bboxes = plate_bboxes;//BBS
|
||||
|
@ -9661,7 +9696,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
|
|||
}
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (project_presets.size() > 0)
|
||||
|
@ -9680,8 +9715,20 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
|
|||
//release the data here, as it will always be generated when export
|
||||
calibration_thumbnails[i]->reset();
|
||||
}
|
||||
for (unsigned int i = 0; i < top_thumbnails.size(); i++)
|
||||
{
|
||||
//release the data here, as it will always be generated when export
|
||||
top_thumbnails[i]->reset();
|
||||
}
|
||||
top_thumbnails.clear();
|
||||
for (unsigned int i = 0; i < picking_thumbnails.size(); i++)
|
||||
{
|
||||
//release the data here, as it will always be generated when export
|
||||
picking_thumbnails[i]->reset();;
|
||||
}
|
||||
picking_thumbnails.clear();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Plater::publish_project()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue