mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-15 01:26:10 +08:00
Merge remote-tracking branch 'remotes/prusa/master' into masterPE
This commit is contained in:
commit
0680d6fe05
10
.github/ISSUE_TEMPLATE.md
vendored
10
.github/ISSUE_TEMPLATE.md
vendored
@ -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)_
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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()), © - 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 © : 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: " <<
|
||||
|
@ -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.
|
||||
|
@ -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]),
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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 )
|
||||
|
@ -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; }
|
||||
|
@ -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 */
|
||||
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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, ¤t_program_id);
|
||||
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_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, ¤t_program_id);
|
||||
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 &)
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(); }
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user