diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index d3e939c03..9d265da7c 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -6493,14 +6493,18 @@ int CLI::run(int argc, char **argv) { Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*no_light_thumbnail, thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, false, false, true); + partplate_list, model.objects, glvolume_collection, colors_out, shader, + Slic3r::GUI::Camera::EType::Ortho, Slic3r::GUI::Camera::ViewAngleType::Iso, + false, true); break; } case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext: { Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*no_light_thumbnail, thumbnail_width, thumbnail_height, thumbnail_params, - partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, false, false, true); + partplate_list, model.objects, glvolume_collection, colors_out, shader, + Slic3r::GUI::Camera::EType::Ortho, Slic3r::GUI::Camera::ViewAngleType::Iso, + false, true); break; } default: @@ -6577,20 +6581,29 @@ int CLI::run(int argc, char **argv) { 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); + partplate_list, model.objects, glvolume_collection, colors_out, shader, + Slic3r::GUI::Camera::EType::Ortho, Slic3r::GUI::Camera::ViewAngleType::Top_Plate, + 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); + partplate_list, model.objects, glvolume_collection, colors_out, shader, + Slic3r::GUI::Camera::EType::Ortho, + Slic3r::GUI::Camera::ViewAngleType::Top_Plate, true); break; } case Slic3r::GUI::OpenGLManager::EFramebufferType::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); + partplate_list, model.objects, glvolume_collection, colors_out, shader, + Slic3r::GUI::Camera::EType::Ortho, + Slic3r::GUI::Camera::ViewAngleType::Top_Plate, 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); + thumbnail_width, thumbnail_height, thumbnail_params, partplate_list, model.objects, + glvolume_collection, colors_out, shader, + Slic3r::GUI::Camera::EType::Ortho, + Slic3r::GUI::Camera::ViewAngleType::Top_Plate, + true); break; } default: diff --git a/src/libslic3r/Format/OBJ.hpp b/src/libslic3r/Format/OBJ.hpp index 7fccb6fca..1dfcb2bde 100644 --- a/src/libslic3r/Format/OBJ.hpp +++ b/src/libslic3r/Format/OBJ.hpp @@ -8,8 +8,6 @@ namespace Slic3r { class TriangleMesh; class Model; class ModelObject; -typedef std::function &input_colors, bool is_single_color, std::vector &filament_ids, unsigned char &first_extruder_id, - std::string& ml_region, std::string& ml_name, std::string& ml_id)> ObjImportColorFn; // Load an OBJ file into a provided model. struct ObjInfo { std::vector vertex_colors; @@ -25,6 +23,21 @@ struct ObjInfo { std::string ml_name; std::string ml_id; }; +struct ObjDialogInOut +{ // input:colors array + std::vector input_colors; + bool is_single_color{false}; + // colors array output: + std::vector filament_ids; + unsigned char first_extruder_id; + bool deal_vertex_color; + Model * model{nullptr}; + // ml + std::string ml_region; + std::string ml_name; + std::string ml_id; +}; +typedef std::function ObjImportColorFn; extern bool load_obj(const char *path, TriangleMesh *mesh, ObjInfo &vertex_colors, std::string &message); extern bool load_obj(const char *path, Model *model, ObjInfo &vertex_colors, std::string &message, const char *object_name = nullptr); diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp index fef480704..53439d0ac 100644 --- a/src/libslic3r/GCode/ThumbnailData.hpp +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -38,6 +38,7 @@ struct ThumbnailsParams bool show_bed; bool transparent_background; int plate_id; + bool use_plate_box{true}; }; typedef std::function ThumbnailsGeneratorCallback; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 4abdfd5bd..c7805568c 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -277,22 +277,21 @@ Model Model::read_from_file(const std::string& ObjInfo obj_info; result = load_obj(input_file.c_str(), &model, obj_info, message); if (result){ - unsigned char first_extruder_id; + ObjDialogInOut in_out; + in_out.model = &model; if (obj_info.vertex_colors.size() > 0) { - std::vector vertex_filament_ids; if (objFn) { // 1.result is ok and pop up a dialog - objFn(obj_info.vertex_colors, false, vertex_filament_ids, first_extruder_id, obj_info.ml_region, obj_info.ml_name, obj_info.ml_id); - if (vertex_filament_ids.size() > 0) { - result = obj_import_vertex_color_deal(vertex_filament_ids, first_extruder_id, & model); - } + in_out.input_colors = std::move(obj_info.vertex_colors); + in_out.is_single_color = false; + in_out.deal_vertex_color = true; + objFn(in_out); } } else if (obj_info.face_colors.size() > 0 && obj_info.has_uv_png == false) { // mtl file - std::vector face_filament_ids; if (objFn) { // 1.result is ok and pop up a dialog - objFn(obj_info.face_colors, obj_info.is_single_mtl, face_filament_ids, first_extruder_id, obj_info.ml_region, obj_info.ml_name, obj_info.ml_id); - if (face_filament_ids.size() > 0) { - result = obj_import_face_color_deal(face_filament_ids, first_extruder_id, &model); - } + in_out.input_colors = std::move(obj_info.face_colors); + in_out.is_single_color = obj_info.is_single_mtl; + in_out.deal_vertex_color = false; + objFn(in_out); } } /*else if (obj_info.has_uv_png && obj_info.uvs.size() > 0) { boost::filesystem::path full_path(input_file); @@ -3670,6 +3669,7 @@ bool Model::obj_import_vertex_color_deal(const std::vector &verte auto volume = obj->volumes[0]; volume->config.set("extruder", first_extruder_id); auto face_count = volume->mesh().its.indices.size(); + volume->mmu_segmentation_facets.reset(); volume->mmu_segmentation_facets.reserve(face_count); if (volume->mesh().its.vertices.size() != vertex_filament_ids.size()) { return false; @@ -3682,9 +3682,6 @@ bool Model::obj_import_vertex_color_deal(const std::vector &verte if (filament_id0 <= 1 && filament_id1 <= 1 && filament_id2 <= 2) { continue; } - if (i == 0) { - std::cout << ""; - } VertexColorCase vertex_color_case; unsigned char iso_index; calc_vertex_color_case(filament_id0, filament_id1, filament_id2, vertex_color_case, iso_index); @@ -3763,6 +3760,7 @@ bool Model::obj_import_face_color_deal(const std::vector &face_fi auto volume = obj->volumes[0]; volume->config.set("extruder", first_extruder_id); auto face_count = volume->mesh().its.indices.size(); + volume->mmu_segmentation_facets.reset(); volume->mmu_segmentation_facets.reserve(face_count); if (volume->mesh().its.indices.size() != face_filament_ids.size()) { return false; } for (size_t i = 0; i < volume->mesh().its.indices.size(); i++) { diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 24cc79f39..acda293f2 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -105,6 +105,45 @@ void Camera::select_view(const std::string& direction) look_at(m_target - 0.707 * m_distance * Vec3d::UnitY() + 0.707 * m_distance * Vec3d::UnitZ(), m_target, Vec3d::UnitY() + Vec3d::UnitZ()); } } +void Camera::select_view(ViewAngleType type) +{ + switch (type) { + case Slic3r::GUI::Camera::ViewAngleType::Iso: { + select_view("iso"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Top_Front: { + select_view("topfront"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Left: { + select_view("left"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Right: { + select_view("right"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Top_Plate: + case Slic3r::GUI::Camera::ViewAngleType::Top: { + select_view("top"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Bottom: { + select_view("bottom"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Front: { + select_view("front"); + break; + } + case Slic3r::GUI::Camera::ViewAngleType::Rear: { + select_view("rear"); + break; + } + default: break; + } +} //how to use //BoundingBox bbox = mesh.aabb.transform(transform); //return camera_->getFrustum().intersects(bbox); diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 84151d1ef..239283ada 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -32,7 +32,18 @@ struct Camera Perspective, Num_types }; - + enum class ViewAngleType : unsigned char { + Iso = 0, + Top_Front, + Left, + Right, + Top, + Bottom, + Front, + Rear, + Count_ViewAngleType, + Top_Plate,//for 3mf and Skip parts + }; bool requires_zoom_to_bed{ false }; //BBS bool requires_zoom_to_volumes{ false }; @@ -94,7 +105,7 @@ public: void select_view(const std::string& direction); - + void select_view(ViewAngleType type); const std::array& get_viewport() const { return m_viewport; } const Transform3d& get_view_matrix() const { return m_view_matrix; } const Transform3d& get_projection_matrix() const { return m_projection_matrix; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 70e08643b..48ab247e5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2178,22 +2178,26 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, unsigned int h, const ThumbnailsParams &thumbnail_params, Camera::EType camera_type, - bool use_top_view, + Camera::ViewAngleType camera_view_angle_type, bool for_picking, bool ban_light) { - render_thumbnail(thumbnail_data, w, h, thumbnail_params, m_volumes, camera_type, use_top_view, for_picking, ban_light); + ModelObjectPtrs &model_objects = GUI::wxGetApp().model().objects; + render_thumbnail(thumbnail_data, w, h, thumbnail_params, model_objects, m_volumes, camera_type, camera_view_angle_type, for_picking, ban_light); } -void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, +void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, + unsigned int w, + unsigned int h, + const ThumbnailsParams & thumbnail_params, + ModelObjectPtrs & model_objects, const GLVolumeCollection &volumes, Camera::EType camera_type, - bool use_top_view, + Camera::ViewAngleType camera_view_angle_type, bool for_picking, bool ban_light) { GLShaderProgram* shader = wxGetApp().get_shader("thumbnail"); - ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects; std::vector> colors = ::get_extruders_colors(); const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type(); BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str(); @@ -2202,22 +2206,56 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, case OpenGLManager::EFramebufferType::Supported: 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, - use_top_view, for_picking, ban_light); + camera_view_angle_type, for_picking, ban_light); 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, - use_top_view, for_picking, ban_light); + camera_view_angle_type, for_picking, ban_light); break; } default:{ render_thumbnail_legacy(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type, - use_top_view, for_picking, ban_light); + camera_view_angle_type, for_picking, ban_light); break; } } } +void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, + std::vector> &extruder_colors, + unsigned int w, + unsigned int h, + const ThumbnailsParams & thumbnail_params, + ModelObjectPtrs & model_objects, + const GLVolumeCollection & volumes, + Camera::EType camera_type, + Camera::ViewAngleType camera_view_angle_type, + bool for_picking, + bool ban_light) +{ + GLShaderProgram *shader = wxGetApp().get_shader("thumbnail"); + const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type(); + BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str(); + switch (fb_type){ + case OpenGLManager::EFramebufferType::Supported: + case OpenGLManager::EFramebufferType::Arb: { + render_thumbnail_framebuffer(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, extruder_colors, shader, + camera_type, camera_view_angle_type, for_picking, ban_light); + break; + } + case OpenGLManager::EFramebufferType::Ext: { + render_thumbnail_framebuffer_ext(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, extruder_colors, shader, + camera_type, camera_view_angle_type, for_picking, ban_light); + break; + } + default: { + render_thumbnail_legacy(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, extruder_colors, shader, camera_type, camera_view_angle_type, for_picking, ban_light); + break; + } + } +} + void GLCanvas3D::render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params) { //load current plate gcode @@ -5957,59 +5995,57 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view, + Camera::ViewAngleType camera_view_angle_type, bool for_picking, bool ban_light) { //BBS modify visible calc function - int plate_idx = thumbnail_params.plate_id; - PartPlate* plate = partplate_list.get_plate(plate_idx); - BoundingBoxf3 plate_build_volume = plate->get_build_volume(); - plate_build_volume.min(0) -= Slic3r::BuildVolume::SceneEpsilon; - plate_build_volume.min(1) -= Slic3r::BuildVolume::SceneEpsilon; - plate_build_volume.min(2) -= Slic3r::BuildVolume::SceneEpsilon; - plate_build_volume.max(0) += Slic3r::BuildVolume::SceneEpsilon; - plate_build_volume.max(1) += Slic3r::BuildVolume::SceneEpsilon; - plate_build_volume.max(2) += Slic3r::BuildVolume::SceneEpsilon; - /*if (m_config != nullptr) { - double h = m_config->opt_float("printable_height"); - plate_build_volume.min(2) = std::min(plate_build_volume.min(2), -h); - plate_build_volume.max(2) = std::max(plate_build_volume.max(2), h); - }*/ + static std::array curr_color; + static const std::array orange = {0.923f, 0.504f, 0.264f, 1.0f}; + static const std::array gray = {0.64f, 0.64f, 0.64f, 1.0f}; + GLVolumePtrs visible_volumes; + BoundingBoxf3 plate_build_volume; + if (thumbnail_params.use_plate_box) { + int plate_idx = thumbnail_params.plate_id; + PartPlate * plate = partplate_list.get_plate(plate_idx); + plate_build_volume = plate->get_build_volume(); + plate_build_volume.min(0) -= Slic3r::BuildVolume::SceneEpsilon; + plate_build_volume.min(1) -= Slic3r::BuildVolume::SceneEpsilon; + plate_build_volume.min(2) -= Slic3r::BuildVolume::SceneEpsilon; + plate_build_volume.max(0) += Slic3r::BuildVolume::SceneEpsilon; + plate_build_volume.max(1) += Slic3r::BuildVolume::SceneEpsilon; + plate_build_volume.max(2) += Slic3r::BuildVolume::SceneEpsilon; + /*if (m_config != nullptr) { + double h = m_config->opt_float("printable_height"); + plate_build_volume.min(2) = std::min(plate_build_volume.min(2), -h); + plate_build_volume.max(2) = std::max(plate_build_volume.max(2), h); + }*/ - auto is_visible = [plate_idx, plate_build_volume](const GLVolume& v) { - bool ret = v.printable; - if (plate_idx >= 0) { - bool contained = false; - BoundingBoxf3 plate_bbox = plate_build_volume; - plate_bbox.min(2) = -1e10; - const BoundingBoxf3& volume_bbox = v.transformed_convex_hull_bounding_box(); - if (plate_bbox.contains(volume_bbox) && (volume_bbox.max(2) > 0)) { - contained = true; + auto is_visible = [plate_idx, plate_build_volume](const GLVolume &v) { + bool ret = v.printable; + if (plate_idx >= 0) { + bool contained = false; + BoundingBoxf3 plate_bbox = plate_build_volume; + plate_bbox.min(2) = -1e10; + const BoundingBoxf3 &volume_bbox = v.transformed_convex_hull_bounding_box(); + if (plate_bbox.contains(volume_bbox) && (volume_bbox.max(2) > 0)) { contained = true; } + ret &= contained; + } else { + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); } - ret &= contained; - } - else { - ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); - } - return ret; - }; + return ret; + }; - static std::array curr_color; - static const std::array orange = { 0.923f, 0.504f, 0.264f, 1.0f }; - static const std::array gray = { 0.64f, 0.64f, 0.64f, 1.0f }; - - GLVolumePtrs visible_volumes; - - for (GLVolume* vol : volumes.volumes) { - if (!vol->is_modifier && !vol->is_wipe_tower && (!thumbnail_params.parts_only || vol->composite_id.volume_id >= 0)) { - if (is_visible(*vol)) { - visible_volumes.emplace_back(vol); + for (GLVolume *vol : volumes.volumes) { + if (!vol->is_modifier && !vol->is_wipe_tower && (!thumbnail_params.parts_only || vol->composite_id.volume_id >= 0)) { + if (is_visible(*vol)) { visible_volumes.emplace_back(vol); } } } + 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 % (int)camera_view_angle_type % for_picking; + } else { + visible_volumes = volumes.volumes; } - - 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; @@ -6027,21 +6063,24 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const volumes_box.min.x() = volumes_box.min.x() - width * 0.1f; volumes_box.max.y() = volumes_box.max.y() + depth * 0.1f; volumes_box.min.y() = volumes_box.min.y() - depth * 0.1f; - volumes_box.max.z() = volumes_box.max.z() + height * 0.1f; - volumes_box.min.z() = volumes_box.min.z() - height * 0.1f; + volumes_box.max.z() = volumes_box.max.z() + height * 0.2f; + volumes_box.min.z() = volumes_box.min.z() - height * 0.2f; Camera camera; camera.set_type(camera_type); //BBS modify scene box to plate scene bounding box //plate_build_volume.min(2) = - plate_build_volume.max(2); - camera.set_scene_box(plate_build_volume); + if (thumbnail_params.use_plate_box) { + camera.set_scene_box(plate_build_volume); + } + camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); //BoundingBoxf3 plate_box = plate->get_bounding_box(false); //plate_box.min.z() = 0.0; //plate_box.max.z() = 0.0; - if (use_top_view) { + if (camera_view_angle_type == Camera::ViewAngleType::Top_Plate) { 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); @@ -6063,14 +6102,17 @@ void GLCanvas3D::render_thumbnail_internal(ThumbnailData& thumbnail_data, const //camera.look_at(target - 0.707 * distance * Vec3d::UnitY() + 0.3 * distance * Vec3d::UnitZ(), target, Vec3d::UnitY() + Vec3d::UnitZ()); //BBS: use original iso view for thumbnail - camera.select_view("iso"); + camera.select_view(camera_view_angle_type); camera.zoom_to_box(volumes_box); } camera.apply_view_matrix(); - - camera.apply_projection(plate_build_volume); - + if (thumbnail_params.use_plate_box) { + camera.apply_projection(plate_build_volume); + } + else { + camera.apply_projection(volumes_box); + } //double near_z = -1.0; //double far_z = -1.0; //camera.apply_projection(volumes_box, near_z, far_z); @@ -6195,7 +6237,7 @@ void GLCanvas3D::render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, uns PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view, + Camera::ViewAngleType camera_view_angle_type, bool for_picking, bool ban_light) { @@ -6250,8 +6292,8 @@ 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, use_top_view, for_picking,ban_light); + render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, camera_view_angle_type, + for_picking, ban_light); if (multisample) { GLuint resolve_fbo; @@ -6308,7 +6350,7 @@ void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view, + Camera::ViewAngleType camera_view_angle_type, bool for_picking, bool ban_light) { @@ -6362,7 +6404,8 @@ 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, use_top_view, for_picking, + render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, camera_view_angle_type, + for_picking, ban_light); if (multisample) { @@ -6413,7 +6456,7 @@ void GLCanvas3D::render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, } void GLCanvas3D::render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, PartPlateList &partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram* shader, Camera::EType camera_type, - bool use_top_view, + Camera::ViewAngleType camera_view_angle_type, bool for_picking, bool ban_light) { @@ -6431,7 +6474,7 @@ void GLCanvas3D::render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned if (!thumbnail_data.is_valid()) return; - render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, use_top_view, for_picking, + render_thumbnail_internal(thumbnail_data, thumbnail_params, partplate_list, model_objects, volumes, extruder_colors, shader, camera_type, camera_view_angle_type, for_picking, ban_light); glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 71b9dae53..8e86de2fd 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -883,20 +883,35 @@ public: // 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, - bool use_top_view = false, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, bool for_picking = false, bool ban_light = false); - void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, + void render_thumbnail(ThumbnailData & thumbnail_data, + unsigned int w, + unsigned int h, + const ThumbnailsParams & thumbnail_params, + ModelObjectPtrs & model_objects, const GLVolumeCollection &volumes, Camera::EType camera_type, - bool use_top_view = false, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, + bool for_picking = false, + bool ban_light = false); + void render_thumbnail(ThumbnailData & thumbnail_data, + std::vector> &extruder_colors, + unsigned int w, + unsigned int h, + const ThumbnailsParams & thumbnail_params, + ModelObjectPtrs & model_objects, + const GLVolumeCollection &volumes, + Camera::EType camera_type, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, bool for_picking = false, bool ban_light = false); static void render_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view = false, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, bool for_picking = false, bool ban_light = false); // render thumbnail using an off-screen framebuffer @@ -904,7 +919,7 @@ public: PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view = false, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, bool for_picking = false, bool ban_light = false); // render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported @@ -912,7 +927,7 @@ public: PartPlateList& partplate_list, ModelObjectPtrs& model_objects, const GLVolumeCollection& volumes, std::vector>& extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view = false, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, bool for_picking = false, bool ban_light = false); @@ -927,7 +942,7 @@ public: std::vector> &extruder_colors, GLShaderProgram * shader, Camera::EType camera_type, - bool use_top_view = false, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, bool for_picking = false, bool ban_light = false); diff --git a/src/slic3r/GUI/ObjColorDialog.cpp b/src/slic3r/GUI/ObjColorDialog.cpp index 652a581aa..f7abcdf4b 100644 --- a/src/slic3r/GUI/ObjColorDialog.cpp +++ b/src/slic3r/GUI/ObjColorDialog.cpp @@ -15,7 +15,7 @@ #include #include "libslic3r/ObjColorUtils.hpp" - +#include "libslic3r/Model.hpp" using namespace Slic3r; using namespace Slic3r::GUI; @@ -26,12 +26,12 @@ const int HEADER_BORDER = 5; const int CONTENT_BORDER = 3; const int PANEL_WIDTH = 370; const int COLOR_LABEL_WIDTH = 180; - +const int IMAGE_SIZE_WIDTH = 300; #define MIN_OBJCOLOR_DIALOG_WIDTH FromDIP(400) #define FIX_SCROLL_HEIGTH FromDIP(400) #define BTN_SIZE wxSize(FromDIP(58), FromDIP(24)) #define BTN_GAP FromDIP(20) - +#define FIX_SCROLL_IMAGE_WIDTH FromDIP(270) static void update_ui(wxWindow* window) { Slic3r::GUI::wxGetApp().UpdateDarkUI(window); @@ -128,20 +128,15 @@ void ObjColorDialog::on_dpi_changed(const wxRect &suggested_rect) this->Refresh(); }; -ObjColorDialog::ObjColorDialog(wxWindow * parent, - std::vector & input_colors, - bool is_single_color, - const std::vector &extruder_colours, - std::vector & filament_ids, - unsigned char & first_extruder_id) +ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector &extruder_colours) : DPIDialog(parent ? parent : static_cast(wxGetApp().mainframe), wxID_ANY, _(L("Obj file Import color")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE /* | wxRESIZE_BORDER*/) - , m_filament_ids(filament_ids) - , m_first_extruder_id(first_extruder_id) + , m_filament_ids(in_out.filament_ids) + , m_first_extruder_id(in_out.first_extruder_id) { std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % Slic3r::resources_dir()).str(); SetIcon(wxIcon(Slic3r::encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); @@ -152,7 +147,7 @@ ObjColorDialog::ObjColorDialog(wxWindow * parent, this->SetBackgroundColour(*wxWHITE); this->SetMinSize(wxSize(MIN_OBJCOLOR_DIALOG_WIDTH, -1)); - m_panel_ObjColor = new ObjColorPanel(this, input_colors, is_single_color, extruder_colours, filament_ids, first_extruder_id); + m_panel_ObjColor = new ObjColorPanel(this, in_out, extruder_colours); auto main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(m_line_top, 0, wxEXPAND, 0); @@ -176,13 +171,16 @@ ObjColorDialog::ObjColorDialog(wxWindow * parent, if (this->FindWindowById(wxID_OK, this)) { this->FindWindowById(wxID_OK, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {// if OK button is clicked.. - m_panel_ObjColor->update_filament_ids(); + m_panel_ObjColor->send_new_filament_to_ui(); EndModal(wxID_OK); }, wxID_OK); } if (this->FindWindowById(wxID_CANCEL, this)) { update_ui(static_cast(this->FindWindowById(wxID_CANCEL, this))); - this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { EndModal(wxCANCEL); }); + this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + m_panel_ObjColor->cancel_paint_color(); + EndModal(wxCANCEL); + }); } this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); }); @@ -190,31 +188,27 @@ ObjColorDialog::ObjColorDialog(wxWindow * parent, } // This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers) -ObjColorPanel::ObjColorPanel(wxWindow * parent, - std::vector& input_colors, - bool is_single_color, - const std::vector& extruder_colours, - std::vector & filament_ids, - unsigned char & first_extruder_id) +ObjColorPanel::ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector &extruder_colours) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize /*,wxBORDER_RAISED*/) - , m_input_colors(input_colors) - , m_filament_ids(filament_ids) - , m_first_extruder_id(first_extruder_id) + , m_obj_in_out(in_out) + , m_input_colors(in_out.input_colors) + , m_filament_ids(in_out.filament_ids) + , m_first_extruder_id(in_out.first_extruder_id) { - if (input_colors.size() == 0) { return; } + if (in_out.input_colors.size() == 0) { return; } for (const std::string& color : extruder_colours) { m_colours.push_back(wxColor(color)); } //deal input_colors - m_input_colors_size = input_colors.size(); - for (size_t i = 0; i < input_colors.size(); i++) { - if (color_is_equal(input_colors[i] , UNDEFINE_COLOR)) { // not define color range:0~1 - input_colors[i]=convert_to_rgba( m_colours[0]); + m_input_colors_size = in_out.input_colors.size(); + for (size_t i = 0; i < in_out.input_colors.size(); i++) { + if (color_is_equal(in_out.input_colors[i], UNDEFINE_COLOR)) { // not define color range:0~1 + in_out.input_colors[i] = convert_to_rgba(m_colours[0]); } } - if (is_single_color && input_colors.size() >=1) { - m_cluster_colors_from_algo.emplace_back(input_colors[0]); - m_cluster_colours.emplace_back(convert_to_wxColour(input_colors[0])); + if (in_out.is_single_color && in_out.input_colors.size() >= 1) { + m_cluster_colors_from_algo.emplace_back(in_out.input_colors[0]); + m_cluster_colours.emplace_back(convert_to_wxColour(in_out.input_colors[0])); m_cluster_labels_from_algo.reserve(m_input_colors_size); for (size_t i = 0; i < m_input_colors_size; i++) { m_cluster_labels_from_algo.emplace_back(0); @@ -239,7 +233,7 @@ ObjColorPanel::ObjColorPanel(wxWindow * parent, // BBS: for tunning flush volumes { //color cluster results - wxBoxSizer * specify_cluster_sizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer * specify_cluster_sizer = new wxBoxSizer(wxHORIZONTAL); wxStaticText *specify_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Specify number of colors:")); specify_color_cluster_title->SetFont(Label::Head_14); specify_cluster_sizer->Add(specify_color_cluster_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); @@ -293,7 +287,48 @@ ObjColorPanel::ObjColorPanel(wxWindow * parent, specify_cluster_sizer->Add(recommend_color_cluster_title, 0, wxALIGN_CENTER | wxALL, 0); m_sizer_simple->Add(specify_cluster_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20)); + {//add image + wxImage image(IMAGE_SIZE_WIDTH, IMAGE_SIZE_WIDTH); + image.InitAlpha(); + for (unsigned int r = 0; r < IMAGE_SIZE_WIDTH; ++r) { + for (unsigned int c = 0; c < IMAGE_SIZE_WIDTH; ++c) { + image.SetRGB((int) c, (int) r, 0, 255, 0); + image.SetAlpha((int) c, (int) r, 255); + } + } + auto icon_sizer = new wxBoxSizer(wxHORIZONTAL); + m_image_button = new wxButton(m_page_simple, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH)), + wxBORDER_NONE | wxBU_AUTODRAW); + m_image_button->SetBitmap(image); + m_image_button->SetCanFocus(false); + icon_sizer->Add(m_image_button, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, + FromDIP(0)); // wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL + m_sizer_simple->Add(icon_sizer, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(0)); + {//choose camera view angle type + auto combox_sizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticText *combox_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Choose camera view angle:")); + combox_sizer->Add(combox_title, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, FromDIP(0)); + + wxStaticText *space_title = new wxStaticText(m_page_simple, wxID_ANY, " "); + combox_sizer->Add(space_title, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(0)); + + auto cur_combox = new ComboBox(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(100), -1), 0, NULL, wxCB_READONLY); + wxArrayString choices = get_all_camera_view_type(); + for (size_t i = 0; i < choices.size(); i++) { + cur_combox->Append(choices[i]); + } + cur_combox->SetSelection(0); + cur_combox->Bind(wxEVT_COMBOBOX, [this](auto &e) { + set_view_angle_type(e.GetSelection()); + Layout(); + Fit(); + }); + combox_sizer->Add(cur_combox, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL, FromDIP(0)); + + m_sizer_simple->Add(combox_sizer, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(2)); + } + } wxBoxSizer * current_filaments_title_sizer = new wxBoxSizer(wxHORIZONTAL); wxStaticText *current_filaments_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Current filament colors:")); current_filaments_title->SetFont(Label::Head_14); @@ -337,6 +372,7 @@ ObjColorPanel::ObjColorPanel(wxWindow * parent, m_sizer_simple->AddSpacer(10); } deal_default_strategy(); + deal_thumbnail(); //page_simple//page_advanced m_sizer = new wxBoxSizer(wxVERTICAL); m_sizer->Add(m_page_simple, 0, wxEXPAND, 0); @@ -346,6 +382,9 @@ ObjColorPanel::ObjColorPanel(wxWindow * parent, this->Layout(); } +ObjColorPanel::~ObjColorPanel() { +} + void ObjColorPanel::msw_rescale() { for (unsigned int i = 0; i < m_extruder_icon_list.size(); ++i) { @@ -370,7 +409,7 @@ bool ObjColorPanel::is_ok() { return true; } -void ObjColorPanel::update_filament_ids() +void ObjColorPanel::send_new_filament_to_ui() { if (m_is_add_filament) { for (auto c : m_new_add_final_colors) { @@ -379,6 +418,17 @@ void ObjColorPanel::update_filament_ids() wxGetApp().sidebar().add_custom_filament(c); } } +} + +void ObjColorPanel::cancel_paint_color() { + m_filament_ids.clear(); + auto mo = m_obj_in_out.model->objects[0]; + auto mv = mo->volumes[0]; + mv->mmu_segmentation_facets.reset(); +} + +void ObjColorPanel::update_filament_ids() +{ //deal m_filament_ids m_filament_ids.clear(); m_filament_ids.reserve(m_input_colors_size); @@ -654,7 +704,8 @@ void ObjColorPanel::draw_table() m_gridsizer->Add(row_panel, 0, wxALIGN_LEFT | wxALL, FromDIP(HEADER_BORDER)); } m_scrolledWindow->SetSizer(m_gridsizer); - int totalHeight = row_height *(row+1) * 2; + const int fix_row = 4; + int totalHeight = row_height * (fix_row + 1) * 2; m_scrolledWindow->SetVirtualSize(MIN_OBJCOLOR_DIALOG_WIDTH, totalHeight); auto look = FIX_SCROLL_HEIGTH; if (totalHeight > FIX_SCROLL_HEIGTH) { @@ -677,6 +728,9 @@ void ObjColorPanel::update_new_add_final_colors() } else { m_new_add_final_colors.resize(m_max_filament_index - m_colours.size()); } + if (m_new_add_final_colors.size() > 0) { + m_is_add_filament = true; + } } void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui) @@ -684,6 +738,7 @@ void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui) if (m_last_cluster_number == cluster_number) { return; } + wxBusyCursor cursor; m_last_cluster_number = cluster_number; obj_color_deal_algo(m_input_colors, m_cluster_colors_from_algo, m_cluster_labels_from_algo, cluster_number); @@ -705,6 +760,7 @@ void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui) if (redraw_ui) { redraw_part_table(); deal_default_strategy(); + deal_thumbnail(); } } @@ -715,6 +771,76 @@ void ObjColorPanel::deal_default_strategy() m_warning_text->SetLabelText(_L("Note:The color has been selected, you can choose OK \n to continue or manually adjust it.")); } +void ObjColorPanel::deal_thumbnail() { + update_filament_ids(); + // generate model volume + m_deal_thumbnail_flag= false; + if (m_obj_in_out.deal_vertex_color) { + if (m_obj_in_out.filament_ids.size() > 0) { + m_deal_thumbnail_flag = Model::obj_import_vertex_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model); + } + } else { + if (m_obj_in_out.filament_ids.size() > 0) { + m_deal_thumbnail_flag = Model::obj_import_face_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model); + } + } + generate_thumbnail(); +} + +void ObjColorPanel::generate_thumbnail() +{ + if (m_deal_thumbnail_flag && m_obj_in_out.model->objects.size() == 1) { + auto mo = m_obj_in_out.model->objects[0]; + mo->add_instance(); + std::vector> colors = ::get_extruders_colors(); + for (size_t i = 0; i < m_new_add_final_colors.size(); i++) { + std::array temp_color; + temp_color[0] = m_new_add_final_colors[i].Red() /255.f; + temp_color[1] = m_new_add_final_colors[i].Green() / 255.f; + temp_color[2] = m_new_add_final_colors[i].Blue() / 255.f; + temp_color[3] = m_new_add_final_colors[i].Alpha() / 255.f; + colors.emplace_back(temp_color); + } + auto mv = mo->volumes[0]; + auto box = mo->bounding_box(); + if (box.min.x() < 0 || box.min.y() < 0 || box.min.z() < 0) { + mv->translate(box.min.x() < 0 ? -box.min.x() : 0, box.min.y() < 0 ? -box.min.y() : 0, box.min.z() < 0 ? -box.min.z() : 0); + } + wxGetApp().plater()->update_obj_preview_thumbnail(mo, 0, 0, colors, (int)m_camera_view_angle_type); + mo->clear_instances(); + // get thumbnail image + PartPlate *plate = wxGetApp().plater()->get_partplate_list().get_plate(0); + auto & data = plate->obj_preview_thumbnail_data; + if (data.is_valid()) { + wxImage image(data.width, data.height); + image.InitAlpha(); + for (unsigned int r = 0; r < data.height; ++r) { + unsigned int rr = (data.height - 1 - r) * data.width; + for (unsigned int c = 0; c < data.width; ++c) { + unsigned char *px = (unsigned char *) data.pixels.data() + 4 * (rr + c); + image.SetRGB((int) c, (int) r, px[0], px[1], px[2]); + image.SetAlpha((int) c, (int) r, px[3]); + } + } + image = image.Rescale(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH)); + m_image_button->SetBitmap(image); + } + } + else { +#ifdef _WIN32 + __debugbreak(); +#endif + } +} + +void ObjColorPanel::set_view_angle_type(int value) +{ + if (value >= 0){ + m_camera_view_angle_type = (Slic3r::GUI::Camera::ViewAngleType)value; + generate_thumbnail(); + } +} + void ObjColorPanel::deal_add_btn() { if (m_colours.size() > g_max_color) { return; } @@ -752,7 +878,6 @@ void ObjColorPanel::deal_add_btn() deal_approximate_match_btn(); m_warning_text->SetLabelText(_L("Waring:The count of newly added and \n current extruders exceeds 16.")); } - m_is_add_filament = true; } void ObjColorPanel::deal_reset_btn() diff --git a/src/slic3r/GUI/ObjColorDialog.hpp b/src/slic3r/GUI/ObjColorDialog.hpp index 21b29578c..12f11693e 100644 --- a/src/slic3r/GUI/ObjColorDialog.hpp +++ b/src/slic3r/GUI/ObjColorDialog.hpp @@ -2,7 +2,9 @@ #define _OBJ_COLOR_DIALOG_H_ #include "GUI_Utils.hpp" +#include "Camera.hpp" #include "GuiColor.hpp" +#include "libslic3r/Format/OBJ.hpp" #include #include #include @@ -18,13 +20,12 @@ class ObjColorPanel : public wxPanel { public: // BBS - ObjColorPanel(wxWindow * parent, - std::vector & input_colors,bool is_single_color, - const std::vector & extruder_colours, - std::vector & filament_ids, - unsigned char & first_extruder_id); + ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector &extruder_colours); + ~ObjColorPanel(); void msw_rescale(); bool is_ok(); + void send_new_filament_to_ui(); + void cancel_paint_color(); void update_filament_ids(); struct ButtonState { @@ -50,8 +51,13 @@ private: void deal_reset_btn(); void deal_algo(char cluster_number,bool redraw_ui =false); void deal_default_strategy(); + void deal_thumbnail(); + void generate_thumbnail(); + void set_view_angle_type(int); private: //view ui + Slic3r::ObjDialogInOut & m_obj_in_out; + Slic3r::GUI::Camera::ViewAngleType m_camera_view_angle_type{Slic3r::GUI::Camera::ViewAngleType::Iso}; wxScrolledWindow * m_scrolledWindow = nullptr; wxPanel * m_page_simple = nullptr; wxBoxSizer * m_sizer = nullptr; @@ -71,7 +77,7 @@ private: int m_combox_icon_width; int m_combox_icon_height; wxGridSizer* m_gridsizer = nullptr; - wxStaticText * m_test = nullptr; + wxButton * m_image_button = nullptr; //data char m_last_cluster_number{-2}; std::vector& m_input_colors; @@ -83,6 +89,7 @@ private: int m_max_filament_index = 0; std::vector m_cluster_colours;//from_algo and show left bool m_can_add_filament{true}; + bool m_deal_thumbnail_flag{false}; std::vector m_new_add_colors; std::vector m_new_add_final_colors; //algo result @@ -97,11 +104,7 @@ private: class ObjColorDialog : public Slic3r::GUI::DPIDialog { public: - ObjColorDialog(wxWindow * parent, - std::vector& input_colors, bool is_single_color, - const std::vector & extruder_colours, - std::vector& filament_ids, - unsigned char & first_extruder_id); + ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector &extruder_colours); wxBoxSizer* create_btn_sizer(long flags); void on_dpi_changed(const wxRect &suggested_rect) override; private: diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index a6e261574..4f3805fb3 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -237,6 +237,7 @@ public: //static const double plate_x_gap = 0.2; ThumbnailData thumbnail_data; ThumbnailData no_light_thumbnail_data; + ThumbnailData obj_preview_thumbnail_data; static const int plate_thumbnail_width = 512; static const int plate_thumbnail_height = 512; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7405e5c78..c9edcad35 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3332,7 +3332,10 @@ struct Plater::priv //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, bool use_top_view = false, bool for_picking = false,bool ban_light = false); + Camera::EType camera_type, + Camera::ViewAngleType camera_view_angle_type = Camera::ViewAngleType::Iso, + bool for_picking = false, + bool ban_light = 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); @@ -4703,18 +4706,17 @@ std::vector Plater::priv::load_files(const std::vector& input_ Semver file_version; //ObjImportColorFn obj_color_fun=nullptr; - auto obj_color_fun = [this, &path, &makerlab_region, &makerlab_name, &makerlab_id](std::vector &input_colors, bool is_single_color, std::vector &filament_ids, - unsigned char& first_extruder_id, std::string ml_origin, std::string ml_name, std::string ml_id) { + auto obj_color_fun = [this, &path, &makerlab_region, &makerlab_name, &makerlab_id](ObjDialogInOut &in_out) { - makerlab_region = ml_origin; - makerlab_name = ml_name; - makerlab_id = ml_id; + makerlab_region = in_out.ml_region; + makerlab_name = in_out.ml_name; + makerlab_id = in_out.ml_id; if (!boost::iends_with(path.string(), ".obj")) { return; } const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); - ObjColorDialog color_dlg(nullptr, input_colors, is_single_color, extruder_colours, filament_ids, first_extruder_id); + ObjColorDialog color_dlg(nullptr, in_out, extruder_colours); if (color_dlg.ShowModal() != wxID_OK) { - filament_ids.clear(); + in_out.filament_ids.clear(); } }; if (boost::iends_with(path.string(), ".stp") || @@ -6639,12 +6641,13 @@ void Plater::priv::reload_from_disk() // load one file at a time for (size_t i = 0; i < input_paths.size(); ++i) { const auto& path = input_paths[i].string(); - auto obj_color_fun = [this, &path](std::vector &input_colors, bool is_single_color, std::vector &filament_ids, unsigned char &first_extruder_id, - std::string ml_origin, std::string ml_name, std::string ml_id) { + auto obj_color_fun = [this, &path](ObjDialogInOut &in_out) { if (!boost::iends_with(path, ".obj")) { return; } const std::vector extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config(); - ObjColorDialog color_dlg(nullptr, input_colors, is_single_color, extruder_colours, filament_ids, first_extruder_id); - if (color_dlg.ShowModal() != wxID_OK) { filament_ids.clear(); } + ObjColorDialog color_dlg(nullptr, in_out, extruder_colours); + if (color_dlg.ShowModal() != wxID_OK) { + in_out.filament_ids.clear(); + } }; wxBusyCursor wait; if (!boost::iends_with(path, ".obj")) { @@ -8349,9 +8352,16 @@ 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, bool use_top_view, bool for_picking, bool ban_light) +void Plater::priv::generate_thumbnail(ThumbnailData & data, + unsigned int w, + unsigned int h, + const ThumbnailsParams &thumbnail_params, + Camera::EType camera_type, + Camera::ViewAngleType camera_view_angle_type, + bool for_picking, + bool ban_light) { - view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type, use_top_view, for_picking, ban_light); + view3D->get_canvas3d()->render_thumbnail(data, w, h, thumbnail_params, camera_type, camera_view_angle_type, for_picking, ban_light); } //BBS: add plate id for thumbnail generate param @@ -11100,11 +11110,23 @@ void Plater::update_all_plate_thumbnails(bool force_update) } if (force_update || !plate->no_light_thumbnail_data.is_valid()) { get_view3D_canvas3D()->render_thumbnail(plate->no_light_thumbnail_data, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params, - Camera::EType::Ortho,false,false,true); + Camera::EType::Ortho, Camera::ViewAngleType::Iso, false, true); } } } +void Plater::update_obj_preview_thumbnail(ModelObject *mo, int obj_idx, int vol_idx, std::vector> colors, int camera_view_angle_type) +{ + PartPlate * plate = get_partplate_list().get_plate(0); + ThumbnailsParams thumbnail_params = {{}, false, true, true, true, 0, false}; + GLVolumeCollection cur_volumes; + cur_volumes.load_object_volume(mo, obj_idx, vol_idx, 0, "volume", true, false, false, false); + ModelObjectPtrs model_objects; + model_objects.emplace_back(mo); + get_view3D_canvas3D()->render_thumbnail(plate->obj_preview_thumbnail_data, colors, plate->plate_thumbnail_width, plate->plate_thumbnail_height, thumbnail_params, + model_objects, cur_volumes, Camera::EType::Ortho, (Camera::ViewAngleType) camera_view_angle_type, false, true); +} + //invalid all plate's thumbnails void Plater::invalid_all_plate_thumbnails() { @@ -13020,8 +13042,8 @@ 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)->no_light_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, - thumbnail_params, Camera::EType::Ortho,false,false,true); + p->generate_thumbnail(p->partplate_list.get_plate(i)->no_light_thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, thumbnail_params, + Camera::EType::Ortho, Camera::ViewAngleType::Iso, false, true); } no_light_thumbnails.push_back(no_light_thumbnail_data); //ThumbnailData* calibration_data = &p->partplate_list.get_plate(i)->cali_thumbnail_data; @@ -13038,8 +13060,8 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy 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); + 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, Camera::ViewAngleType::Top_Plate, false); } top_thumbnails.push_back(top_thumbnail); @@ -13051,8 +13073,8 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy 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); + 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, Camera::ViewAngleType::Top_Plate, true); } picking_thumbnails.push_back(picking_thumbnail); } @@ -15751,5 +15773,24 @@ SuppressBackgroundProcessingUpdate::~SuppressBackgroundProcessingUpdate() { wxGetApp().plater()->schedule_background_process(m_was_scheduled); } - +wxString get_view_type_string(Camera::ViewAngleType type) { + switch (type) { + case Slic3r::GUI::Camera::ViewAngleType::Iso: return _L("isometric"); + case Slic3r::GUI::Camera::ViewAngleType::Top_Front: return _L("top_front"); + case Slic3r::GUI::Camera::ViewAngleType::Left: return _L("left"); + case Slic3r::GUI::Camera::ViewAngleType::Right: return _L("right"); + case Slic3r::GUI::Camera::ViewAngleType::Top: return _L("top"); + case Slic3r::GUI::Camera::ViewAngleType::Bottom: return _L("bottom"); + case Slic3r::GUI::Camera::ViewAngleType::Front: return _L("front"); + case Slic3r::GUI::Camera::ViewAngleType::Rear: return _L("rear"); + default: return ""; + } +} +wxArrayString get_all_camera_view_type() { + wxArrayString all_types; + for (size_t i = 0; i < (int)Camera::ViewAngleType::Count_ViewAngleType; i++) { + all_types.Add(get_view_type_string((Camera::ViewAngleType) i)); + } + return all_types; +} }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 697ea13e9..c0312d000 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -287,6 +287,7 @@ public: // BBS wxString get_project_name(); void update_all_plate_thumbnails(bool force_update = false); + void update_obj_preview_thumbnail(ModelObject *, int obj_idx, int vol_idx, std::vector> colors, int camera_view_angle_type); void invalid_all_plate_thumbnails(); void force_update_all_plate_thumbnails(); @@ -813,8 +814,9 @@ private: std::vector get_min_flush_volumes(const DynamicPrintConfig &full_config, size_t nozzle_id); std::string check_boolean_possible(const std::vector& volumes); - Preset *get_printer_preset(MachineObject *obj); -} // namespace GUI +Preset *get_printer_preset(MachineObject *obj); +wxArrayString get_all_camera_view_type(); + } // namespace GUI } // namespace Slic3r #endif