ENH:add "gamma_correct_in_import_obj" function

jira: none
Change-Id: Ia16d1c996f02333745222eb2144d01a44d101754
This commit is contained in:
zhou.xu 2025-03-13 10:20:13 +08:00 committed by lane.wei
parent 1f41a3da7a
commit 9d93dd7d98
8 changed files with 57 additions and 29 deletions

View File

@ -183,6 +183,8 @@ void AppConfig::set_defaults()
set_bool("show_shells_in_preview", true); set_bool("show_shells_in_preview", true);
if (get("enable_lod").empty()) if (get("enable_lod").empty())
set_bool("enable_lod", true); 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()) if (get("enable_opengl_multi_instance").empty())
set_bool("enable_opengl_multi_instance", true); set_bool("enable_opengl_multi_instance", true);
if (get("import_single_svg_and_split").empty()) if (get("import_single_svg_and_split").empty())

View File

@ -235,6 +235,27 @@ ColorRGBA ColorRGBA::operator * (float value) const
return ret; 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; } ColorRGB operator * (float value, const ColorRGB& other) { return other * value; }
ColorRGBA operator * (float value, const ColorRGBA& other) { return other * value; } ColorRGBA operator * (float value, const ColorRGBA& other) { return other * value; }

View File

@ -107,7 +107,9 @@ public:
void g(float g) { m_data[1] = std::clamp(g, 0.0f, 1.0f); } 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 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 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) { void set(unsigned int comp, float value) {
assert(0 <= comp && comp <= 3); assert(0 <= comp && comp <= 3);
m_data[comp] = std::clamp(value, 0.0f, 1.0f); m_data[comp] = std::clamp(value, 0.0f, 1.0f);

View File

@ -22,7 +22,7 @@
namespace Slic3r { 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) if (meshptr == nullptr)
return false; 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; size_t j = i * OBJ_VERTEX_LENGTH;
its.vertices.emplace_back(data.coordinates[j], data.coordinates[j + 1], data.coordinates[j + 2]); its.vertices.emplace_back(data.coordinates[j], data.coordinates[j + 1], data.coordinates[j + 2]);
if (data.has_vertex_color) { 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), RGBA color{data.coordinates[j + 3], data.coordinates[j + 4], data.coordinates[j + 5],data.coordinates[j + 6]};
std::clamp(data.coordinates[j + 6], 0.f, 1.f)}; 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); 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]); its.indices.emplace_back(indices[0], indices[1], indices[2]);
int face_index =its.indices.size() - 1; int face_index =its.indices.size() - 1;
RGBA face_color; 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()) { 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++) {//0.1 is light ambient
for (size_t n = 0; n < 3; n++) { float object_ka = 0.f;
if (float(mtl_data.new_mtl_unmap[mtl_name]->Ka[n] + mtl_data.new_mtl_unmap[mtl_name]->Kd[n]) > 1.0) { if (mtl_data.new_mtl_unmap[mtl_name]->Ka[n] > 0.01 && mtl_data.new_mtl_unmap[mtl_name]->Ka[n] < 0.99) {
is_merge_ka_kd=false; object_ka = mtl_data.new_mtl_unmap[mtl_name]->Ka[n] * 0.1;
break;
} }
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++) { 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 (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
if (mtl_data.new_mtl_unmap[mtl_name]->map_Kd.size() > 0) { if (mtl_data.new_mtl_unmap[mtl_name]->map_Kd.size() > 0) {
auto png_name = mtl_data.new_mtl_unmap[mtl_name]->map_Kd; auto png_name = mtl_data.new_mtl_unmap[mtl_name]->map_Kd;
obj_info.has_uv_png = true; 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; 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; TriangleMesh mesh;
bool ret = load_obj(path, &mesh, obj_info, message); bool ret = load_obj(path, &mesh, obj_info, message, gamma_correct);
if (ret) { if (ret) {
std::string object_name; std::string object_name;

View File

@ -40,8 +40,8 @@ struct ObjDialogInOut
std::string lost_material_name{""}; std::string lost_material_name{""};
}; };
typedef std::function<void(ObjDialogInOut &in_out)> ObjImportColorFn; typedef std::function<void(ObjDialogInOut &in_out)> ObjImportColorFn;
extern bool load_obj(const char *path, TriangleMesh *mesh, ObjInfo &vertex_colors, std::string &message); 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); 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, TriangleMesh *mesh);
extern bool store_obj(const char *path, ModelObject *model); extern bool store_obj(const char *path, ModelObject *model);

View File

@ -257,12 +257,10 @@ Model Model::read_from_file(const std::string&
config_substitutions = &temp_config_substitutions_context; config_substitutions = &temp_config_substitutions_context;
//BBS: plate_data //BBS: plate_data
PlateDataPtrs temp_plate_data; PlateDataPtrs temp_plate_data;
bool temp_is_xxx;
Semver temp_version; Semver temp_version;
if (plate_data == nullptr) if (plate_data == nullptr)
plate_data = &temp_plate_data; plate_data = &temp_plate_data;
if (is_xxx == nullptr)
is_xxx = &temp_is_xxx;
if (file_version == nullptr) if (file_version == nullptr)
file_version = &temp_version; 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); result = load_stl(input_file.c_str(), &model, nullptr, stlFn,256);
else if (boost::algorithm::iends_with(input_file, ".obj")) { else if (boost::algorithm::iends_with(input_file, ".obj")) {
ObjInfo obj_info; 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){ if (result){
ObjDialogInOut in_out; ObjDialogInOut in_out;
in_out.model = &model; in_out.model = &model;

View File

@ -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 = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
p->m_panel_printer_content->SetBackgroundColour(wxColour(255, 255, 255)); p->m_panel_printer_content->SetBackgroundColour(wxColour(255, 255, 255));
StateColor panel_bd_col(std::pair<wxColour, int>(wxColour(0x00AE42), StateColor::Pressed), StateColor panel_bd_col(std::pair<wxColour, int>(wxColour(0x00AE42), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(0x00AE42), StateColor::Hovered), std::pair<wxColour, int>(wxColour(0x00AE42), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0xEEEEEE), StateColor::Normal)); std::pair<wxColour, int>(wxColour(0xEEEEEE), StateColor::Normal));
@ -5597,6 +5597,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
return -1; return -1;
}, linear, angle, split_compound); }, linear, angle, split_compound);
}else { }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( model = Slic3r::Model:: read_from_file(
path.string(), nullptr, nullptr, strategy, &plate_data, &project_presets, &is_xxx, &file_version, nullptr, 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, [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,

View File

@ -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, 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, _L("Import a single SVG and then split it to several parts."), 50,
"import_single_svg_and_split"); "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, 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, _L("Improved rendering performance under the scene of multiple plates and many models."), 50,
"enable_lod"); "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_mouse_zoom_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_show_shells_in_preview_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_import_single_svg_and_split, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_gamma_correct_in_import_obj, 0, wxTOP, FromDIP(3));
#ifdef __WIN32__ #ifdef __WIN32__
sizer_page->Add(prefer_to_use_dgpu, 0, wxTOP, FromDIP(3)); sizer_page->Add(prefer_to_use_dgpu, 0, wxTOP, FromDIP(3));
#endif // __WIN32__ #endif // __WIN32__