Fixed conflicts after merge with master
This commit is contained in:
commit
e9d57c932a
18 changed files with 230 additions and 58 deletions
BIN
resources/icons/Pmetal_001.png
Normal file
BIN
resources/icons/Pmetal_001.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
|
@ -17,6 +17,9 @@ struct SlopeDetection
|
|||
uniform vec4 uniform_color;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
uniform sampler2D environment_tex;
|
||||
uniform bool use_environment_tex;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
|
@ -26,6 +29,7 @@ varying vec3 delta_box_min;
|
|||
varying vec3 delta_box_max;
|
||||
|
||||
varying float world_normal_z;
|
||||
varying vec3 eye_normal;
|
||||
|
||||
vec3 slope_color()
|
||||
{
|
||||
|
@ -40,5 +44,8 @@ void main()
|
|||
vec3 color = slope.actived ? slope_color() : uniform_color.rgb;
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
|
||||
if (use_environment_tex)
|
||||
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, uniform_color.a);
|
||||
else
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, uniform_color.a);
|
||||
}
|
||||
|
|
|
@ -51,22 +51,23 @@ varying vec3 delta_box_max;
|
|||
varying vec3 clipping_planes_dots;
|
||||
|
||||
varying float world_normal_z;
|
||||
varying vec3 eye_normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
eye_normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
|
||||
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
|
||||
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
|
||||
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
|
||||
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
|
||||
|
||||
// Perform the same lighting calculation for the 2nd light source (no specular applied).
|
||||
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
|
||||
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
|
||||
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
||||
|
||||
// compute deltas for out of print volume detection (world coordinates)
|
||||
|
|
|
@ -85,6 +85,8 @@ void PrintConfigDef::init_common_params()
|
|||
def->label = L("Max print height");
|
||||
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->max = 1200;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(200.0));
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
// Enable rendering of objects colored by facets' slope
|
||||
#define ENABLE_SLOPE_RENDERING (1 && ENABLE_2_3_0_ALPHA1)
|
||||
|
||||
// Enable rendering of objects using environment map
|
||||
#define ENABLE_ENVIRONMENT_MAP (1 && ENABLE_2_3_0_ALPHA1)
|
||||
|
||||
// Enable G-Code viewer
|
||||
#define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1)
|
||||
#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER)
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include "3DScene.hpp"
|
||||
#include "GLShader.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
#include "Plater.hpp"
|
||||
#include "AppConfig.hpp"
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
|
@ -664,6 +668,15 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||
shader->set_uniform("slope.z_range", m_slope.z_range);
|
||||
#endif // ENABLE_SLOPE_RENDERING
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();
|
||||
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1";
|
||||
shader->set_uniform("use_environment_tex", use_environment_texture);
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id));
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
glcheck();
|
||||
|
||||
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
volume.first->set_render_color();
|
||||
|
@ -680,6 +693,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||
#endif // ENABLE_SLOPE_RENDERING
|
||||
}
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
|
|
|
@ -93,6 +93,11 @@ void AppConfig::set_defaults()
|
|||
if (get("use_free_camera").empty())
|
||||
set("use_free_camera", "0");
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
if (get("use_environment_map").empty())
|
||||
set("use_environment_map", "0");
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
// Remove legacy window positions/sizes
|
||||
erase("", "main_frame_maximized");
|
||||
erase("", "main_frame_pos");
|
||||
|
|
|
@ -770,7 +770,6 @@ void GCodeViewer::render_toolpaths() const
|
|||
double zoom = camera.get_zoom();
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
std::array<int, 2> viewport_sizes = { viewport[2], viewport[3] };
|
||||
const std::pair<double, double>& camera_z_range = camera.get_z_range();
|
||||
|
||||
Transform3d inv_proj = camera.get_projection_matrix().inverse();
|
||||
|
||||
|
|
|
@ -1983,6 +1983,10 @@ void GLCanvas3D::render()
|
|||
return;
|
||||
}
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
wxGetApp().plater()->init_environment_texture();
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
const Size& cnv_size = get_canvas_size();
|
||||
// Probably due to different order of events on Linux/GTK2, when one switched from 3D scene
|
||||
// to preview, this was called before canvas had its final size. It reported zero width
|
||||
|
|
|
@ -715,16 +715,24 @@ void GUI_App::update_ui_from_settings()
|
|||
void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_maximized)
|
||||
{
|
||||
const std::string name = into_u8(window->GetName());
|
||||
wxTopLevelWindow* settings_dlg = dynamic_cast<MainFrame*>(window)->m_settings_dialog;
|
||||
const std::string settings_dlg_name = "settings_dialog";
|
||||
|
||||
window->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent &event) {
|
||||
window_pos_save(window, name);
|
||||
if (settings_dlg)
|
||||
window_pos_save(settings_dlg, settings_dlg_name);
|
||||
event.Skip();
|
||||
});
|
||||
|
||||
window_pos_restore(window, name, default_maximized);
|
||||
if (settings_dlg)
|
||||
window_pos_restore(settings_dlg, settings_dlg_name, default_maximized);
|
||||
|
||||
on_window_geometry(window, [=]() {
|
||||
window_pos_sanitize(window);
|
||||
if (settings_dlg)
|
||||
window_pos_sanitize(settings_dlg);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2390,40 +2390,120 @@ void ObjectList::merge(bool to_multipart_object)
|
|||
// merge selected objects to the multipart object
|
||||
if (to_multipart_object)
|
||||
{
|
||||
auto get_object_idxs = [this](std::vector<int>& obj_idxs, wxDataViewItemArray& sels)
|
||||
{
|
||||
// check selections and split instances to the separated objects...
|
||||
bool instance_selection = false;
|
||||
for (wxDataViewItem item : sels)
|
||||
if (m_objects_model->GetItemType(item) & itInstance) {
|
||||
instance_selection = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!instance_selection)
|
||||
{
|
||||
for (wxDataViewItem item : sels) {
|
||||
assert(m_objects_model->GetItemType(item) & itObject);
|
||||
obj_idxs.emplace_back(m_objects_model->GetIdByItem(item));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// map of obj_idx -> set of selected instance_idxs
|
||||
std::map<int, std::set<int>> sel_map;
|
||||
std::set<int> empty_set;
|
||||
for (wxDataViewItem item : sels) {
|
||||
if (m_objects_model->GetItemType(item) & itObject)
|
||||
{
|
||||
int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
int inst_cnt = (*m_objects)[obj_idx]->instances.size();
|
||||
if (inst_cnt == 1)
|
||||
sel_map.emplace(obj_idx, empty_set);
|
||||
else
|
||||
for (int i = 0; i < inst_cnt; i++)
|
||||
sel_map[obj_idx].emplace(i);
|
||||
continue;
|
||||
}
|
||||
int obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
||||
sel_map[obj_idx].emplace(m_objects_model->GetInstanceIdByItem(item));
|
||||
}
|
||||
|
||||
// all objects, created from the instances will be added to the end of list
|
||||
int new_objects_cnt = 0; // count of this new objects
|
||||
// std::vector<int> obj_idxs;
|
||||
|
||||
for (auto map_item : sel_map)
|
||||
{
|
||||
int obj_idx = map_item.first;
|
||||
// object with just 1 instance
|
||||
if (map_item.second.empty()) {
|
||||
obj_idxs.emplace_back(obj_idx);
|
||||
continue;
|
||||
}
|
||||
|
||||
// object with selected all instances
|
||||
if ((*m_objects)[map_item.first]->instances.size() == map_item.second.size()) {
|
||||
instances_to_separated_objects(obj_idx);
|
||||
// first instance stay on its own place and another all add to the end of list :
|
||||
obj_idxs.emplace_back(obj_idx);
|
||||
new_objects_cnt += map_item.second.size() - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// object with selected some of instances
|
||||
instances_to_separated_object(obj_idx, map_item.second);
|
||||
|
||||
if (map_item.second.size() == 1)
|
||||
new_objects_cnt += 1;
|
||||
else {// we should split to separate instances last object
|
||||
instances_to_separated_objects(m_objects->size() - 1);
|
||||
// all instances will stay at the end of list :
|
||||
new_objects_cnt += map_item.second.size();
|
||||
}
|
||||
}
|
||||
|
||||
// all instatnces are extracted to the separate objects and should be selected
|
||||
m_prevent_list_events = true;
|
||||
sels.Clear();
|
||||
for (int obj_idx : obj_idxs)
|
||||
sels.Add(m_objects_model->GetItemById(obj_idx));
|
||||
int obj_cnt = m_objects->size();
|
||||
for (int obj_idx = obj_cnt - new_objects_cnt; obj_idx < obj_cnt; obj_idx++) {
|
||||
sels.Add(m_objects_model->GetItemById(obj_idx));
|
||||
obj_idxs.emplace_back(obj_idx);
|
||||
}
|
||||
UnselectAll();
|
||||
SetSelections(sels);
|
||||
assert(!sels.IsEmpty());
|
||||
m_prevent_list_events = false;
|
||||
};
|
||||
|
||||
std::vector<int> obj_idxs;
|
||||
wxDataViewItemArray sels;
|
||||
GetSelections(sels);
|
||||
assert(!sels.IsEmpty());
|
||||
|
||||
for (wxDataViewItem item : sels) {
|
||||
const ItemType type = m_objects_model->GetItemType(item);
|
||||
assert(type & (itObject/* | itInstance*/));
|
||||
obj_idxs.emplace_back(type & itObject ? m_objects_model->GetIdByItem(item) :
|
||||
m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)));
|
||||
}
|
||||
std::sort(obj_idxs.begin(), obj_idxs.end());
|
||||
obj_idxs.erase(std::unique(obj_idxs.begin(), obj_idxs.end()), obj_idxs.end());
|
||||
|
||||
if (obj_idxs.size() <= 1)
|
||||
return;
|
||||
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Merge"));
|
||||
|
||||
get_object_idxs(obj_idxs, sels);
|
||||
|
||||
// resulted objects merge to the one
|
||||
Model* model = (*m_objects)[0]->get_model();
|
||||
ModelObject* new_object = model->add_object();
|
||||
new_object->name = _u8L("Merged");
|
||||
DynamicPrintConfig* new_config = &new_object->config;
|
||||
DynamicPrintConfig* config = &new_object->config;
|
||||
|
||||
const Vec3d& main_offset = (*m_objects)[0]->instances[0]->get_offset();
|
||||
int frst_obj_idx = obj_idxs.front();
|
||||
const Vec3d& main_offset = (*m_objects)[frst_obj_idx]->instances[0]->get_offset();
|
||||
|
||||
for (int obj_idx : obj_idxs)
|
||||
{
|
||||
ModelObject* object = (*m_objects)[obj_idx];
|
||||
Vec3d offset = object->instances[0]->get_offset();
|
||||
|
||||
if (object->id() == (*m_objects)[0]->id())
|
||||
if (object->id() == (*m_objects)[frst_obj_idx]->id())
|
||||
new_object->add_instance(*object->instances[0]);
|
||||
auto new_opt_keys = new_config->keys();
|
||||
auto new_opt_keys = config->keys();
|
||||
|
||||
const DynamicPrintConfig& from_config = object->config;
|
||||
auto opt_keys = from_config.keys();
|
||||
|
@ -2437,7 +2517,7 @@ void ObjectList::merge(bool to_multipart_object)
|
|||
// get it from default config values
|
||||
option = DynamicPrintConfig::new_from_defaults_keys({ opt_key })->option(opt_key);
|
||||
}
|
||||
new_config->set_key_value(opt_key, option->clone());
|
||||
config->set_key_value(opt_key, option->clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2461,8 +2541,11 @@ void ObjectList::merge(bool to_multipart_object)
|
|||
}
|
||||
// remove selected objects
|
||||
remove();
|
||||
|
||||
// Add new object(merged) to the object_list
|
||||
add_object_to_list(m_objects->size() - 1);
|
||||
select_item(m_objects_model->GetItemById(m_objects->size() - 1));
|
||||
update_selections_on_canvas();
|
||||
}
|
||||
// merge all parts to the one single object
|
||||
// all part's settings will be lost
|
||||
|
@ -2613,6 +2696,9 @@ bool ObjectList::can_split_instances()
|
|||
|
||||
bool ObjectList::can_merge_to_multipart_object() const
|
||||
{
|
||||
if (printer_technology() == ptSLA)
|
||||
return false;
|
||||
|
||||
wxDataViewItemArray sels;
|
||||
GetSelections(sels);
|
||||
if (sels.IsEmpty())
|
||||
|
@ -2620,7 +2706,7 @@ bool ObjectList::can_merge_to_multipart_object() const
|
|||
|
||||
// should be selected just objects
|
||||
for (wxDataViewItem item : sels)
|
||||
if (!(m_objects_model->GetItemType(item) & (itObject/* | itInstance*/)))
|
||||
if (!(m_objects_model->GetItemType(item) & (itObject | itInstance)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -365,13 +365,23 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
}
|
||||
}
|
||||
|
||||
bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None);
|
||||
|
||||
// The mouse button click detection is enabled when there is a valid hit
|
||||
// or when the user clicks the clipping plane. Missing the object entirely
|
||||
// shall not capture the mouse.
|
||||
if (closest_hit_mesh_id != -1 || clipped_mesh_was_hit) {
|
||||
if (m_button_down == Button::None)
|
||||
m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right);
|
||||
}
|
||||
|
||||
if (closest_hit_mesh_id == -1) {
|
||||
// In case we have no valid hit, we can return. The event will
|
||||
// be stopped in following two cases:
|
||||
// 1. clicking the clipping plane
|
||||
// 2. dragging while painting (to prevent scene rotations and moving the object)
|
||||
return clipped_mesh_was_hit
|
||||
|| (action == SLAGizmoEventType::Dragging && m_button_down != Button::None);
|
||||
|| dragging_while_painting;
|
||||
}
|
||||
|
||||
// Now propagate the hits
|
||||
|
@ -472,10 +482,6 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_button_down == Button::None)
|
||||
m_button_down = ((action == SLAGizmoEventType::LeftDown) ? Button::Left : Button::Right);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -204,29 +204,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
|||
event.Skip();
|
||||
});
|
||||
|
||||
/*
|
||||
Bind(wxEVT_SYS_COLOUR_CHANGED, [this](wxSysColourChangedEvent& event)
|
||||
{
|
||||
bool recreate_gui = false;
|
||||
{
|
||||
// the dialog needs to be destroyed before the call to recreate_gui()
|
||||
// or sometimes the application crashes into wxDialogBase() destructor
|
||||
// so we put it into an inner scope
|
||||
wxMessageDialog dialog(nullptr,
|
||||
_L("System color mode was changed. "
|
||||
"It is possible to update the Slicer in respect to the system mode.") + "\n" +
|
||||
_L("You will lose content of the plater.") + "\n\n" +
|
||||
_L("Do you want to proceed?"),
|
||||
wxString(SLIC3R_APP_NAME) + " - " + _L("Switching system color mode"),
|
||||
wxICON_QUESTION | wxOK | wxCANCEL);
|
||||
recreate_gui = dialog.ShowModal() == wxID_OK;
|
||||
}
|
||||
if (recreate_gui)
|
||||
wxGetApp().recreate_GUI(_L("Changing of an application in respect to the system mode") + dots);
|
||||
event.Skip();
|
||||
});
|
||||
*/
|
||||
|
||||
wxGetApp().persist_window_geometry(this, true);
|
||||
|
||||
update_ui_from_settings(); // FIXME (?)
|
||||
|
@ -350,7 +327,8 @@ void MainFrame::init_tabpanel()
|
|||
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
|
||||
auto panel = m_tabpanel->GetCurrentPage();
|
||||
|
||||
if (panel == nullptr)
|
||||
// There shouldn't be a case, when we try to select a tab, which doesn't support a printer technology
|
||||
if (panel == nullptr || !static_cast<Tab*>(panel)->supports_printer_technology(m_plater->printer_technology()))
|
||||
return;
|
||||
|
||||
auto& tabs_list = wxGetApp().tabs_list;
|
||||
|
|
|
@ -1589,6 +1589,9 @@ struct Plater::priv
|
|||
Sidebar *sidebar;
|
||||
Bed3D bed;
|
||||
Camera camera;
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
GLTexture environment_texture;
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
Mouse3DController mouse3d_controller;
|
||||
View3D* view3D;
|
||||
GLToolbar view_toolbar;
|
||||
|
@ -2101,7 +2104,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
});
|
||||
wxGetApp().other_instance_message_handler()->init(this->q);
|
||||
|
||||
|
||||
// collapse sidebar according to saved value
|
||||
bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
|
||||
sidebar->collapse(is_collapsed);
|
||||
|
@ -5570,6 +5572,19 @@ Camera& Plater::get_camera()
|
|||
return p->camera;
|
||||
}
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
void Plater::init_environment_texture()
|
||||
{
|
||||
if (p->environment_texture.get_id() == 0)
|
||||
p->environment_texture.load_from_file(resources_dir() + "/icons/Pmetal_001.png", false, GLTexture::SingleThreaded, false);
|
||||
}
|
||||
|
||||
unsigned int Plater::get_environment_texture_id() const
|
||||
{
|
||||
return p->environment_texture.get_id();
|
||||
}
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
const Bed3D& Plater::get_bed() const
|
||||
{
|
||||
return p->bed;
|
||||
|
|
|
@ -319,6 +319,11 @@ public:
|
|||
const Camera& get_camera() const;
|
||||
Camera& get_camera();
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
void init_environment_texture();
|
||||
unsigned int get_environment_texture_id() const;
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
const Bed3D& get_bed() const;
|
||||
Bed3D& get_bed();
|
||||
|
||||
|
|
|
@ -180,10 +180,28 @@ void PreferencesDialog::build()
|
|||
|
||||
create_settings_mode_widget();
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
m_optgroup_render = std::make_shared<ConfigOptionsGroup>(this, _(L("Render")));
|
||||
m_optgroup_render->label_width = 40;
|
||||
m_optgroup_render->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
|
||||
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
|
||||
};
|
||||
|
||||
def.label = L("Use environment map");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If enabled, renders object using the environment map.");
|
||||
def.set_default_value(new ConfigOptionBool{ app_config->get("use_environment_map") == "1" });
|
||||
option = Option(def, "use_environment_map");
|
||||
m_optgroup_render->append_single_option_line(option);
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(m_optgroup_general->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||
sizer->Add(m_optgroup_camera->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||
sizer->Add(m_optgroup_gui->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
sizer->Add(m_optgroup_render->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
SetFont(wxGetApp().normal_font());
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ class PreferencesDialog : public DPIDialog
|
|||
std::shared_ptr<ConfigOptionsGroup> m_optgroup_general;
|
||||
std::shared_ptr<ConfigOptionsGroup> m_optgroup_camera;
|
||||
std::shared_ptr<ConfigOptionsGroup> m_optgroup_gui;
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
std::shared_ptr<ConfigOptionsGroup> m_optgroup_render;
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
wxSizer* m_icon_size_sizer;
|
||||
wxRadioBox* m_layout_mode_box;
|
||||
bool isOSX {false};
|
||||
|
|
|
@ -28,6 +28,12 @@ using GUI::into_u8;
|
|||
|
||||
namespace Search {
|
||||
|
||||
// Does our wxWidgets version support markup?
|
||||
// https://github.com/prusa3d/PrusaSlicer/issues/4282#issuecomment-634676371
|
||||
#if wxUSE_MARKUP && wxCHECK_VERSION(3, 1, 1)
|
||||
#define SEARCH_SUPPORTS_MARKUP
|
||||
#endif
|
||||
|
||||
static const std::vector<std::wstring>& NameByType()
|
||||
{
|
||||
static std::vector<std::wstring> data;
|
||||
|
@ -271,8 +277,14 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
|
|||
label += L" [" + std::to_wstring(score) + L"]";// add score value
|
||||
std::string label_u8 = into_u8(label);
|
||||
std::string label_plain = label_u8;
|
||||
|
||||
#ifdef SEARCH_SUPPORTS_MARKUP
|
||||
boost::replace_all(label_plain, std::string(1, char(ImGui::ColorMarkerStart)), "<b>");
|
||||
boost::replace_all(label_plain, std::string(1, char(ImGui::ColorMarkerEnd)), "</b>");
|
||||
#else
|
||||
boost::erase_all(label_plain, std::string(1, char(ImGui::ColorMarkerStart)));
|
||||
boost::erase_all(label_plain, std::string(1, char(ImGui::ColorMarkerEnd)));
|
||||
#endif
|
||||
found.emplace_back(FoundOption{ label_plain, label_u8, boost::nowide::narrow(get_tooltip(opt)), i, score });
|
||||
}
|
||||
}
|
||||
|
@ -443,9 +455,11 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
|
|||
search_list->AppendBitmapColumn("", SearchListModel::colIcon);
|
||||
|
||||
wxDataViewTextRenderer* const markupRenderer = new wxDataViewTextRenderer();
|
||||
#if wxUSE_MARKUP
|
||||
|
||||
#ifdef SEARCH_SUPPORTS_MARKUP
|
||||
markupRenderer->EnableMarkup();
|
||||
#endif // wxUSE_MARKUP
|
||||
#endif
|
||||
|
||||
search_list->AppendColumn(new wxDataViewColumn("", markupRenderer, SearchListModel::colMarkedText, wxCOL_WIDTH_AUTOSIZE, wxALIGN_LEFT));
|
||||
|
||||
search_list->GetColumn(SearchListModel::colIcon )->SetWidth(3 * em_unit());
|
||||
|
|
Loading…
Reference in a new issue