Fixed conflicts after merge with master

This commit is contained in:
enricoturri1966 2020-05-28 15:50:21 +02:00
commit e9d57c932a
18 changed files with 230 additions and 58 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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;
boost::replace_all(label_plain, std::string(1, char(ImGui::ColorMarkerStart)), "<b>");
boost::replace_all(label_plain, std::string(1, char(ImGui::ColorMarkerEnd)), "</b>");
#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());