diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index fbc7a76bd..cf05c5e63 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -183,6 +183,8 @@ void AppConfig::set_defaults() set_bool("show_shells_in_preview", true); if (get("enable_lod").empty()) set_bool("enable_lod", true); + if (get("gamma_correct_in_import_obj").empty()) + set_bool("gamma_correct_in_import_obj", false); if (get("enable_opengl_multi_instance").empty()) set_bool("enable_opengl_multi_instance", true); if (get("import_single_svg_and_split").empty()) diff --git a/src/libslic3r/Color.cpp b/src/libslic3r/Color.cpp index 654b248b8..377536296 100644 --- a/src/libslic3r/Color.cpp +++ b/src/libslic3r/Color.cpp @@ -235,6 +235,27 @@ ColorRGBA ColorRGBA::operator * (float value) const return ret; } +void ColorRGBA::gamma_correct() { + auto coe = 1 / 2.2f; + for (int i = 0; i < 4; i++) { + m_data[i] = std::pow(m_data[i], coe); + } +} + +void ColorRGBA::gamma_correct(RGBA &color) +{ + auto coe = 1 / 2.2f; + for (int i = 0; i < 4; i++) { + color[i] = std::pow(color[i], coe); + } +} + +float ColorRGBA::gamma_correct(float value) +{ + auto coe = 1 / 2.2f; + return std::pow(value, coe); +} + ColorRGB operator * (float value, const ColorRGB& other) { return other * value; } ColorRGBA operator * (float value, const ColorRGBA& other) { return other * value; } diff --git a/src/libslic3r/Color.hpp b/src/libslic3r/Color.hpp index c6caa3f6e..733dfbb18 100644 --- a/src/libslic3r/Color.hpp +++ b/src/libslic3r/Color.hpp @@ -107,7 +107,9 @@ public: void g(float g) { m_data[1] = std::clamp(g, 0.0f, 1.0f); } void b(float b) { m_data[2] = std::clamp(b, 0.0f, 1.0f); } void a(float a) { m_data[3] = std::clamp(a, 0.0f, 1.0f); } - + void gamma_correct(); + static void gamma_correct(RGBA& color); + static float gamma_correct(float value); void set(unsigned int comp, float value) { assert(0 <= comp && comp <= 3); m_data[comp] = std::clamp(value, 0.0f, 1.0f); diff --git a/src/libslic3r/Format/OBJ.cpp b/src/libslic3r/Format/OBJ.cpp index 7f8d72751..d54a66f15 100644 --- a/src/libslic3r/Format/OBJ.cpp +++ b/src/libslic3r/Format/OBJ.cpp @@ -22,7 +22,7 @@ namespace Slic3r { -bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::string &message) +bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo &obj_info, std::string &message, bool gamma_correct) { if (meshptr == nullptr) return false; @@ -115,8 +115,13 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s size_t j = i * OBJ_VERTEX_LENGTH; its.vertices.emplace_back(data.coordinates[j], data.coordinates[j + 1], data.coordinates[j + 2]); if (data.has_vertex_color) { - RGBA color{std::clamp(data.coordinates[j + 3], 0.f, 1.f), std::clamp(data.coordinates[j + 4], 0.f, 1.f), std::clamp(data.coordinates[j + 5], 0.f, 1.f), - std::clamp(data.coordinates[j + 6], 0.f, 1.f)}; + RGBA color{data.coordinates[j + 3], data.coordinates[j + 4], data.coordinates[j + 5],data.coordinates[j + 6]}; + if (gamma_correct) { + ColorRGBA::gamma_correct(color); + } + for (int i = 0; i < color.size(); i++) { + color[i] = std::clamp(color[i], 0.f, 1.f); + } obj_info.vertex_colors.emplace_back(color); } } @@ -147,24 +152,18 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s its.indices.emplace_back(indices[0], indices[1], indices[2]); int face_index =its.indices.size() - 1; RGBA face_color; - auto set_face_color = [&uvs, &data, &mtl_data, &obj_info, &face_color](int face_index, const std::string mtl_name) { + auto set_face_color = [&uvs, &data, &mtl_data, &obj_info, &face_color, &gamma_correct](int face_index, const std::string mtl_name) { if (mtl_data.new_mtl_unmap.find(mtl_name) != mtl_data.new_mtl_unmap.end()) { - bool is_merge_ka_kd = true; - for (size_t n = 0; n < 3; n++) { - if (float(mtl_data.new_mtl_unmap[mtl_name]->Ka[n] + mtl_data.new_mtl_unmap[mtl_name]->Kd[n]) > 1.0) { - is_merge_ka_kd=false; - break; + for (size_t n = 0; n < 3; n++) {//0.1 is light ambient + float object_ka = 0.f; + if (mtl_data.new_mtl_unmap[mtl_name]->Ka[n] > 0.01 && mtl_data.new_mtl_unmap[mtl_name]->Ka[n] < 0.99) { + object_ka = mtl_data.new_mtl_unmap[mtl_name]->Ka[n] * 0.1; } + auto value = object_ka + float(mtl_data.new_mtl_unmap[mtl_name]->Kd[n]); + float temp = gamma_correct ? ColorRGBA::gamma_correct(value) : value; + face_color[n] = std::clamp(temp, 0.f, 1.f); } - for (size_t n = 0; n < 3; n++) { - if (is_merge_ka_kd) { - face_color[n] = std::clamp(float(mtl_data.new_mtl_unmap[mtl_name]->Ka[n] + mtl_data.new_mtl_unmap[mtl_name]->Kd[n]), 0.f, 1.f); - } - else { - face_color[n] = std::clamp(float(mtl_data.new_mtl_unmap[mtl_name]->Kd[n]), 0.f, 1.f); - } - } - face_color[3] = mtl_data.new_mtl_unmap[mtl_name]->Tr; // alpha + face_color[3] = gamma_correct ? ColorRGBA::gamma_correct(mtl_data.new_mtl_unmap[mtl_name]->Tr) : mtl_data.new_mtl_unmap[mtl_name]->Tr; // alpha if (mtl_data.new_mtl_unmap[mtl_name]->map_Kd.size() > 0) { auto png_name = mtl_data.new_mtl_unmap[mtl_name]->map_Kd; obj_info.has_uv_png = true; @@ -223,11 +222,11 @@ bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo& obj_info, std::s return true; } -bool load_obj(const char *path, Model *model, ObjInfo& obj_info, std::string &message, const char *object_name_in) +bool load_obj(const char *path, Model *model, ObjInfo& obj_info, std::string &message, const char *object_name_in,bool gamma_correct) { TriangleMesh mesh; - bool ret = load_obj(path, &mesh, obj_info, message); + bool ret = load_obj(path, &mesh, obj_info, message, gamma_correct); if (ret) { std::string object_name; diff --git a/src/libslic3r/Format/OBJ.hpp b/src/libslic3r/Format/OBJ.hpp index 48335f823..a1dd20681 100644 --- a/src/libslic3r/Format/OBJ.hpp +++ b/src/libslic3r/Format/OBJ.hpp @@ -40,8 +40,8 @@ struct ObjDialogInOut std::string lost_material_name{""}; }; 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); +extern bool load_obj(const char *path, TriangleMesh *mesh, ObjInfo &vertex_colors, std::string &message, bool gamma_correct =false); +extern bool load_obj(const char *path, Model *model, ObjInfo &vertex_colors, std::string &message, const char *object_name = nullptr, bool gamma_correct =false); extern bool store_obj(const char *path, TriangleMesh *mesh); extern bool store_obj(const char *path, ModelObject *model); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6ca7571e3..77e0a405d 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -257,12 +257,10 @@ Model Model::read_from_file(const std::string& config_substitutions = &temp_config_substitutions_context; //BBS: plate_data PlateDataPtrs temp_plate_data; - bool temp_is_xxx; Semver temp_version; if (plate_data == nullptr) plate_data = &temp_plate_data; - if (is_xxx == nullptr) - is_xxx = &temp_is_xxx; + if (file_version == nullptr) file_version = &temp_version; @@ -275,7 +273,7 @@ Model Model::read_from_file(const std::string& result = load_stl(input_file.c_str(), &model, nullptr, stlFn,256); else if (boost::algorithm::iends_with(input_file, ".obj")) { ObjInfo obj_info; - result = load_obj(input_file.c_str(), &model, obj_info, message); + result = load_obj(input_file.c_str(), &model, obj_info, message, nullptr, (is_xxx && *is_xxx) ? true : false); if (result){ ObjDialogInOut in_out; in_out.model = &model; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d461384e6..e42ba4771 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1525,7 +1525,7 @@ Sidebar::Sidebar(Plater *parent) p->m_panel_printer_content = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); p->m_panel_printer_content->SetBackgroundColour(wxColour(255, 255, 255)); - StateColor panel_bd_col(std::pair(wxColour(0x00AE42), StateColor::Pressed), + StateColor panel_bd_col(std::pair(wxColour(0x00AE42), StateColor::Pressed), std::pair(wxColour(0x00AE42), StateColor::Hovered), std::pair(wxColour(0xEEEEEE), StateColor::Normal)); @@ -5597,6 +5597,9 @@ std::vector Plater::priv::load_files(const std::vector& input_ return -1; }, linear, angle, split_compound); }else { + if (boost::algorithm::iends_with(path.string(), ".obj")) { + is_xxx = GUI::wxGetApp().app_config->get_bool("gamma_correct_in_import_obj"); + } model = Slic3r::Model:: read_from_file( path.string(), nullptr, nullptr, strategy, &plate_data, &project_presets, &is_xxx, &file_version, nullptr, [this, &dlg, real_filename, &progress_percent, &file_percent, INPUT_FILES_RATIO, total_files, i, &designer_model_id, &designer_country_code, &makerlab_region, &makerlab_name, &makerlab_id](int current, int total, bool &cancel, diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index a21bc0112..2a01b823a 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1211,6 +1211,9 @@ wxWindow* PreferencesDialog::create_general_page() auto item_import_single_svg_and_split = create_item_checkbox(_L("Import a single SVG and split it"), page, _L("Import a single SVG and then split it to several parts."), 50, "import_single_svg_and_split"); + auto item_gamma_correct_in_import_obj = create_item_checkbox(_L("Enable gamma correct in imported obj"), page, + _L("Perform gamma correction on color after importing the obj model."), 50, + "gamma_correct_in_import_obj"); auto enable_lod_settings = create_item_checkbox(_L("Improve rendering performance by lod"), page, _L("Improved rendering performance under the scene of multiple plates and many models."), 50, "enable_lod"); @@ -1314,7 +1317,7 @@ wxWindow* PreferencesDialog::create_general_page() sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_import_single_svg_and_split, 0, wxTOP, FromDIP(3)); - + sizer_page->Add(item_gamma_correct_in_import_obj, 0, wxTOP, FromDIP(3)); #ifdef __WIN32__ sizer_page->Add(prefer_to_use_dgpu, 0, wxTOP, FromDIP(3)); #endif // __WIN32__