Merge remote-tracking branch 'remotes/prusa/master' into masterPE

This commit is contained in:
supermerill 2019-02-01 11:52:07 +01:00
commit 0680d6fe05
36 changed files with 722 additions and 361 deletions

View File

@ -1,5 +1,5 @@
### Version
_Version of Slic3r used goes here_
_Version of Slic3r Prusa Edition used goes here_
_Use `About->About Slic3r` for release versions_
@ -7,6 +7,10 @@ _For -dev versions, use `git describe --tag` or get the hash value for the versi
### Operating system type + version
_What OS are you using, and state any version #s_
_In case of 3D rendering issues, please attach the content of menu Help -> System Info dialog_
### 3D printer brand / version + firmware version (if known)
_What 3D printer brand / version are you printing on, is it a stock model or did you modify the printer, what firmware is running on your printer, version of the firmware #s_
### Behavior
* _Describe the problem_
@ -18,5 +22,5 @@ _What OS are you using, and state any version #s_
_Is this a new feature request?_
#### STL/Config (.ZIP) where problem occurs
_Upload a zipped copy of an STL and your config (`File -> Export Config`)_
#### Project File (.3MF) where problem occurs
_Upload a Slic3r PE Project File (.3MF) (`Plater -> Export plate as 3MF` for Slic3r PE 1.41.2 and older, `File -> Save` / `Save Project` for Slic3r PE 1.42.0-alpha and newer)_

View File

@ -86,9 +86,8 @@ set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
if(NOT WIN32)
# Add DEBUG flags for the debug builds in a way the Visual Studio adds these flags.
# Add DEBUG flags to debug builds.
add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")
add_compile_options("$<$<CONFIG:DEBUG>:-D_DEBUG>")
endif()
# To be able to link libslic3r with the Perl XS module.

View File

@ -73,8 +73,8 @@ add_library(libslic3r STATIC
GCode/CoolingBuffer.hpp
GCode/PostProcessor.cpp
GCode/PostProcessor.hpp
GCode/PressureEqualizer.cpp
GCode/PressureEqualizer.hpp
# GCode/PressureEqualizer.cpp
# GCode/PressureEqualizer.hpp
GCode/PreviewData.cpp
GCode/PreviewData.hpp
GCode/PrintExtents.cpp

View File

@ -662,10 +662,14 @@ void GCode::_do_export(Print &print, FILE *file)
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
if (print.config().spiral_vase.value)
m_spiral_vase = make_unique<SpiralVase>(print.config());
#ifdef HAS_PRESSURE_EQUALIZER
if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 ||
print.config().max_volumetric_extrusion_rate_slope_negative.value > 0)
m_pressure_equalizer = make_unique<PressureEqualizer>(&print.config());
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
#else /* HAS_PRESSURE_EQUALIZER */
m_enable_extrusion_role_markers = false;
#endif /* HAS_PRESSURE_EQUALIZER */
// Write information on the generator.
_write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str());
@ -918,8 +922,10 @@ void GCode::_do_export(Print &print, FILE *file)
this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), &copy - object.copies().data());
print.throw_if_canceled();
}
#ifdef HAS_PRESSURE_EQUALIZER
if (m_pressure_equalizer)
_write(file, m_pressure_equalizer->process("", true));
#endif /* HAS_PRESSURE_EQUALIZER */
++ finished_objects;
// Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
// Reset it when starting another object from 1st layer.
@ -975,8 +981,10 @@ void GCode::_do_export(Print &print, FILE *file)
this->process_layer(file, print, layer.second, layer_tools, size_t(-1));
print.throw_if_canceled();
}
#ifdef HAS_PRESSURE_EQUALIZER
if (m_pressure_equalizer)
_write(file, m_pressure_equalizer->process("", true));
#endif /* HAS_PRESSURE_EQUALIZER */
if (m_wipe_tower)
// Purge the extruder, pull out the active filament.
_write(file, m_wipe_tower->finalize(*this));
@ -1619,9 +1627,8 @@ void GCode::process_layer(
unsigned int copy_id = 0;
for (const Point &copy : copies) {
if (this->config().label_printed_objects) {
gcode += ((std::ostringstream&)(std::ostringstream() << "; printing object " << print_object->model_object()->name << " id:" << layer_id << " copy " << copy_id << "\n")).str();
}
if (this->config().gcode_label_objects)
gcode += std::string("; printing object ") + print_object->model_object()->name + " id:" + std::to_string(layer_id) + " copy " + std::to_string(copy_id) + "\n";
// When starting a new object, use the external motion planner for the first travel move.
std::pair<const PrintObject*, Point> this_object_copy(print_object, copy);
if (m_last_obj_copy != this_object_copy)
@ -1642,10 +1649,9 @@ void GCode::process_layer(
gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
gcode += this->extrude_infill(print, by_region_specific, false);
}
if (this->config().label_printed_objects) {
gcode += ((std::ostringstream&)(std::ostringstream() << "; stop printing object " << print_object->model_object()->name << " id:" << layer_id << " copy " << copy_id << "\n")).str();
}
++copy_id;
if (this->config().gcode_label_objects)
gcode += std::string("; stop printing object ") + print_object->model_object()->name + " id:" + std::to_string(layer_id) + " copy " + std::to_string(copy_id) + "\n";
++ copy_id;
}
}
}
@ -1663,12 +1669,14 @@ void GCode::process_layer(
if (m_cooling_buffer)
gcode = m_cooling_buffer->process_layer(gcode, layer.id());
#ifdef HAS_PRESSURE_EQUALIZER
// Apply pressure equalization if enabled;
// printf("G-code before filter:\n%s\n", gcode.c_str());
if (m_pressure_equalizer)
gcode = m_pressure_equalizer->process(gcode.c_str(), false);
// printf("G-code after filter:\n%s\n", out.c_str());
#endif /* HAS_PRESSURE_EQUALIZER */
_write(file, gcode);
BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z <<
", time estimator memory: " <<

View File

@ -11,7 +11,6 @@
#include "Print.hpp"
#include "PrintConfig.hpp"
#include "GCode/CoolingBuffer.hpp"
#include "GCode/PressureEqualizer.hpp"
#include "GCode/SpiralVase.hpp"
#include "GCode/ToolOrdering.hpp"
#include "GCode/WipeTower.hpp"
@ -22,6 +21,10 @@
#include <memory>
#include <string>
#ifdef HAS_PRESSURE_EQUALIZER
#include "GCode/PressureEqualizer.hpp"
#endif /* HAS_PRESSURE_EQUALIZER */
namespace Slic3r {
// Forward declarations.
@ -306,7 +309,9 @@ protected:
std::unique_ptr<CoolingBuffer> m_cooling_buffer;
std::unique_ptr<SpiralVase> m_spiral_vase;
#ifdef HAS_PRESSURE_EQUALIZER
std::unique_ptr<PressureEqualizer> m_pressure_equalizer;
#endif /* HAS_PRESSURE_EQUALIZER */
std::unique_ptr<WipeTowerIntegration> m_wipe_tower;
// Heights at which the skirt has already been extruded.

View File

@ -482,14 +482,14 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
}
case Extrusion::ColorPrint:
{
const auto color_print_cnt = cp_values.size();
const int color_cnt = (int)tool_colors.size()/4;
const auto color_print_cnt = (int)cp_values.size();
for (int i = color_print_cnt; i >= 0 ; --i)
{
int val = i;
while (val >= GCodePreviewData::Range::Colors_Count)
val -= GCodePreviewData::Range::Colors_Count;
GCodePreviewData::Color color = Range::Default_Colors[val];
GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (i % color_cnt) * 4), 4 * sizeof(float));
if (color_print_cnt == 0) {
items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color);
break;
@ -524,6 +524,12 @@ size_t GCodePreviewData::memory_used() const
sizeof(shell) + sizeof(ranges);
}
const std::vector<std::string>& GCodePreviewData::ColorPrintColors()
{
static std::vector<std::string> color_print = {"#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6"};
return color_print;
}
GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2)
{
return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]),

View File

@ -217,6 +217,8 @@ public:
// Return an estimate of the memory consumed by the time estimator.
size_t memory_used() const;
static const std::vector<std::string>& ColorPrintColors();
};
GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2);

View File

@ -13,7 +13,7 @@ class SpiralVase {
SpiralVase(const PrintConfig &config)
: enable(false), _config(&config)
{
this->_reader.z() = this->_config->z_offset;
this->_reader.z() = (float)this->_config->z_offset;
this->_reader.apply_config(*this->_config);
};
std::string process_layer(const std::string &gcode);

View File

@ -381,22 +381,7 @@ public:
Writer& comment_material(WipeTowerPrusaMM::material_type material)
{
m_gcode += "; material : ";
switch (material)
{
case WipeTowerPrusaMM::PVA:
m_gcode += "#8 (PVA)";
break;
case WipeTowerPrusaMM::SCAFF:
m_gcode += "#5 (Scaffold)";
break;
case WipeTowerPrusaMM::FLEX:
m_gcode += "#4 (Flex)";
break;
default:
m_gcode += "DEFAULT (PLA)";
break;
}
m_gcode += "\n";
m_gcode += WipeTowerPrusaMM::to_string(material) + "\n";
return *this;
};
@ -487,6 +472,23 @@ WipeTowerPrusaMM::material_type WipeTowerPrusaMM::parse_material(const char *nam
return INVALID;
}
std::string WipeTowerPrusaMM::to_string(material_type material)
{
switch (material) {
case PLA: return "PLA";
case ABS: return "ABS";
case PET: return "PET";
case HIPS: return "HIPS";
case FLEX: return "FLEX";
case SCAFF: return "SCAFF";
case EDGE: return "EDGE";
case NGEN: return "NGEN";
case PVA: return "PVA";
case INVALID:
default: return "INVALID";
}
}
// Returns gcode to prime the nozzles at the front edge of the print bed.
WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
// print_z of the first layer.

View File

@ -38,6 +38,7 @@ public:
// Parse material name into material_type.
static material_type parse_material(const char *name);
static std::string to_string(material_type material);
// x -- x coordinates of wipe tower in mm ( left bottom corner )
// y -- y coordinates of wipe tower in mm ( left bottom corner )

View File

@ -43,7 +43,7 @@ public:
}
bool cmd_is(const char *cmd_test) const {
const char *cmd = GCodeReader::skip_whitespaces(m_raw.c_str());
int len = strlen(cmd_test);
size_t len = strlen(cmd_test);
return strncmp(cmd, cmd_test, len) == 0 && GCodeReader::is_end_of_word(cmd[len]);
}
bool extruding(const GCodeReader &reader) const { return this->cmd_is("G1") && this->dist_E(reader) > 0; }

View File

@ -549,11 +549,18 @@ void Model::reset_auto_extruder_id()
std::string Model::propose_export_file_name() const
{
std::string input_file;
for (const ModelObject *model_object : this->objects)
for (ModelInstance *model_instance : model_object->instances)
if (model_instance->is_printable())
return model_object->input_file;
return std::string();
if (model_instance->is_printable()) {
input_file = model_object->name.empty() ? model_object->input_file : model_object->name;
if (! input_file.empty())
goto end;
// Other instances will produce the same name, skip them.
break;
}
end:
return input_file;
}
ModelObject::~ModelObject()
@ -1686,7 +1693,7 @@ bool model_volume_list_changed(const ModelObject &model_object_old, const ModelO
return false;
}
#ifdef _DEBUG
#ifndef NDEBUG
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
void check_model_ids_validity(const Model &model)
{
@ -1732,6 +1739,6 @@ void check_model_ids_equal(const Model &model1, const Model &model2)
}
}
}
#endif /* _DEBUG */
#endif /* NDEBUG */
}

View File

@ -629,11 +629,11 @@ extern bool model_object_list_extended(const Model &model_old, const Model &mode
// than the old ModelObject.
extern bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolume::Type type);
#ifdef _DEBUG
#ifndef NDEBUG
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
void check_model_ids_validity(const Model &model);
void check_model_ids_equal(const Model &model1, const Model &model2);
#endif /* _DEBUG */
#endif /* NDEBUG */
}

View File

@ -128,8 +128,8 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"first_layer_speed",
"first_layer_infill_speed",
"gcode_comments",
"label_printed_objects",
"gcode_flavor",
"gcode_label_objects",
"infill_acceleration",
"layer_gcode",
"min_fan_speed",
@ -138,8 +138,10 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"min_print_speed",
"max_print_speed",
"max_volumetric_speed",
#ifdef HAS_PRESSURE_EQUALIZER
"max_volumetric_extrusion_rate_slope_positive",
"max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
"notes",
"only_retract_when_crossing_perimeters",
"output_filename_format",

View File

@ -67,20 +67,9 @@ std::string PrintBase::output_filename(const std::string &format, const std::str
std::string PrintBase::output_filepath(const std::string &path) const
{
// if we were supplied no path, generate an automatic one based on our first object's input file
if (path.empty()) {
if (path.empty())
// get the first input file name
std::string input_file;
for (const ModelObject *model_object : m_model.objects) {
for (ModelInstance *model_instance : model_object->instances)
if (model_instance->is_printable()) {
input_file = model_object->input_file;
break;
}
if (! input_file.empty())
break;
}
return (boost::filesystem::path(input_file).parent_path() / this->output_filename()).make_preferred().string();
}
return (boost::filesystem::path(m_model.propose_export_file_name()).parent_path() / this->output_filename()).make_preferred().string();
// if we were supplied a directory, use it and append our automatically generated filename
boost::filesystem::path p(path);

View File

@ -1082,13 +1082,6 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->default_value = new ConfigOptionBool(0);
def = this->add("label_printed_objects", coBool);
def->label = "Label Prints with Object ID";
def->tooltip = "Enable this to add comments in the G-Code that label print moves with what object they belong. Can be used with Octoprint CancelObject plugin.";
def->cli = "label-printed-objects!";
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(0);
def = this->add("gcode_flavor", coEnum);
def->label = L("G-code flavor");
def->tooltip = L("Some G/M-code commands, including temperature control and others, are not universal. "
@ -1119,6 +1112,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
def = this->add("gcode_label_objects", coBool);
def->label = "Label objects";
def->tooltip = "Enable this to add comments into the G-Code labeling print moves with what object they belong to,"
" which is useful for the Octoprint CancelObject plugin. This settings is NOT compatible with "
"Single Extruder Multi Material setup and Wipe into Object / Wipe into Infill.";
def->cli = "gcode-label-objects!";
def->mode = comAdvanced;
def->default_value = new ConfigOptionBool(0);
def = this->add("high_current_on_filament_swap", coBool);
def->label = L("High extruder current on filament swap");
def->tooltip = L("It may be beneficial to increase the extruder motor current during the filament exchange"
@ -1439,6 +1441,7 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->default_value = new ConfigOptionFloat(0);
#ifdef HAS_PRESSURE_EQUALIZER
def = this->add("max_volumetric_extrusion_rate_slope_positive", coFloat);
def->label = L("Max volumetric slope positive");
def->tooltip = L("This experimental setting is used to limit the speed of change in extrusion rate. "
@ -1462,6 +1465,7 @@ void PrintConfigDef::init_fff_params()
def->min = 0;
def->mode = comExpert;
def->default_value = new ConfigOptionFloat(0);
#endif /* HAS_PRESSURE_EQUALIZER */
def = this->add("min_fan_speed", coInts);
def->label = L("Min");
@ -3065,6 +3069,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
"start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start",
"seal_position", "vibration_limit", "bed_size",
"print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe"
#ifndef HAS_PRESSURE_EQUALIZER
, "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative"
#endif /* HAS_PRESSURE_EQUALIZER */
};
if (ignore.find(opt_key) != ignore.end()) {

View File

@ -20,6 +20,8 @@
#include "libslic3r.h"
#include "Config.hpp"
// #define HAS_PRESSURE_EQUALIZER
namespace Slic3r {
enum PrinterTechnology
@ -698,13 +700,15 @@ public:
ConfigOptionFloats filament_cooling_final_speed;
ConfigOptionStrings filament_ramming_parameters;
ConfigOptionBool gcode_comments;
ConfigOptionBool label_printed_objects;
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
ConfigOptionBool gcode_label_objects;
ConfigOptionString layer_gcode;
ConfigOptionFloat max_print_speed;
ConfigOptionFloat max_volumetric_speed;
#ifdef HAS_PRESSURE_EQUALIZER
ConfigOptionFloat max_volumetric_extrusion_rate_slope_positive;
ConfigOptionFloat max_volumetric_extrusion_rate_slope_negative;
#endif
ConfigOptionPercents retract_before_wipe;
ConfigOptionFloats retract_length;
ConfigOptionFloats retract_length_toolchange;
@ -769,13 +773,15 @@ protected:
OPT_PTR(filament_cooling_final_speed);
OPT_PTR(filament_ramming_parameters);
OPT_PTR(gcode_comments);
OPT_PTR(label_printed_objects);
OPT_PTR(gcode_flavor);
OPT_PTR(gcode_label_objects);
OPT_PTR(layer_gcode);
OPT_PTR(max_print_speed);
OPT_PTR(max_volumetric_speed);
#ifdef HAS_PRESSURE_EQUALIZER
OPT_PTR(max_volumetric_extrusion_rate_slope_positive);
OPT_PTR(max_volumetric_extrusion_rate_slope_negative);
#endif /* HAS_PRESSURE_EQUALIZER */
OPT_PTR(retract_before_wipe);
OPT_PTR(retract_length);
OPT_PTR(retract_length_toolchange);
@ -810,7 +816,7 @@ protected:
class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig
{
STATIC_PRINT_CONFIG_CACHE_DERIVED(PrintConfig)
PrintConfig() : GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); }
PrintConfig() : MachineEnvelopeConfig(0), GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); }
public:
double min_object_distance() const;
static double min_object_distance(const ConfigBase *config);
@ -891,7 +897,7 @@ public:
ConfigOptionFloat exp_time_first;
protected:
PrintConfig(int) : GCodeConfig(1) {}
PrintConfig(int) : MachineEnvelopeConfig(1), GCodeConfig(1) {}
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
this->MachineEnvelopeConfig::initialize(cache, base_ptr);

View File

@ -56,3 +56,12 @@
#define ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES (1 && ENABLE_1_42_0_ALPHA4)
// Bunch of fixes related to volumes centering
#define ENABLE_VOLUMES_CENTERING_FIXES (1 && ENABLE_1_42_0_ALPHA4)
//====================
// 1.42.0.alpha5 techs
//====================
#define ENABLE_1_42_0_ALPHA5 1
// Toolbar items hidden/shown in dependence of the user mode
#define ENABLE_MODE_AWARE_TOOLBAR_ITEMS (1 && ENABLE_1_42_0_ALPHA5)

View File

@ -35,6 +35,27 @@
#include "GUI.hpp"
#ifdef HAS_GLSAFE
void glAssertRecentCallImpl()
{
GLenum err = glGetError();
if (err == GL_NO_ERROR)
return;
const char *sErr = 0;
switch (err) {
case GL_INVALID_ENUM: sErr = "Invalid Enum"; break;
case GL_INVALID_VALUE: sErr = "Invalid Value"; break;
case GL_INVALID_OPERATION: sErr = "Invalid Operation"; break;
case GL_STACK_OVERFLOW: sErr = "Stack Overflow"; break;
case GL_STACK_UNDERFLOW: sErr = "Stack Underflow"; break;
case GL_OUT_OF_MEMORY: sErr = "Out Of Memory"; break;
default: sErr = "Unknown"; break;
}
BOOST_LOG_TRIVIAL(error) << "OpenGL error " << (int)err << ": " << sErr;
assert(false);
}
#endif
namespace Slic3r {
void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
@ -81,25 +102,25 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
if (use_VBOs) {
if (! empty()) {
glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id);
glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glsafe(glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
glsafe(glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW));
glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
this->vertices_and_normals_interleaved.clear();
}
if (! this->triangle_indices.empty()) {
glGenBuffers(1, &this->triangle_indices_VBO_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW);
glsafe(glGenBuffers(1, &this->triangle_indices_VBO_id));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW));
this->triangle_indices.clear();
}
if (! this->quad_indices.empty()) {
glGenBuffers(1, &this->quad_indices_VBO_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW);
glsafe(glGenBuffers(1, &this->quad_indices_VBO_id));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW));
this->quad_indices.clear();
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
this->shrink_to_fit();
}
@ -107,15 +128,15 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
void GLIndexedVertexArray::release_geometry()
{
if (this->vertices_and_normals_interleaved_VBO_id) {
glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id);
glsafe(glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
this->vertices_and_normals_interleaved_VBO_id = 0;
}
if (this->triangle_indices_VBO_id) {
glDeleteBuffers(1, &this->triangle_indices_VBO_id);
glsafe(glDeleteBuffers(1, &this->triangle_indices_VBO_id));
this->triangle_indices_VBO_id = 0;
}
if (this->quad_indices_VBO_id) {
glDeleteBuffers(1, &this->quad_indices_VBO_id);
glsafe(glDeleteBuffers(1, &this->quad_indices_VBO_id));
this->quad_indices_VBO_id = 0;
}
this->clear();
@ -125,42 +146,42 @@ void GLIndexedVertexArray::release_geometry()
void GLIndexedVertexArray::render() const
{
if (this->vertices_and_normals_interleaved_VBO_id) {
glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
} else {
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3);
glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data());
glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glsafe(glEnableClientState(GL_VERTEX_ARRAY));
glsafe(glEnableClientState(GL_NORMAL_ARRAY));
if (this->indexed()) {
if (this->vertices_and_normals_interleaved_VBO_id) {
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_size > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr);
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr));
}
if (this->quad_indices_size > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr);
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr));
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else {
// Render in an immediate mode.
if (! this->triangle_indices.empty())
glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data());
glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data()));
if (! this->quad_indices.empty())
glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data());
glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data()));
}
} else
glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6));
glsafe(glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6)));
if (this->vertices_and_normals_interleaved_VBO_id)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(glDisableClientState(GL_VERTEX_ARRAY));
glsafe(glDisableClientState(GL_NORMAL_ARRAY));
}
void GLIndexedVertexArray::render(
@ -173,35 +194,35 @@ void GLIndexedVertexArray::render(
if (this->vertices_and_normals_interleaved_VBO_id) {
// Render using the Vertex Buffer Objects.
glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
glsafe(glEnableClientState(GL_VERTEX_ARRAY));
glsafe(glEnableClientState(GL_NORMAL_ARRAY));
if (this->triangle_indices_size > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)));
}
if (this->quad_indices_size > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)));
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else {
// Render in an immediate mode.
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3);
glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data());
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
glsafe(glEnableClientState(GL_VERTEX_ARRAY));
glsafe(glEnableClientState(GL_NORMAL_ARRAY));
if (! this->triangle_indices.empty())
glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first));
glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first)));
if (! this->quad_indices.empty())
glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first));
glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first)));
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glsafe(glDisableClientState(GL_VERTEX_ARRAY));
glsafe(glDisableClientState(GL_NORMAL_ARRAY));
}
const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
@ -231,6 +252,7 @@ GLVolume::GLVolume(float r, float g, float b, float a)
, is_modifier(false)
, is_wipe_tower(false)
, is_extrusion_path(false)
, force_transparent(false)
, tverts_range(0, size_t(-1))
, qverts_range(0, size_t(-1))
{
@ -272,6 +294,9 @@ void GLVolume::set_render_color()
set_render_color(OUTSIDE_COLOR, 4);
else
set_render_color(color, 4);
if (force_transparent)
render_color[3] = color[3];
}
void GLVolume::set_color_from_model_volume(const ModelVolume *model_volume)
@ -375,15 +400,15 @@ void GLVolume::render() const
if (!is_active)
return;
::glCullFace(GL_BACK);
::glPushMatrix();
glsafe(::glCullFace(GL_BACK));
glsafe(::glPushMatrix());
::glMultMatrixd(world_matrix().data());
glsafe(::glMultMatrixd(world_matrix().data()));
if (this->indexed_vertex_array.indexed())
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
else
this->indexed_vertex_array.render();
::glPopMatrix();
glsafe(::glPopMatrix());
}
void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const
@ -398,63 +423,63 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
if (n_triangles + n_quads == 0)
{
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
if (color_id >= 0)
{
float color[4];
::memcpy((void*)color, (const void*)render_color, 4 * sizeof(float));
::glUniform4fv(color_id, 1, (const GLfloat*)color);
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color));
}
else
::glColor4fv(render_color);
glsafe(::glColor4fv(render_color));
if (detection_id != -1)
::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0));
if (worldmatrix_id != -1)
::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()));
render();
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
return;
}
if (color_id >= 0)
::glUniform4fv(color_id, 1, (const GLfloat*)render_color);
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)render_color));
else
::glColor4fv(render_color);
glsafe(::glColor4fv(render_color));
if (detection_id != -1)
::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0));
if (worldmatrix_id != -1)
::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()));
::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
::glPushMatrix();
glsafe(::glPushMatrix());
::glMultMatrixd(world_matrix().data());
glsafe(::glMultMatrixd(world_matrix().data()));
if (n_triangles > 0)
{
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id);
::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id));
glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)));
}
if (n_quads > 0)
{
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id);
::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id));
glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)));
}
::glPopMatrix();
glsafe(::glPopMatrix());
}
void GLVolume::render_legacy() const
@ -467,33 +492,33 @@ void GLVolume::render_legacy() const
GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
if (n_triangles + n_quads == 0)
{
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
::glColor4fv(render_color);
glsafe(::glColor4fv(render_color));
render();
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
return;
}
::glColor4fv(render_color);
::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3);
::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data());
glsafe(::glColor4fv(render_color));
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3));
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data()));
::glPushMatrix();
glsafe(::glPushMatrix());
::glMultMatrixd(world_matrix().data());
glsafe(::glMultMatrixd(world_matrix().data()));
if (n_triangles > 0)
::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first);
glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first));
if (n_quads > 0)
::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first);
glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first));
::glPopMatrix();
glsafe(::glPopMatrix());
}
std::vector<int> GLVolumeCollection::load_object(
@ -705,7 +730,7 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
{
Transform3d modelview_matrix;
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()));
for (GLVolumeWithZ& volume : list)
{
@ -722,18 +747,18 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum
void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func) const
{
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
::glCullFace(GL_BACK);
glsafe(::glCullFace(GL_BACK));
if (disable_cullface)
::glDisable(GL_CULL_FACE);
glsafe(::glDisable(GL_CULL_FACE));
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
GLint current_program_id;
::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id));
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
GLint z_range_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "z_range") : -1;
GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1;
@ -742,13 +767,13 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
GLint print_box_worldmatrix_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
if (print_box_min_id != -1)
::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min));
if (print_box_max_id != -1)
::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max));
if (z_range_id != -1)
::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range);
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func);
for (GLVolumeWithZ& volume : to_render) {
@ -756,29 +781,29 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
}
::glBindBuffer(GL_ARRAY_BUFFER, 0);
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
if (disable_cullface)
::glEnable(GL_CULL_FACE);
glsafe(::glEnable(GL_CULL_FACE));
::glDisable(GL_BLEND);
glsafe(::glDisable(GL_BLEND));
}
void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface) const
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glsafe(glEnable(GL_BLEND));
glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
glCullFace(GL_BACK);
glsafe(glCullFace(GL_BACK));
if (disable_cullface)
::glDisable(GL_CULL_FACE);
glsafe(::glDisable(GL_CULL_FACE));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glsafe(glEnableClientState(GL_VERTEX_ARRAY));
glsafe(glEnableClientState(GL_NORMAL_ARRAY));
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, std::function<bool(const GLVolume&)>());
for (GLVolumeWithZ& volume : to_render)
@ -787,13 +812,13 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface)
volume.first->render_legacy();
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glsafe(glDisableClientState(GL_VERTEX_ARRAY));
glsafe(glDisableClientState(GL_NORMAL_ARRAY));
if (disable_cullface)
::glEnable(GL_CULL_FACE);
glsafe(::glEnable(GL_CULL_FACE));
glDisable(GL_BLEND);
glsafe(glDisable(GL_BLEND));
}
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state)
@ -1718,44 +1743,44 @@ void GLModel::render() const
void GLModel::render_VBOs() const
{
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
::glCullFace(GL_BACK);
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
glsafe(::glCullFace(GL_BACK));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
GLint current_program_id;
::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id));
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
m_volume.render_VBOs(color_id, -1, -1);
::glBindBuffer(GL_ARRAY_BUFFER, 0);
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
::glDisable(GL_BLEND);
glsafe(::glDisable(GL_BLEND));
}
void GLModel::render_legacy() const
{
::glEnable(GL_LIGHTING);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glsafe(::glEnable(GL_LIGHTING));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
::glCullFace(GL_BACK);
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
glsafe(::glCullFace(GL_BACK));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
m_volume.render_legacy();
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
::glDisable(GL_BLEND);
::glDisable(GL_LIGHTING);
glsafe(::glDisable(GL_BLEND));
glsafe(::glDisable(GL_LIGHTING));
}
bool GLArrow::on_init(bool useVBOs)

View File

@ -11,6 +11,19 @@
#include <functional>
#ifndef NDEBUG
#define HAS_GLSAFE
#endif
#ifdef HAS_GLSAFE
extern void glAssertRecentCallImpl();
inline void glAssertRecentCall() { glAssertRecentCallImpl(); }
#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(); } while (false)
#else
inline void glAssertRecentCall() { }
#define glsafe(cmd) cmd
#endif
namespace Slic3r {
class Print;
@ -282,6 +295,8 @@ public:
bool is_wipe_tower;
// Wheter or not this volume has been generated from an extrusion path
bool is_extrusion_path;
// Wheter or not to always render this volume using its own alpha
bool force_transparent;
// Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array;

View File

@ -1888,12 +1888,12 @@ static double rotation_diff_z(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to
Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
Vec3d axis = angle_axis.axis();
double angle = angle_axis.angle();
#ifdef _DEBUG
#ifndef NDEBUG
if (std::abs(angle) > 1e-8) {
assert(std::abs(axis.x()) < 1e-8);
assert(std::abs(axis.y()) < 1e-8);
}
#endif /* _DEBUG */
#endif /* NDEBUG */
return (axis.z() < 0) ? -angle : angle;
}
@ -2881,7 +2881,7 @@ void GLCanvas3D::Selection::_render_sidebar_size_hint(Axis axis, double length)
{
}
#ifdef _DEBUG
#ifndef NDEBUG
static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
{
Eigen::AngleAxisd angle_axis(rotation_xyz_diff(rot_xyz_from, rot_xyz_to));
@ -2915,7 +2915,7 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV
}
}
}
#endif /* _DEBUG */
#endif /* NDEBUG */
void GLCanvas3D::Selection::_synchronize_unselected_instances(SyncRotationType sync_rotation_type)
{
@ -2975,9 +2975,9 @@ void GLCanvas3D::Selection::_synchronize_unselected_instances(SyncRotationType s
}
}
#ifdef _DEBUG
#ifndef NDEBUG
verify_instances_rotation_synchronized(*m_model, *m_volumes);
#endif /* _DEBUG */
#endif /* NDEBUG */
}
void GLCanvas3D::Selection::_synchronize_unselected_volumes()
@ -3843,17 +3843,12 @@ GLCanvas3D::LegendTexture::LegendTexture()
{
}
bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors)
void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas,
std::vector<std::pair<double, double>>& cp_legend_values)
{
reset();
// collects items to render
auto title = _(preview_data.get_legend_title());
std::vector<std::pair<double, double>> cp_legend_values;
if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint)
{
const auto& config = wxGetApp().preset_bundle->full_config();
auto& config = wxGetApp().preset_bundle->project_config;
const std::vector<double>& color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
const int values_cnt = color_print_values.size();
if (values_cnt > 0) {
@ -3874,7 +3869,19 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
}
}
}
const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, /*color_print_values*/cp_legend_values);
}
bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors)
{
reset();
// collects items to render
auto title = _(preview_data.get_legend_title());
std::vector<std::pair<double, double>> cp_legend_values;
fill_color_print_legend_values(preview_data, canvas, cp_legend_values);
const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values);
unsigned int items_count = (unsigned int)items.size();
if (items_count == 0)
@ -4261,6 +4268,8 @@ unsigned int GLCanvas3D::get_volumes_count() const
void GLCanvas3D::reset_volumes()
{
_set_current();
if (!m_volumes.empty())
{
m_selection.clear();
@ -4372,6 +4381,13 @@ bool GLCanvas3D::is_reload_delayed() const
void GLCanvas3D::enable_layers_editing(bool enable)
{
m_layers_editing.set_enabled(enable);
const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
for (unsigned int idx : idxs)
{
GLVolume* v = m_volumes.volumes[idx];
if (v->is_modifier)
v->force_transparent = enable;
}
}
void GLCanvas3D::enable_warning_texture(bool enable)
@ -4500,6 +4516,16 @@ void GLCanvas3D::update_volumes_colors_by_extruder()
m_volumes.update_colors_by_extruder(m_config);
}
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
void GLCanvas3D::update_toolbar_items_visibility()
{
ConfigOptionMode mode = wxGetApp().get_mode();
m_toolbar.set_item_visible("more", mode != comSimple);
m_toolbar.set_item_visible("fewer", mode != comSimple);
m_dirty = true;
}
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
// Returns a Rect object denoting size and position of the Reset button used by a gizmo.
// Returns in either screen or viewport coords.
#if !ENABLE_IMGUI
@ -4715,6 +4741,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
return;
_set_current();
struct ModelVolumeState {
ModelVolumeState(const GLVolume *volume) :
model_volume(nullptr), geometry_id(volume->geometry_id), volume_idx(-1) {}
@ -4769,10 +4797,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
}
if (printer_technology == ptSLA) {
const SLAPrint *sla_print = this->sla_print();
#ifdef _DEBUG
#ifndef NDEBUG
// Verify that the SLAPrint object is synchronized with m_model.
check_model_ids_equal(*m_model, sla_print->model());
#endif /* _DEBUG */
#endif /* NDEBUG */
sla_support_state.reserve(sla_print->objects().size());
for (const SLAPrintObject *print_object : sla_print->objects()) {
SLASupportState state;
@ -5021,6 +5049,8 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const
const Print *print = this->fff_print();
if ((m_canvas != nullptr) && (print != nullptr))
{
_set_current();
std::vector<float> tool_colors = _parse_colors(str_tool_colors);
if (m_volumes.empty())
@ -5058,22 +5088,25 @@ void GLCanvas3D::load_sla_preview()
const SLAPrint* print = this->sla_print();
if ((m_canvas != nullptr) && (print != nullptr))
{
_set_current();
_load_shells_sla();
}
}
void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors)
void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values)
{
const Print *print = this->fff_print();
if (print == nullptr)
return;
_set_current();
_load_print_toolpaths();
_load_wipe_tower_toolpaths(str_tool_colors);
for (const PrintObject* object : print->objects())
{
if (object != nullptr)
_load_print_object_toolpaths(*object, str_tool_colors);
_load_print_object_toolpaths(*object, str_tool_colors, color_print_values);
}
for (GLVolume* volume : m_volumes.volumes)
@ -5083,7 +5116,14 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors)
_update_toolpath_volumes_outside_state();
_show_warning_texture_if_needed();
reset_legend_texture();
if (color_print_values.empty())
reset_legend_texture();
else {
auto preview_data = GCodePreviewData();
preview_data.extrusion.view_type = GCodePreviewData::Extrusion::ColorPrint;
const std::vector<float> tool_colors = _parse_colors(str_tool_colors);
_generate_legend_texture(preview_data, tool_colors);
}
}
void GLCanvas3D::bind_event_handlers()
@ -5278,6 +5318,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
Point pos(evt.GetX(), evt.GetY());
if (m_picking_enabled)
_set_current();
int selected_object_idx = m_selection.get_object_idx();
int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
m_layers_editing.select_object(*m_model, layer_editing_object_idx);
@ -5731,7 +5774,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
void GLCanvas3D::on_paint(wxPaintEvent& evt)
{
render();
if (m_initialized)
m_dirty = true;
else
// Call render directly, so it gets initialized immediately, not from On Idle handler.
this->render();
}
void GLCanvas3D::on_key_down(wxKeyEvent& evt)
@ -5782,6 +5829,7 @@ Point GLCanvas3D::get_local_mouse_position() const
void GLCanvas3D::reset_legend_texture()
{
_set_current();
m_legend_texture.reset();
}
@ -6233,6 +6281,10 @@ bool GLCanvas3D::_init_toolbar()
enable_toolbar_item("add", true);
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
update_toolbar_items_visibility();
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
return true;
}
@ -7339,7 +7391,7 @@ void GLCanvas3D::_load_print_toolpaths()
volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
}
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors)
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values)
{
std::vector<float> tool_colors = _parse_colors(str_tool_colors);
@ -7351,6 +7403,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
bool has_infill;
bool has_support;
const std::vector<float>* tool_colors;
const std::vector<double>* color_print_values;
// Number of vertices (each vertex is 6x4=24 bytes long)
static const size_t alloc_size_max() { return 131072; } // 3.15MB
@ -7368,7 +7421,15 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
int volume_idx(int extruder, int feature) const
{
return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature;
return this->color_by_color_print() ? 0 : this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature;
}
// For coloring by a color_print(M600), return a parsed color.
bool color_by_color_print() const { return color_print_values!=nullptr; }
const float* color_print_by_layer_idx(const size_t layer_idx) const
{
auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON);
return color_tool((it - color_print_values->begin()) % number_tools());
}
} ctxt;
@ -7376,6 +7437,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
ctxt.has_infill = print_object.is_step_done(posInfill);
ctxt.has_support = print_object.is_step_done(posSupportMaterial);
ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values;
ctxt.shifted_copies = &print_object.copies();
@ -7400,7 +7462,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
//FIXME Improve the heuristics for a grain size.
size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
size_t grain_size = ctxt.color_by_color_print() ? size_t(1) : std::max(ctxt.layers.size() / 16, size_t(1));
tbb::spin_mutex new_volume_mutex;
auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
auto *volume = new GLVolume(color);
@ -7415,7 +7477,9 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
[&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
GLVolumePtrs vols;
if (ctxt.color_by_tool()) {
if (ctxt.color_by_color_print())
vols.emplace_back(new_volume(ctxt.color_print_by_layer_idx(range.begin())));
else if (ctxt.color_by_tool()) {
for (size_t i = 0; i < ctxt.number_tools(); ++i)
vols.emplace_back(new_volume(ctxt.color_tool(i)));
}
@ -7735,11 +7799,15 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
}
case GCodePreviewData::Extrusion::ColorPrint:
{
const size_t color_cnt = tool_colors.size() / 4;
int val = int(value);
while (val >= GCodePreviewData::Range::Colors_Count)
val -= GCodePreviewData::Range::Colors_Count;
while (val >= color_cnt)
val -= color_cnt;
GCodePreviewData::Color color = GCodePreviewData::Range::Default_Colors[val];
GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float));
return color;
}
default:
@ -8391,6 +8459,8 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state()
void GLCanvas3D::_show_warning_texture_if_needed()
{
_set_current();
if (_is_any_volume_outside())
{
enable_warning_texture(true);

View File

@ -860,6 +860,8 @@ private:
public:
LegendTexture();
void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas,
std::vector<std::pair<double, double>>& cp_legend_values);
bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors);
@ -1005,6 +1007,10 @@ public:
void update_volumes_colors_by_extruder();
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
void update_toolbar_items_visibility();
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
#if !ENABLE_IMGUI
Rect get_gizmo_reset_rect(const GLCanvas3D& canvas, bool viewport) const;
bool gizmo_reset_rect_contains(const GLCanvas3D& canvas, float x, float y) const;
@ -1030,8 +1036,7 @@ public:
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
void load_sla_preview();
void load_preview(const std::vector<std::string>& str_tool_colors);
void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values);
void bind_event_handlers();
void unbind_event_handlers();
@ -1136,7 +1141,8 @@ private:
// Create 3D thick extrusion lines for object forming extrusions.
// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
// one for perimeters, one for infill and one for supports.
void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors);
void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors,
const std::vector<double>& color_print_values);
// Create 3D thick extrusion lines for wipe tower extrusions
void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);

View File

@ -35,6 +35,9 @@ GLToolbarItem::Data::Data()
, tooltip("")
, sprite_id(-1)
, is_toggable(false)
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
, visible(true)
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
{
}
@ -45,61 +48,11 @@ GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Dat
{
}
GLToolbarItem::EState GLToolbarItem::get_state() const
{
return m_state;
}
void GLToolbarItem::set_state(GLToolbarItem::EState state)
{
m_state = state;
}
const std::string& GLToolbarItem::get_name() const
{
return m_data.name;
}
const std::string& GLToolbarItem::get_tooltip() const
{
return m_data.tooltip;
}
void GLToolbarItem::do_action(wxEvtHandler *target)
{
wxPostEvent(target, SimpleEvent(m_data.action_event));
}
bool GLToolbarItem::is_enabled() const
{
return m_state != Disabled;
}
bool GLToolbarItem::is_disabled() const
{
return m_state == Disabled;
}
bool GLToolbarItem::is_hovered() const
{
return (m_state == Hover) || (m_state == HoverPressed);
}
bool GLToolbarItem::is_pressed() const
{
return (m_state == Pressed) || (m_state == HoverPressed);
}
bool GLToolbarItem::is_toggable() const
{
return m_data.is_toggable;
}
bool GLToolbarItem::is_separator() const
{
return m_type == Separator;
}
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
{
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size));
@ -355,6 +308,46 @@ bool GLToolbar::is_item_disabled(const std::string& name) const
return false;
}
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
bool GLToolbar::is_item_visible(const std::string& name) const
{
for (GLToolbarItem* item : m_items)
{
if (item->get_name() == name)
return item->is_visible();
}
return false;
}
void GLToolbar::set_item_visible(const std::string& name, bool visible)
{
for (GLToolbarItem* item : m_items)
{
if ((item->get_name() == name) && (item->is_visible() != visible))
{
item->set_visible(visible);
m_layout.dirty = true;
break;
}
}
// updates separators visibility to avoid having two consecutive
bool any_item_visible = false;
for (GLToolbarItem* item : m_items)
{
if (!item->is_separator())
any_item_visible |= item->is_visible();
else
{
item->set_visible(any_item_visible);
any_item_visible = false;
}
}
}
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
{
if (!m_enabled)
@ -486,6 +479,11 @@ float GLToolbar::get_main_size() const
float size = 2.0f * m_layout.border * m_layout.icons_scale;
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
{
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!m_items[i]->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (m_items[i]->is_separator())
size += m_layout.separator_size * m_layout.icons_scale;
else
@ -524,6 +522,11 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
for (GLToolbarItem* item : m_items)
{
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!item->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (item->is_separator())
left += separator_stride;
else
@ -618,6 +621,11 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
for (GLToolbarItem* item : m_items)
{
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!item->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (item->is_separator())
top -= separator_stride;
else
@ -714,6 +722,11 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
{
++id;
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!item->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (item->is_separator())
left += separator_stride;
else
@ -759,6 +772,11 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
{
++id;
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!item->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (item->is_separator())
top -= separator_stride;
else
@ -892,6 +910,11 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
// renders icons
for (const GLToolbarItem* item : m_items)
{
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!item->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (item->is_separator())
left += separator_stride;
else
@ -1018,6 +1041,11 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
// renders icons
for (const GLToolbarItem* item : m_items)
{
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (!item->is_visible())
continue;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (item->is_separator())
top -= separator_stride;
else

View File

@ -8,7 +8,6 @@
#include "GLTexture.hpp"
#include "Event.hpp"
class wxEvtHandler;
namespace Slic3r {
@ -56,6 +55,9 @@ public:
unsigned int sprite_id;
bool is_toggable;
wxEventType action_event;
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
bool visible;
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
Data();
};
@ -68,21 +70,25 @@ private:
public:
GLToolbarItem(EType type, const Data& data);
EState get_state() const;
void set_state(EState state);
EState get_state() const { return m_state; }
void set_state(EState state) { m_state = state; }
const std::string& get_name() const;
const std::string& get_tooltip() const;
const std::string& get_name() const { return m_data.name; }
const std::string& get_tooltip() const { return m_data.tooltip; }
void do_action(wxEvtHandler *target);
bool is_enabled() const;
bool is_disabled() const;
bool is_hovered() const;
bool is_pressed() const;
bool is_enabled() const { return m_state != Disabled; }
bool is_disabled() const { return m_state == Disabled; }
bool is_hovered() const { return (m_state == Hover) || (m_state == HoverPressed); }
bool is_pressed() const { return (m_state == Pressed) || (m_state == HoverPressed); }
bool is_toggable() const;
bool is_separator() const;
bool is_toggable() const { return m_data.is_toggable; }
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
bool is_visible() const { return m_data.visible; }
void set_visible(bool visible) { m_data.visible = visible; }
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
bool is_separator() const { return m_type == Separator; }
void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
@ -223,6 +229,10 @@ public:
bool is_item_pressed(const std::string& name) const;
bool is_item_disabled(const std::string& name) const;
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
bool is_item_visible(const std::string& name) const;
void set_item_visible(const std::string& name, bool visible);
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent);

View File

@ -64,12 +64,6 @@ ObjectList::ObjectList(wxWindow* parent) :
init_icons();
// create popup menus for object and part
create_object_popupmenu(&m_menu_object);
create_part_popupmenu(&m_menu_part);
create_sla_object_popupmenu(&m_menu_sla_object);
create_instance_popupmenu(&m_menu_instance);
// describe control behavior
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) {
selection_changed();
@ -106,8 +100,6 @@ ObjectList::ObjectList(wxWindow* parent) :
ObjectList::~ObjectList()
{
if (m_default_config)
delete m_default_config;
}
void ObjectList::create_objects_ctrl()
@ -141,6 +133,15 @@ void ObjectList::create_objects_ctrl()
wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
}
void ObjectList::create_popup_menus()
{
// create popup menus for object and part
create_object_popupmenu(&m_menu_object);
create_part_popupmenu(&m_menu_part);
create_sla_object_popupmenu(&m_menu_sla_object);
create_instance_popupmenu(&m_menu_instance);
}
void ObjectList::set_tooltip_for_item(const wxPoint& pt)
{
wxDataViewItem item;
@ -310,7 +311,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item)
wxGetApp().plater()->update();
}
void ObjectList::update_name_in_model(const wxDataViewItem& item)
void ObjectList::update_name_in_model(const wxDataViewItem& item) const
{
const int obj_idx = m_objects_model->GetObjectIdByItem(item);
if (obj_idx < 0) return;
@ -421,9 +422,6 @@ void ObjectList::show_context_menu()
if (multiple_selection() && selected_instances_of_same_object())
{
wxGetApp().plater()->PopupMenu(&m_menu_instance);
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId());
return;
}
@ -442,12 +440,6 @@ void ObjectList::show_context_menu()
append_menu_item_settings(menu);
wxGetApp().plater()->PopupMenu(menu);
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
evt.Enable(is_splittable()); }, m_menu_item_split->GetId());
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
evt.Enable(is_splittable()); }, m_menu_item_split_part->GetId());
}
}
@ -755,10 +747,8 @@ void ObjectList::get_settings_choice(const wxString& category_name)
const ConfigOption* option = from_config.option(opt_key);
if (!option) {
// if current option doesn't exist in prints.get_edited_preset(),
// get it from m_default_config
if (m_default_config) delete m_default_config;
m_default_config = DynamicPrintConfig::new_from_defaults_keys(get_options(false));
option = m_default_config->option(opt_key);
// get it from default config values
option = DynamicPrintConfig::new_from_defaults_keys({ opt_key })->option(opt_key);
}
m_config->set_key_value(opt_key, option->clone());
}
@ -782,10 +772,8 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name)
const ConfigOption* option = from_config.option(opt_key);
if (!option) {
// if current option doesn't exist in prints.get_edited_preset(),
// get it from m_default_config
if (m_default_config) delete m_default_config;
m_default_config = DynamicPrintConfig::new_from_defaults_keys(get_options(false));
option = m_default_config->option(opt_key);
// get it from default config values
option = DynamicPrintConfig::new_from_defaults_keys({ opt_key })->option(opt_key);
}
m_config->set_key_value(opt_key, option->clone());
}
@ -964,8 +952,30 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu)
[this](wxCommandEvent&) { split_instances(); }, "", menu);
}
void ObjectList::append_menu_item_rename(wxMenu* menu)
{
append_menu_item(menu, wxID_ANY, _(L("Rename")), "",
[this](wxCommandEvent&) { rename_item(); }, "", menu);
menu->AppendSeparator();
}
void ObjectList::append_menu_item_fix_through_netfabb(wxMenu* menu)
{
if (!is_windows10())
return;
append_menu_item(menu, wxID_ANY, _(L("Fix through the Netfabb")), "",
[this](wxCommandEvent&) { fix_through_netfabb(); }, "", menu);
menu->AppendSeparator();
}
void ObjectList::create_object_popupmenu(wxMenu *menu)
{
#ifdef __WXOSX__
append_menu_item_rename(menu);
#endif // __WXOSX__
append_menu_item_fix_through_netfabb(menu);
// Split object to parts
m_menu_item_split = append_menu_item_split(menu);
menu->AppendSeparator();
@ -973,16 +983,30 @@ void ObjectList::create_object_popupmenu(wxMenu *menu)
// rest of a object_menu will be added later in:
// - append_menu_items_add_volume() -> for "Add (volumes)"
// - append_menu_item_settings() -> for "Add (settings)"
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
evt.Enable(is_splittable()); }, m_menu_item_split->GetId());
}
void ObjectList::create_sla_object_popupmenu(wxMenu *menu)
{
#ifdef __WXOSX__
append_menu_item_rename(menu);
#endif // __WXOSX__
append_menu_item_fix_through_netfabb(menu);
// rest of a object_sla_menu will be added later in:
// - append_menu_item_settings() -> for "Add (settings)"
}
void ObjectList::create_part_popupmenu(wxMenu *menu)
{
#ifdef __WXOSX__
append_menu_item_rename(menu);
#endif // __WXOSX__
append_menu_item_fix_through_netfabb(menu);
m_menu_item_split_part = append_menu_item_split(menu);
// Append change part type
@ -991,11 +1015,17 @@ void ObjectList::create_part_popupmenu(wxMenu *menu)
// rest of a object_sla_menu will be added later in:
// - append_menu_item_settings() -> for "Add (settings)"
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
evt.Enable(is_splittable()); }, m_menu_item_split_part->GetId());
}
void ObjectList::create_instance_popupmenu(wxMenu*menu)
{
m_menu_item_split_instances = append_menu_item_instance_to_object(menu);
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId());
}
wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu)
@ -2052,6 +2082,66 @@ void ObjectList::split_instances()
instances_to_separated_object(obj_idx, inst_idxs);
}
void ObjectList::rename_item()
{
const wxDataViewItem item = GetSelection();
if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject)))
return ;
const wxString new_name = wxGetTextFromUser(_(L("Enter new name"))+":", _(L("Renaming")),
m_objects_model->GetName(item), this);
if (new_name.IsEmpty())
return;
bool is_unusable_symbol = false;
std::string chosen_name = Slic3r::normalize_utf8_nfc(new_name.ToUTF8());
const char* unusable_symbols = "<>:/\\|?*\"";
for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
if (chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) {
is_unusable_symbol = true;
}
}
if (is_unusable_symbol) {
show_error(this, _(L("The supplied name is not valid;")) + "\n" +
_(L("the following characters are not allowed:")) + " <>:/\\|?*\"");
return;
}
// The icon can't be edited so get its old value and reuse it.
wxVariant valueOld;
m_objects_model->GetValue(valueOld, item, 0);
PrusaDataViewBitmapText bmpText;
bmpText << valueOld;
// But replace the text with the value entered by user.
bmpText.SetText(new_name);
wxVariant value;
value << bmpText;
m_objects_model->SetValue(value, item, 0);
m_objects_model->ItemChanged(item);
update_name_in_model(item);
}
void ObjectList::fix_through_netfabb() const
{
const wxDataViewItem item = GetSelection();
if (!item)
return;
ItemType type = m_objects_model->GetItemType(item);
if (type & itObject)
wxGetApp().plater()->fix_through_netfabb(m_objects_model->GetIdByItem(item));
else if (type & itVolume)
wxGetApp().plater()->fix_through_netfabb(m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)),
m_objects_model->GetVolumeIdByItem(item));
}
void ObjectList::ItemValueChanged(wxDataViewEvent &event)
{
if (event.GetColumn() == 0)

View File

@ -97,9 +97,6 @@ class ObjectList : public wxDataViewCtrl
} m_dragged_data;
wxBoxSizer *m_sizer {nullptr};
DynamicPrintConfig *m_default_config {nullptr};
wxWindow *m_parent {nullptr};
wxBitmap m_bmp_modifiermesh;
@ -153,6 +150,7 @@ public:
void create_objects_ctrl();
void create_popup_menus();
wxDataViewColumn* create_objects_list_extruder_column(int extruders_count);
void update_objects_list_extruder_column(int extruders_count);
// show/hide "Extruder" column for Objects List
@ -160,7 +158,7 @@ public:
// update extruder in current config
void update_extruder_in_config(const wxDataViewItem& item);
// update changed name in the object model
void update_name_in_model(const wxDataViewItem& item);
void update_name_in_model(const wxDataViewItem& item) const;
void update_extruder_values_for_items(const int max_extruder);
void init_icons();
@ -181,6 +179,8 @@ public:
wxMenuItem* append_menu_item_settings(wxMenu* menu);
wxMenuItem* append_menu_item_change_type(wxMenu* menu);
wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu);
void append_menu_item_rename(wxMenu* menu);
void append_menu_item_fix_through_netfabb(wxMenu* menu);
void create_object_popupmenu(wxMenu *menu);
void create_sla_object_popupmenu(wxMenu*menu);
void create_part_popupmenu(wxMenu*menu);
@ -262,7 +262,8 @@ public:
void instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idx);
void split_instances();
void rename_item();
void fix_through_netfabb() const;
private:
void OnChar(wxKeyEvent& event);
void OnContextMenu(wxDataViewEvent &event);

View File

@ -139,6 +139,14 @@ void View3D::mirror_selection(Axis axis)
m_canvas->mirror_selection(axis);
}
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
void View3D::update_toolbar_items_visibility()
{
if (m_canvas != nullptr)
m_canvas->update_toolbar_items_visibility();
}
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
void View3D::enable_toolbar_item(const std::string& name, bool enable)
{
if (m_canvas != nullptr)
@ -558,6 +566,7 @@ void Preview::create_double_slider()
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
m_preferred_color_mode = "feature";
}
reload_print();
});
}
@ -728,10 +737,22 @@ void Preview::load_print_as_fff()
m_preferred_color_mode = "tool_or_feature";
}
bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty();
// Collect colors per extruder.
std::vector<std::string> colors;
bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty();
if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool))
std::vector<double> color_print_values = {};
// set color print values, if it si selected "ColorPrint" view type
if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint)
{
colors = GCodePreviewData::ColorPrintColors();
if (! gcode_preview_data_valid) {
//FIXME accessing full_config() is pretty expensive.
// Only initialize color_print_values for the initial preview, not for the full preview where the color_print_values is extracted from the G-code.
const auto& config = wxGetApp().preset_bundle->project_config;
color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
}
}
else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) )
{
const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour"));
const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour"));
@ -748,8 +769,9 @@ void Preview::load_print_as_fff()
color = "#FFFFFF";
}
colors.push_back(color);
colors.emplace_back(color);
}
color_print_values.clear();
}
if (IsShown())
@ -759,7 +781,7 @@ void Preview::load_print_as_fff()
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
else
// Load the initial preview based on slices, not the final G-code.
m_canvas->load_preview(colors);
m_canvas->load_preview(colors, color_print_values);
show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple");
// recalculates zs and update sliders accordingly
std::vector<double> zs = m_canvas->get_current_print_zs(true);

View File

@ -58,6 +58,9 @@ public:
void delete_selected();
void mirror_selection(Axis axis);
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
void update_toolbar_items_visibility();
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
void enable_toolbar_item(const std::string& name, bool enable);
int check_volumes_outside_state() const;

View File

@ -44,7 +44,8 @@ KBShortcutsDialog::KBShortcutsDialog()
for (auto& sc : m_full_shortcuts)
{
auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer;
// auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer;
auto sizer = sc.second.second == 0 ? l_sizer : r_sizer;
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
@ -61,7 +62,7 @@ KBShortcutsDialog::KBShortcutsDialog()
auto grid_sizer = new wxFlexGridSizer(2, 5, 15);
sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15);
for (auto pair : sc.second)
for (auto pair : sc.second.first)
{
auto shortcut = new wxStaticText(panel, wxID_ANY, _(pair.first));
shortcut->SetFont(bold_font);
@ -95,6 +96,8 @@ void KBShortcutsDialog::fill_shortcuts()
const std::string alt = "Alt+";
#endif // __WXOSX__
m_full_shortcuts.reserve(4);
Shortcuts main_shortcuts;
main_shortcuts.reserve(25);
@ -122,7 +125,7 @@ void KBShortcutsDialog::fill_shortcuts()
main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list")));
main_shortcuts.push_back(Shortcut("Shift+LeftMouse", L("Select multiple object/Move multiple object")));
m_full_shortcuts.emplace(_(L("Main Shortcuts")), main_shortcuts);
m_full_shortcuts.push_back(std::make_pair( _(L("Main Shortcuts")), std::make_pair(main_shortcuts, 0) ));
Shortcuts plater_shortcuts;
@ -138,6 +141,8 @@ void KBShortcutsDialog::fill_shortcuts()
plater_shortcuts.push_back(Shortcut("C", L("Gizmo cut")));
plater_shortcuts.push_back(Shortcut("F", L("Gizmo Place face on bed")));
plater_shortcuts.push_back(Shortcut("L", L("Gizmo SLA support points")));
plater_shortcuts.push_back(Shortcut("Shift+", L("Press to snap by 5% in Gizmo scale\nor by 1mm in Gizmo move")));
plater_shortcuts.push_back(Shortcut(alt, L("Press to scale or rotate selected objects\naround their own center")));
plater_shortcuts.push_back(Shortcut("B", L("Zoom to Bed")));
plater_shortcuts.push_back(Shortcut("Z", L("Zoom to all objects in scene, if none selected")));
plater_shortcuts.push_back(Shortcut("Z", L("Zoom to selected object")));
@ -145,16 +150,40 @@ void KBShortcutsDialog::fill_shortcuts()
plater_shortcuts.push_back(Shortcut("O", L("Zoom out")));
plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo, keep object selection")));
m_full_shortcuts.emplace(_(L("Plater Shortcuts")), plater_shortcuts);
m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, 1)));
// Shortcuts gizmo_shortcuts;
// gizmo_shortcuts.reserve(2);
//
// gizmo_shortcuts.push_back(Shortcut("Shift+", L("Press to snap by 5% in Gizmo Scale\n or by 1mm in Gizmo Move")));
// gizmo_shortcuts.push_back(Shortcut(alt, L("Press to scale or rotate selected objects around their own center")));
//
// m_full_shortcuts.push_back(std::make_pair(_(L("Gizmo Shortcuts")), std::make_pair(gizmo_shortcuts, 1)));
Shortcuts preview_shortcuts;
preview_shortcuts.reserve(2);
preview_shortcuts.reserve(4);
preview_shortcuts.push_back(Shortcut(L("Arrow Up"), L("Upper Layer")));
preview_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Lower Layer")));
preview_shortcuts.push_back(Shortcut("U", L("Upper Layer")));
preview_shortcuts.push_back(Shortcut("D", L("Lower Layer")));
m_full_shortcuts.emplace(_(L("Preview Shortcuts")), preview_shortcuts);
m_full_shortcuts.push_back(std::make_pair( _(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, 0) ));
Shortcuts layers_slider_shortcuts;
layers_slider_shortcuts.reserve(6);
layers_slider_shortcuts.push_back(Shortcut(L("Arrow Up"), L("Move current slider thump Up")));
layers_slider_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Move current slider thump Down")));
layers_slider_shortcuts.push_back(Shortcut(L("Arrow Left"), L("Set upper thumb to current slider thumb")));
layers_slider_shortcuts.push_back(Shortcut(L("Arrow Right"),L("Set lower thumb to current slider thumb")));
layers_slider_shortcuts.push_back(Shortcut("+", L("Add color change marker for current layer")));
layers_slider_shortcuts.push_back(Shortcut("-", L("Delete color change marker for current layer")));
m_full_shortcuts.push_back(std::make_pair( _(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, 1) ));
}
void KBShortcutsDialog::onCloseDialog(wxEvent &)

View File

@ -11,11 +11,11 @@ class KBShortcutsDialog : public wxDialog
{
typedef std::pair<std::string, std::string> Shortcut;
typedef std::vector< Shortcut > Shortcuts;
typedef std::map<wxString, Shortcuts> ShortcutsMap;
typedef std::vector< std::pair<wxString, std::pair<Shortcuts, int>> > ShortcutsVec;
wxString text_info {wxEmptyString};
ShortcutsMap m_full_shortcuts;
ShortcutsVec m_full_shortcuts;
public:
KBShortcutsDialog();

View File

@ -22,6 +22,7 @@
#include "AppConfig.hpp"
#include "PrintHostDialogs.hpp"
#include "wxExtensions.hpp"
#include "GUI_ObjectList.hpp"
#include "I18N.hpp"
#include <fstream>
@ -132,6 +133,8 @@ void MainFrame::init_tabpanel()
wxGetApp().plater_ = m_plater;
m_tabpanel->AddPage(m_plater, _(L("Plater")));
wxGetApp().obj_list()->create_popup_menus();
// The following event is emited by Tab implementation on config value change.
Bind(EVT_TAB_VALUE_CHANGED, &MainFrame::on_value_changed, this);

View File

@ -896,7 +896,7 @@ std::vector<PresetComboBox*>& Sidebar::combos_filament()
class PlaterDropTarget : public wxFileDropTarget
{
public:
PlaterDropTarget(Plater *plater) : plater(plater) {}
PlaterDropTarget(Plater *plater) : plater(plater) { this->SetDefaultAction(wxDragCopy); }
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames);
@ -1031,7 +1031,7 @@ struct Plater::priv
void update_restart_background_process(bool force_scene_update, bool force_preview_update);
void export_gcode(fs::path output_path, PrintHostJob upload_job);
void reload_from_disk();
void fix_through_netfabb(const int obj_idx);
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
void set_current_panel(wxPanel* panel);
@ -1717,6 +1717,8 @@ void Plater::priv::reset()
object_list_changed();
update();
// The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here
this->sidebar->show_sliced_info_sizer(false);
auto& config = wxGetApp().preset_bundle->project_config;
config.option<ConfigOptionFloats>("colorprint_heights")->values.clear();
@ -2104,7 +2106,7 @@ void Plater::priv::reload_from_disk()
remove(obj_orig_idx);
}
void Plater::priv::fix_through_netfabb(const int obj_idx)
void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/)
{
if (obj_idx < 0)
return;
@ -2438,6 +2440,8 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
}
menu->AppendSeparator();
sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu);
wxMenu* mirror_menu = new wxMenu();
if (mirror_menu == nullptr)
return false;
@ -2644,6 +2648,10 @@ bool Plater::priv::can_mirror() const
void Plater::priv::update_object_menu()
{
sidebar->obj_list()->append_menu_items_add_volume(&object_menu);
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
if (view3D != nullptr)
view3D->update_toolbar_items_visibility();
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
}
// Plater / Public
@ -3148,7 +3156,7 @@ void Plater::changed_object(int obj_idx)
this->p->schedule_background_process();
}
void Plater::fix_through_netfabb(const int obj_idx) { p->fix_through_netfabb(obj_idx); }
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
void Plater::update_object_menu() { p->update_object_menu(); }

View File

@ -147,7 +147,7 @@ public:
void export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path());
void reslice();
void changed_object(int obj_idx);
void fix_through_netfabb(const int obj_idx);
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
void send_gcode();
void on_extruders_change(int extruders_count);

View File

@ -323,7 +323,10 @@ const std::vector<std::string>& Preset::print_options()
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
"max_volumetric_speed",
#ifdef HAS_PRESSURE_EQUALIZER
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
@ -337,7 +340,7 @@ const std::vector<std::string>& Preset::print_options()
, "support_material_contact_distance_top"
, "support_material_contact_distance_bottom"
, "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "output_filename_format", "post_process", "perimeter_extruder",
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
@ -356,7 +359,6 @@ const std::vector<std::string>& Preset::print_options()
, "remove_small_gaps"
, "infill_not_connected"
, "first_layer_infill_speed"
, "label_printed_objects"
, "thin_walls_min_width"
};
return s_opts;
@ -1180,7 +1182,7 @@ std::string PresetCollection::name() const
case Preset::TYPE_PRINT: return L("print");
case Preset::TYPE_FILAMENT: return L("filament");
case Preset::TYPE_SLA_PRINT: return L("SLA print");
case Preset::TYPE_SLA_MATERIAL: return L("SLA material");
case Preset::TYPE_SLA_MATERIAL: return L("SLA material");
case Preset::TYPE_PRINTER: return L("printer");
default: return "invalid";
}

View File

@ -1081,8 +1081,10 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Autospeed (advanced)")));
optgroup->append_single_option_line("max_print_speed");
optgroup->append_single_option_line("max_volumetric_speed");
#ifdef HAS_PRESSURE_EQUALIZER
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive");
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative");
#endif /* HAS_PRESSURE_EQUALIZER */
page = add_options_page(_(L("Multiple Extruders")), "funnel.png");
optgroup = page->new_optgroup(_(L("Extruders")));
@ -1154,7 +1156,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(_(L("Output file")));
optgroup->append_single_option_line("gcode_comments");
optgroup->append_single_option_line("label_printed_objects");
optgroup->append_single_option_line("gcode_label_objects");
option = optgroup->get_option("output_filename_format");
option.opt.full_width = true;
optgroup->append_single_option_line(option);

View File

@ -1867,8 +1867,10 @@ void PrusaDoubleSlider::draw_colored_band(wxDC& dc)
return;
}
const std::vector<unsigned char>& clr_bytes = Slic3r::GCodePreviewData::Range::Default_Colors[0].as_bytes();
wxColour clr = wxColour(clr_bytes[0], clr_bytes[1], clr_bytes[2], clr_bytes[3]);
const std::vector<std::string>& colors = Slic3r::GCodePreviewData::ColorPrintColors();
const size_t colors_cnt = colors.size();
wxColour clr(colors[0]);
dc.SetPen(clr);
dc.SetBrush(clr);
dc.DrawRectangle(main_band);
@ -1876,15 +1878,13 @@ void PrusaDoubleSlider::draw_colored_band(wxDC& dc)
int i = 1;
for (auto tick : m_ticks)
{
if (i == Slic3r::GCodePreviewData::Range::Colors_Count)
if (i == colors_cnt)
i = 0;
const wxCoord pos = get_position_from_value(tick);
is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) :
main_band.SetBottom(pos-1);
const std::vector<unsigned char>& clr_b = Slic3r::GCodePreviewData::Range::Default_Colors[i].as_bytes();
clr = wxColour(clr_b[0], clr_b[1], clr_b[2], clr_b[3]);
clr = wxColour(colors[i]);
dc.SetPen(clr);
dc.SetBrush(clr);
dc.DrawRectangle(main_band);