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);
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())

View File

@ -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; }

View File

@ -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);

View File

@ -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;

View File

@ -40,8 +40,8 @@ struct ObjDialogInOut
std::string lost_material_name{""};
};
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, 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);

View File

@ -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;

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->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(0xEEEEEE), StateColor::Normal));
@ -5597,6 +5597,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& 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,

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,
_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__