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 vec4 uniform_color;
|
||||||
uniform SlopeDetection slope;
|
uniform SlopeDetection slope;
|
||||||
|
|
||||||
|
uniform sampler2D environment_tex;
|
||||||
|
uniform bool use_environment_tex;
|
||||||
|
|
||||||
varying vec3 clipping_planes_dots;
|
varying vec3 clipping_planes_dots;
|
||||||
|
|
||||||
// x = tainted, y = specular;
|
// x = tainted, y = specular;
|
||||||
|
@ -26,6 +29,7 @@ varying vec3 delta_box_min;
|
||||||
varying vec3 delta_box_max;
|
varying vec3 delta_box_max;
|
||||||
|
|
||||||
varying float world_normal_z;
|
varying float world_normal_z;
|
||||||
|
varying vec3 eye_normal;
|
||||||
|
|
||||||
vec3 slope_color()
|
vec3 slope_color()
|
||||||
{
|
{
|
||||||
|
@ -40,5 +44,8 @@ void main()
|
||||||
vec3 color = slope.actived ? slope_color() : uniform_color.rgb;
|
vec3 color = slope.actived ? slope_color() : uniform_color.rgb;
|
||||||
// if the fragment is outside the print volume -> use darker color
|
// 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;
|
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 vec3 clipping_planes_dots;
|
||||||
|
|
||||||
varying float world_normal_z;
|
varying float world_normal_z;
|
||||||
|
varying vec3 eye_normal;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// First transform the normal into camera space and normalize the result.
|
// 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.
|
// 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.
|
// 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;
|
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||||
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
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).
|
// 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;
|
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
||||||
|
|
||||||
// compute deltas for out of print volume detection (world coordinates)
|
// 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->label = L("Max print height");
|
||||||
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
|
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
|
def->min = 0;
|
||||||
|
def->max = 1200;
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloat(200.0));
|
def->set_default_value(new ConfigOptionFloat(200.0));
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
// Enable rendering of objects colored by facets' slope
|
// Enable rendering of objects colored by facets' slope
|
||||||
#define ENABLE_SLOPE_RENDERING (1 && ENABLE_2_3_0_ALPHA1)
|
#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
|
// Enable G-Code viewer
|
||||||
#define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1)
|
#define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1)
|
||||||
#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER)
|
#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER)
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
#include "GLShader.hpp"
|
#include "GLShader.hpp"
|
||||||
#include "GUI_App.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/ExtrusionEntity.hpp"
|
||||||
#include "libslic3r/ExtrusionEntityCollection.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);
|
shader->set_uniform("slope.z_range", m_slope.z_range);
|
||||||
#endif // ENABLE_SLOPE_RENDERING
|
#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);
|
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
||||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
volume.first->set_render_color();
|
volume.first->set_render_color();
|
||||||
|
@ -680,6 +693,11 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
#endif // ENABLE_SLOPE_RENDERING
|
#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_ARRAY_BUFFER, 0));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,11 @@ void AppConfig::set_defaults()
|
||||||
if (get("use_free_camera").empty())
|
if (get("use_free_camera").empty())
|
||||||
set("use_free_camera", "0");
|
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
|
// Remove legacy window positions/sizes
|
||||||
erase("", "main_frame_maximized");
|
erase("", "main_frame_maximized");
|
||||||
erase("", "main_frame_pos");
|
erase("", "main_frame_pos");
|
||||||
|
|
|
@ -770,7 +770,6 @@ void GCodeViewer::render_toolpaths() const
|
||||||
double zoom = camera.get_zoom();
|
double zoom = camera.get_zoom();
|
||||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||||
std::array<int, 2> viewport_sizes = { viewport[2], viewport[3] };
|
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();
|
Transform3d inv_proj = camera.get_projection_matrix().inverse();
|
||||||
|
|
||||||
|
|
|
@ -1983,6 +1983,10 @@ void GLCanvas3D::render()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_ENVIRONMENT_MAP
|
||||||
|
wxGetApp().plater()->init_environment_texture();
|
||||||
|
#endif // ENABLE_ENVIRONMENT_MAP
|
||||||
|
|
||||||
const Size& cnv_size = get_canvas_size();
|
const Size& cnv_size = get_canvas_size();
|
||||||
// Probably due to different order of events on Linux/GTK2, when one switched from 3D scene
|
// 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
|
// 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)
|
void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_maximized)
|
||||||
{
|
{
|
||||||
const std::string name = into_u8(window->GetName());
|
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->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent &event) {
|
||||||
window_pos_save(window, name);
|
window_pos_save(window, name);
|
||||||
|
if (settings_dlg)
|
||||||
|
window_pos_save(settings_dlg, settings_dlg_name);
|
||||||
event.Skip();
|
event.Skip();
|
||||||
});
|
});
|
||||||
|
|
||||||
window_pos_restore(window, name, default_maximized);
|
window_pos_restore(window, name, default_maximized);
|
||||||
|
if (settings_dlg)
|
||||||
|
window_pos_restore(settings_dlg, settings_dlg_name, default_maximized);
|
||||||
|
|
||||||
on_window_geometry(window, [=]() {
|
on_window_geometry(window, [=]() {
|
||||||
window_pos_sanitize(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
|
// merge selected objects to the multipart object
|
||||||
if (to_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;
|
std::vector<int> obj_idxs;
|
||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
GetSelections(sels);
|
GetSelections(sels);
|
||||||
assert(!sels.IsEmpty());
|
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"));
|
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();
|
Model* model = (*m_objects)[0]->get_model();
|
||||||
ModelObject* new_object = model->add_object();
|
ModelObject* new_object = model->add_object();
|
||||||
new_object->name = _u8L("Merged");
|
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)
|
for (int obj_idx : obj_idxs)
|
||||||
{
|
{
|
||||||
ModelObject* object = (*m_objects)[obj_idx];
|
ModelObject* object = (*m_objects)[obj_idx];
|
||||||
Vec3d offset = object->instances[0]->get_offset();
|
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]);
|
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;
|
const DynamicPrintConfig& from_config = object->config;
|
||||||
auto opt_keys = from_config.keys();
|
auto opt_keys = from_config.keys();
|
||||||
|
@ -2437,7 +2517,7 @@ void ObjectList::merge(bool to_multipart_object)
|
||||||
// get it from default config values
|
// get it from default config values
|
||||||
option = DynamicPrintConfig::new_from_defaults_keys({ opt_key })->option(opt_key);
|
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 selected objects
|
||||||
remove();
|
remove();
|
||||||
|
|
||||||
// Add new object(merged) to the object_list
|
// Add new object(merged) to the object_list
|
||||||
add_object_to_list(m_objects->size() - 1);
|
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
|
// merge all parts to the one single object
|
||||||
// all part's settings will be lost
|
// all part's settings will be lost
|
||||||
|
@ -2613,6 +2696,9 @@ bool ObjectList::can_split_instances()
|
||||||
|
|
||||||
bool ObjectList::can_merge_to_multipart_object() const
|
bool ObjectList::can_merge_to_multipart_object() const
|
||||||
{
|
{
|
||||||
|
if (printer_technology() == ptSLA)
|
||||||
|
return false;
|
||||||
|
|
||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
GetSelections(sels);
|
GetSelections(sels);
|
||||||
if (sels.IsEmpty())
|
if (sels.IsEmpty())
|
||||||
|
@ -2620,7 +2706,7 @@ bool ObjectList::can_merge_to_multipart_object() const
|
||||||
|
|
||||||
// should be selected just objects
|
// should be selected just objects
|
||||||
for (wxDataViewItem item : sels)
|
for (wxDataViewItem item : sels)
|
||||||
if (!(m_objects_model->GetItemType(item) & (itObject/* | itInstance*/)))
|
if (!(m_objects_model->GetItemType(item) & (itObject | itInstance)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
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) {
|
if (closest_hit_mesh_id == -1) {
|
||||||
// In case we have no valid hit, we can return. The event will
|
// In case we have no valid hit, we can return. The event will
|
||||||
// be stopped in following two cases:
|
// be stopped in following two cases:
|
||||||
// 1. clicking the clipping plane
|
// 1. clicking the clipping plane
|
||||||
// 2. dragging while painting (to prevent scene rotations and moving the object)
|
// 2. dragging while painting (to prevent scene rotations and moving the object)
|
||||||
return clipped_mesh_was_hit
|
return clipped_mesh_was_hit
|
||||||
|| (action == SLAGizmoEventType::Dragging && m_button_down != Button::None);
|
|| dragging_while_painting;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now propagate the hits
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,29 +204,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||||
event.Skip();
|
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);
|
wxGetApp().persist_window_geometry(this, true);
|
||||||
|
|
||||||
update_ui_from_settings(); // FIXME (?)
|
update_ui_from_settings(); // FIXME (?)
|
||||||
|
@ -350,7 +327,8 @@ void MainFrame::init_tabpanel()
|
||||||
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
|
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
|
||||||
auto panel = m_tabpanel->GetCurrentPage();
|
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;
|
return;
|
||||||
|
|
||||||
auto& tabs_list = wxGetApp().tabs_list;
|
auto& tabs_list = wxGetApp().tabs_list;
|
||||||
|
|
|
@ -1589,6 +1589,9 @@ struct Plater::priv
|
||||||
Sidebar *sidebar;
|
Sidebar *sidebar;
|
||||||
Bed3D bed;
|
Bed3D bed;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
#if ENABLE_ENVIRONMENT_MAP
|
||||||
|
GLTexture environment_texture;
|
||||||
|
#endif // ENABLE_ENVIRONMENT_MAP
|
||||||
Mouse3DController mouse3d_controller;
|
Mouse3DController mouse3d_controller;
|
||||||
View3D* view3D;
|
View3D* view3D;
|
||||||
GLToolbar view_toolbar;
|
GLToolbar view_toolbar;
|
||||||
|
@ -2101,7 +2104,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||||
});
|
});
|
||||||
wxGetApp().other_instance_message_handler()->init(this->q);
|
wxGetApp().other_instance_message_handler()->init(this->q);
|
||||||
|
|
||||||
|
|
||||||
// collapse sidebar according to saved value
|
// collapse sidebar according to saved value
|
||||||
bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
|
bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
|
||||||
sidebar->collapse(is_collapsed);
|
sidebar->collapse(is_collapsed);
|
||||||
|
@ -5570,6 +5572,19 @@ Camera& Plater::get_camera()
|
||||||
return p->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
|
const Bed3D& Plater::get_bed() const
|
||||||
{
|
{
|
||||||
return p->bed;
|
return p->bed;
|
||||||
|
|
|
@ -319,6 +319,11 @@ public:
|
||||||
const Camera& get_camera() const;
|
const Camera& get_camera() const;
|
||||||
Camera& get_camera();
|
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;
|
const Bed3D& get_bed() const;
|
||||||
Bed3D& get_bed();
|
Bed3D& get_bed();
|
||||||
|
|
||||||
|
|
|
@ -180,10 +180,28 @@ void PreferencesDialog::build()
|
||||||
|
|
||||||
create_settings_mode_widget();
|
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);
|
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
sizer->Add(m_optgroup_general->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
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_camera->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
|
||||||
sizer->Add(m_optgroup_gui->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());
|
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_general;
|
||||||
std::shared_ptr<ConfigOptionsGroup> m_optgroup_camera;
|
std::shared_ptr<ConfigOptionsGroup> m_optgroup_camera;
|
||||||
std::shared_ptr<ConfigOptionsGroup> m_optgroup_gui;
|
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;
|
wxSizer* m_icon_size_sizer;
|
||||||
wxRadioBox* m_layout_mode_box;
|
wxRadioBox* m_layout_mode_box;
|
||||||
bool isOSX {false};
|
bool isOSX {false};
|
||||||
|
|
|
@ -28,6 +28,12 @@ using GUI::into_u8;
|
||||||
|
|
||||||
namespace Search {
|
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 const std::vector<std::wstring>& NameByType()
|
||||||
{
|
{
|
||||||
static std::vector<std::wstring> data;
|
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
|
label += L" [" + std::to_wstring(score) + L"]";// add score value
|
||||||
std::string label_u8 = into_u8(label);
|
std::string label_u8 = into_u8(label);
|
||||||
std::string label_plain = label_u8;
|
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::ColorMarkerStart)), "<b>");
|
||||||
boost::replace_all(label_plain, std::string(1, char(ImGui::ColorMarkerEnd)), "</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 });
|
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);
|
search_list->AppendBitmapColumn("", SearchListModel::colIcon);
|
||||||
|
|
||||||
wxDataViewTextRenderer* const markupRenderer = new wxDataViewTextRenderer();
|
wxDataViewTextRenderer* const markupRenderer = new wxDataViewTextRenderer();
|
||||||
#if wxUSE_MARKUP
|
|
||||||
|
#ifdef SEARCH_SUPPORTS_MARKUP
|
||||||
markupRenderer->EnableMarkup();
|
markupRenderer->EnableMarkup();
|
||||||
#endif // wxUSE_MARKUP
|
#endif
|
||||||
|
|
||||||
search_list->AppendColumn(new wxDataViewColumn("", markupRenderer, SearchListModel::colMarkedText, wxCOL_WIDTH_AUTOSIZE, wxALIGN_LEFT));
|
search_list->AppendColumn(new wxDataViewColumn("", markupRenderer, SearchListModel::colMarkedText, wxCOL_WIDTH_AUTOSIZE, wxALIGN_LEFT));
|
||||||
|
|
||||||
search_list->GetColumn(SearchListModel::colIcon )->SetWidth(3 * em_unit());
|
search_list->GetColumn(SearchListModel::colIcon )->SetWidth(3 * em_unit());
|
||||||
|
|
Loading…
Reference in a new issue