Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_transformations
This commit is contained in:
commit
61536981ea
16 changed files with 155 additions and 149 deletions
|
@ -1032,6 +1032,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||||
m_pressure_equalizer = make_unique<PressureEqualizer>(print.config());
|
m_pressure_equalizer = make_unique<PressureEqualizer>(print.config());
|
||||||
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
|
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
|
||||||
|
|
||||||
|
if (print.config().avoid_crossing_curled_overhangs){
|
||||||
|
this->m_avoid_crossing_curled_overhangs.init_bed_shape(get_bed_shape(print.config()));
|
||||||
|
}
|
||||||
|
|
||||||
// Write information on the generator.
|
// Write information on the generator.
|
||||||
file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
||||||
|
|
||||||
|
@ -2107,8 +2111,12 @@ LayerResult GCode::process_layer(
|
||||||
if (this->config().avoid_crossing_curled_overhangs) {
|
if (this->config().avoid_crossing_curled_overhangs) {
|
||||||
m_avoid_crossing_curled_overhangs.clear();
|
m_avoid_crossing_curled_overhangs.clear();
|
||||||
for (const ObjectLayerToPrint &layer_to_print : layers) {
|
for (const ObjectLayerToPrint &layer_to_print : layers) {
|
||||||
m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.object_layer, Point(scaled(this->origin())));
|
if (layer_to_print.object() == nullptr)
|
||||||
m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.support_layer, Point(scaled(this->origin())));
|
continue;
|
||||||
|
for (const auto &instance : layer_to_print.object()->instances()) {
|
||||||
|
m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.object_layer, instance.shift);
|
||||||
|
m_avoid_crossing_curled_overhangs.add_obstacles(layer_to_print.support_layer, instance.shift);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2922,19 +2930,19 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||||
+ float_to_string_decimal_point(m_last_height) + "\n";
|
+ float_to_string_decimal_point(m_last_height) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string comment;
|
std::string cooling_marker_setspeed_comments;
|
||||||
if (m_enable_cooling_markers) {
|
if (m_enable_cooling_markers) {
|
||||||
if (path.role().is_bridge())
|
if (path.role().is_bridge())
|
||||||
gcode += ";_BRIDGE_FAN_START\n";
|
gcode += ";_BRIDGE_FAN_START\n";
|
||||||
else
|
else
|
||||||
comment = ";_EXTRUDE_SET_SPEED";
|
cooling_marker_setspeed_comments = ";_EXTRUDE_SET_SPEED";
|
||||||
if (path.role() == ExtrusionRole::ExternalPerimeter)
|
if (path.role() == ExtrusionRole::ExternalPerimeter)
|
||||||
comment += ";_EXTERNAL_PERIMETER";
|
cooling_marker_setspeed_comments += ";_EXTERNAL_PERIMETER";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variable_speed) {
|
if (!variable_speed) {
|
||||||
// F is mm per minute.
|
// F is mm per minute.
|
||||||
gcode += m_writer.set_speed(F, "", comment);
|
gcode += m_writer.set_speed(F, "", cooling_marker_setspeed_comments);
|
||||||
double path_length = 0.;
|
double path_length = 0.;
|
||||||
std::string comment;
|
std::string comment;
|
||||||
if (m_config.gcode_comments) {
|
if (m_config.gcode_comments) {
|
||||||
|
@ -2958,7 +2966,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||||
marked_comment += description_bridge;
|
marked_comment += description_bridge;
|
||||||
}
|
}
|
||||||
double last_set_speed = new_points[0].speed * 60.0;
|
double last_set_speed = new_points[0].speed * 60.0;
|
||||||
gcode += m_writer.set_speed(last_set_speed, "", comment);
|
gcode += m_writer.set_speed(last_set_speed, "", cooling_marker_setspeed_comments);
|
||||||
Vec2d prev = this->point_to_gcode_quantized(new_points[0].p);
|
Vec2d prev = this->point_to_gcode_quantized(new_points[0].p);
|
||||||
for (size_t i = 1; i < new_points.size(); i++) {
|
for (size_t i = 1; i < new_points.size(); i++) {
|
||||||
const ProcessedPoint& processed_point = new_points[i];
|
const ProcessedPoint& processed_point = new_points[i];
|
||||||
|
@ -2968,7 +2976,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
||||||
prev = p;
|
prev = p;
|
||||||
double new_speed = processed_point.speed * 60.0;
|
double new_speed = processed_point.speed * 60.0;
|
||||||
if (last_set_speed != new_speed) {
|
if (last_set_speed != new_speed) {
|
||||||
gcode += m_writer.set_speed(new_speed, "", comment);
|
gcode += m_writer.set_speed(new_speed, "", cooling_marker_setspeed_comments);
|
||||||
last_set_speed = new_speed;
|
last_set_speed = new_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -472,7 +472,7 @@ const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> GCodeProces
|
||||||
{ EProducer::Slic3r, "generated by Slic3r" },
|
{ EProducer::Slic3r, "generated by Slic3r" },
|
||||||
{ EProducer::SuperSlicer, "generated by SuperSlicer" },
|
{ EProducer::SuperSlicer, "generated by SuperSlicer" },
|
||||||
{ EProducer::Cura, "Cura_SteamEngine" },
|
{ EProducer::Cura, "Cura_SteamEngine" },
|
||||||
{ EProducer::Simplify3D, "G-Code generated by Simplify3D(R)" },
|
{ EProducer::Simplify3D, "generated by Simplify3D(R)" },
|
||||||
{ EProducer::CraftWare, "CraftWare" },
|
{ EProducer::CraftWare, "CraftWare" },
|
||||||
{ EProducer::ideaMaker, "ideaMaker" },
|
{ EProducer::ideaMaker, "ideaMaker" },
|
||||||
{ EProducer::KissSlicer, "KISSlicer" },
|
{ EProducer::KissSlicer, "KISSlicer" },
|
||||||
|
@ -2025,10 +2025,10 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ; layer
|
// ; layer | ;layer
|
||||||
tag = " layer";
|
tag = "layer";
|
||||||
pos = cmt.find(tag);
|
pos = cmt.find(tag);
|
||||||
if (pos == 0) {
|
if (pos == 0 || pos == 1) {
|
||||||
// skip lines "; layer end"
|
// skip lines "; layer end"
|
||||||
const std::string_view data = cmt.substr(pos + tag.length());
|
const std::string_view data = cmt.substr(pos + tag.length());
|
||||||
size_t end_start = data.find("end");
|
size_t end_start = data.find("end");
|
||||||
|
@ -2402,7 +2402,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
if (m_forced_height > 0.0f)
|
if (m_forced_height > 0.0f)
|
||||||
m_height = m_forced_height;
|
m_height = m_forced_height;
|
||||||
else if (m_layer_id == 0)
|
else if (m_layer_id == 0)
|
||||||
m_height = (m_end_position[Z] <= double(m_first_layer_height)) ? m_end_position[Z] : m_first_layer_height;
|
m_height = std::min((float)m_end_position[Z], m_first_layer_height + m_z_offset);
|
||||||
else if (line.comment() != INTERNAL_G2G3_TAG){
|
else if (line.comment() != INTERNAL_G2G3_TAG){
|
||||||
if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0)
|
if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0)
|
||||||
m_height = m_end_position[Z] - m_extruded_last_z;
|
m_height = m_end_position[Z] - m_extruded_last_z;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "JumpPointSearch.hpp"
|
#include "JumpPointSearch.hpp"
|
||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
|
#include "ExPolygon.hpp"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include "libslic3r/AStar.hpp"
|
#include "libslic3r/AStar.hpp"
|
||||||
#include "libslic3r/KDTreeIndirect.hpp"
|
#include "libslic3r/KDTreeIndirect.hpp"
|
||||||
|
@ -181,17 +182,18 @@ public:
|
||||||
void JPSPathFinder::clear()
|
void JPSPathFinder::clear()
|
||||||
{
|
{
|
||||||
inpassable.clear();
|
inpassable.clear();
|
||||||
obstacle_max = Pixel(std::numeric_limits<coord_t>::min(), std::numeric_limits<coord_t>::min());
|
max_search_box.max = Pixel(std::numeric_limits<coord_t>::min(), std::numeric_limits<coord_t>::min());
|
||||||
obstacle_min = Pixel(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max());
|
max_search_box.min = Pixel(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max());
|
||||||
|
add_obstacles(bed_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JPSPathFinder::add_obstacles(const Lines &obstacles)
|
void JPSPathFinder::add_obstacles(const Lines &obstacles)
|
||||||
{
|
{
|
||||||
auto store_obstacle = [&](coord_t x, coord_t y) {
|
auto store_obstacle = [&](coord_t x, coord_t y) {
|
||||||
obstacle_max.x() = std::max(obstacle_max.x(), x);
|
max_search_box.max.x() = std::max(max_search_box.max.x(), x);
|
||||||
obstacle_max.y() = std::max(obstacle_max.y(), y);
|
max_search_box.max.y() = std::max(max_search_box.max.y(), y);
|
||||||
obstacle_min.x() = std::min(obstacle_min.x(), x);
|
max_search_box.min.x() = std::min(max_search_box.min.x(), x);
|
||||||
obstacle_min.y() = std::min(obstacle_min.y(), y);
|
max_search_box.min.y() = std::min(max_search_box.min.y(), y);
|
||||||
inpassable.insert(Pixel{x, y});
|
inpassable.insert(Pixel{x, y});
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -240,9 +242,9 @@ Polyline JPSPathFinder::find_path(const Point &p0, const Point &p1)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBox search_box({start, end, obstacle_max, obstacle_min});
|
BoundingBox search_box = max_search_box;
|
||||||
search_box.max += Pixel(1, 1);
|
search_box.max -= Pixel(1, 1);
|
||||||
search_box.min -= Pixel(1, 1);
|
search_box.min += Pixel(1, 1);
|
||||||
|
|
||||||
BoundingBox bounding_square(Points{start, end});
|
BoundingBox bounding_square(Points{start, end});
|
||||||
bounding_square.max += Pixel(5, 5);
|
bounding_square.max += Pixel(5, 5);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define SRC_LIBSLIC3R_JUMPPOINTSEARCH_HPP_
|
#define SRC_LIBSLIC3R_JUMPPOINTSEARCH_HPP_
|
||||||
|
|
||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
|
#include "Polygon.hpp"
|
||||||
#include "libslic3r/Layer.hpp"
|
#include "libslic3r/Layer.hpp"
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
#include "libslic3r/Polyline.hpp"
|
#include "libslic3r/Polyline.hpp"
|
||||||
|
@ -16,18 +17,19 @@ class JPSPathFinder
|
||||||
using Pixel = Point;
|
using Pixel = Point;
|
||||||
std::unordered_set<Pixel, PointHash> inpassable;
|
std::unordered_set<Pixel, PointHash> inpassable;
|
||||||
coordf_t print_z;
|
coordf_t print_z;
|
||||||
Pixel obstacle_min;
|
BoundingBox max_search_box;
|
||||||
Pixel obstacle_max;
|
Lines bed_shape;
|
||||||
|
|
||||||
const coord_t resolution = scaled(1.5);
|
const coord_t resolution = scaled(1.5);
|
||||||
Pixel pixelize(const Point &p) { return p / resolution; }
|
Pixel pixelize(const Point &p) { return p / resolution; }
|
||||||
Point unpixelize(const Pixel &p) { return p * resolution; }
|
Point unpixelize(const Pixel &p) { return p * resolution; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JPSPathFinder() { clear(); };
|
JPSPathFinder() = default;
|
||||||
void clear();
|
void init_bed_shape(const Points &bed_shape) { this->bed_shape = (to_lines(Polygon{bed_shape})); };
|
||||||
void add_obstacles(const Lines &obstacles);
|
void clear();
|
||||||
void add_obstacles(const Layer* layer, const Point& global_origin);
|
void add_obstacles(const Lines &obstacles);
|
||||||
|
void add_obstacles(const Layer *layer, const Point &global_origin);
|
||||||
Polyline find_path(const Point &start, const Point &end);
|
Polyline find_path(const Point &start, const Point &end);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1043,6 +1043,7 @@ void estimate_supports_malformations(SupportLayerPtrs &layers, float flow_width,
|
||||||
AABBTreeLines::LinesDistancer<ExtrusionLine> prev_layer_lines{};
|
AABBTreeLines::LinesDistancer<ExtrusionLine> prev_layer_lines{};
|
||||||
|
|
||||||
for (SupportLayer *l : layers) {
|
for (SupportLayer *l : layers) {
|
||||||
|
l->malformed_lines.clear();
|
||||||
std::vector<ExtrusionLine> current_layer_lines;
|
std::vector<ExtrusionLine> current_layer_lines;
|
||||||
|
|
||||||
for (const ExtrusionEntity *extrusion : l->support_fills.flatten().entities) {
|
for (const ExtrusionEntity *extrusion : l->support_fills.flatten().entities) {
|
||||||
|
@ -1114,6 +1115,7 @@ void estimate_malformations(LayerPtrs &layers, const Params ¶ms)
|
||||||
LD prev_layer_lines{};
|
LD prev_layer_lines{};
|
||||||
|
|
||||||
for (Layer *l : layers) {
|
for (Layer *l : layers) {
|
||||||
|
l->malformed_lines.clear();
|
||||||
std::vector<Linef> boundary_lines = l->lower_layer != nullptr ? to_unscaled_linesf(l->lower_layer->lslices) : std::vector<Linef>();
|
std::vector<Linef> boundary_lines = l->lower_layer != nullptr ? to_unscaled_linesf(l->lower_layer->lslices) : std::vector<Linef>();
|
||||||
AABBTreeLines::LinesDistancer<Linef> prev_layer_boundary{std::move(boundary_lines)};
|
AABBTreeLines::LinesDistancer<Linef> prev_layer_boundary{std::move(boundary_lines)};
|
||||||
std::vector<ExtrusionLine> current_layer_lines;
|
std::vector<ExtrusionLine> current_layer_lines;
|
||||||
|
|
|
@ -2785,7 +2785,7 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
|
||||||
{
|
{
|
||||||
// Walk over all installed Printer presets and verify whether there is a filament or SLA material profile installed at the same PresetBundle,
|
// Walk over all installed Printer presets and verify whether there is a filament or SLA material profile installed at the same PresetBundle,
|
||||||
// which is compatible with it.
|
// which is compatible with it.
|
||||||
const auto printer_models_missing_materials = [this, only_for_model_id](PrinterTechnology technology, const std::string §ion)
|
const auto printer_models_missing_materials = [this, only_for_model_id](PrinterTechnology technology, const std::string §ion, bool no_templates)
|
||||||
{
|
{
|
||||||
const std::map<std::string, std::string> &appconfig_presets = appconfig_new.has_section(section) ? appconfig_new.get_section(section) : std::map<std::string, std::string>();
|
const std::map<std::string, std::string> &appconfig_presets = appconfig_new.has_section(section) ? appconfig_new.get_section(section) : std::map<std::string, std::string>();
|
||||||
std::set<const VendorProfile::PrinterModel*> printer_models_without_material;
|
std::set<const VendorProfile::PrinterModel*> printer_models_without_material;
|
||||||
|
@ -2805,15 +2805,16 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
|
||||||
has_material = true;
|
has_material = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find if preset.first is part of the templates profile (up is searching if preset.first is part of printer vendor preset)
|
// find if preset.first is part of the templates profile (up is searching if preset.first is part of printer vendor preset)
|
||||||
for (const auto& bp : bundles) {
|
if (!no_templates) {
|
||||||
if (!bp.second.preset_bundle->vendors.empty() && bp.second.preset_bundle->vendors.begin()->second.templates_profile) {
|
for (const auto& bp : bundles) {
|
||||||
const PresetCollection& template_materials = bp.second.preset_bundle->materials(technology);
|
if (!bp.second.preset_bundle->vendors.empty() && bp.second.preset_bundle->vendors.begin()->second.templates_profile) {
|
||||||
const Preset* template_material = template_materials.find_preset(preset.first, false);
|
const PresetCollection& template_materials = bp.second.preset_bundle->materials(technology);
|
||||||
if (template_material && is_compatible_with_printer(PresetWithVendorProfile(*template_material, &bp.second.preset_bundle->vendors.begin()->second), PresetWithVendorProfile(printer, nullptr))) {
|
const Preset* template_material = template_materials.find_preset(preset.first, false);
|
||||||
has_material = true;
|
if (template_material && is_compatible_with_printer(PresetWithVendorProfile(*template_material, &bp.second.preset_bundle->vendors.begin()->second), PresetWithVendorProfile(printer, nullptr))) {
|
||||||
break;
|
has_material = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2872,15 +2873,17 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool no_templates = wxGetApp().app_config->get("no_templates") == "1";
|
||||||
|
|
||||||
if (any_fff_selected && (technology & T_FFF)) {
|
if (any_fff_selected && (technology & T_FFF)) {
|
||||||
std::set<const VendorProfile::PrinterModel*> printer_models_without_material = printer_models_missing_materials(ptFFF, AppConfig::SECTION_FILAMENTS);
|
std::set<const VendorProfile::PrinterModel*> printer_models_without_material = printer_models_missing_materials(ptFFF, AppConfig::SECTION_FILAMENTS, no_templates);
|
||||||
if (! printer_models_without_material.empty()) {
|
if (! printer_models_without_material.empty()) {
|
||||||
if (only_for_model_id.empty())
|
if (only_for_model_id.empty())
|
||||||
ask_and_select_default_materials(
|
ask_and_select_default_materials(
|
||||||
_L("The following FFF printer models have no filament selected:") +
|
_L("The following FFF printer models have no filament selected:") +
|
||||||
"\n\n\t" +
|
"\n\n" +
|
||||||
printer_model_list(printer_models_without_material) +
|
printer_model_list(printer_models_without_material) +
|
||||||
"\n\n\t" +
|
"\n\n" +
|
||||||
_L("Do you want to select default filaments for these FFF printer models?"),
|
_L("Do you want to select default filaments for these FFF printer models?"),
|
||||||
printer_models_without_material,
|
printer_models_without_material,
|
||||||
T_FFF);
|
T_FFF);
|
||||||
|
@ -2891,14 +2894,14 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (any_sla_selected && (technology & T_SLA)) {
|
if (any_sla_selected && (technology & T_SLA)) {
|
||||||
std::set<const VendorProfile::PrinterModel*> printer_models_without_material = printer_models_missing_materials(ptSLA, AppConfig::SECTION_MATERIALS);
|
std::set<const VendorProfile::PrinterModel*> printer_models_without_material = printer_models_missing_materials(ptSLA, AppConfig::SECTION_MATERIALS, no_templates);
|
||||||
if (! printer_models_without_material.empty()) {
|
if (! printer_models_without_material.empty()) {
|
||||||
if (only_for_model_id.empty())
|
if (only_for_model_id.empty())
|
||||||
ask_and_select_default_materials(
|
ask_and_select_default_materials(
|
||||||
_L("The following SLA printer models have no materials selected:") +
|
_L("The following SLA printer models have no materials selected:") +
|
||||||
"\n\n\t" +
|
"\n\n" +
|
||||||
printer_model_list(printer_models_without_material) +
|
printer_model_list(printer_models_without_material) +
|
||||||
"\n\n\t" +
|
"\n\n" +
|
||||||
_L("Do you want to select default SLA materials for these printer models?"),
|
_L("Do you want to select default SLA materials for these printer models?"),
|
||||||
printer_models_without_material,
|
printer_models_without_material,
|
||||||
T_SLA);
|
T_SLA);
|
||||||
|
|
|
@ -2250,9 +2250,9 @@ void GCodeViewer::load_shells(const Print& print)
|
||||||
const PrintConfig& config = print.config();
|
const PrintConfig& config = print.config();
|
||||||
const size_t extruders_count = config.nozzle_diameter.size();
|
const size_t extruders_count = config.nozzle_diameter.size();
|
||||||
if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) {
|
if (extruders_count > 1 && config.wipe_tower && !config.complete_objects) {
|
||||||
const float depth = print.wipe_tower_data(extruders_count).depth;
|
const WipeTowerData& wipe_tower_data = print.wipe_tower_data(extruders_count);
|
||||||
const float brim_width = print.wipe_tower_data(extruders_count).brim_width;
|
const float depth = wipe_tower_data.depth;
|
||||||
|
const float brim_width = wipe_tower_data.brim_width;
|
||||||
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
|
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
|
||||||
!print.is_step_done(psWipeTower), brim_width);
|
!print.is_step_done(psWipeTower), brim_width);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1972,31 +1972,30 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
// Should the wipe tower be visualized ?
|
// Should the wipe tower be visualized ?
|
||||||
unsigned int extruders_count = (unsigned int)dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"))->values.size();
|
unsigned int extruders_count = (unsigned int)dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"))->values.size();
|
||||||
|
|
||||||
bool wt = dynamic_cast<const ConfigOptionBool*>(m_config->option("wipe_tower"))->value;
|
const bool wt = dynamic_cast<const ConfigOptionBool*>(m_config->option("wipe_tower"))->value;
|
||||||
bool co = dynamic_cast<const ConfigOptionBool*>(m_config->option("complete_objects"))->value;
|
const bool co = dynamic_cast<const ConfigOptionBool*>(m_config->option("complete_objects"))->value;
|
||||||
|
|
||||||
if (extruders_count > 1 && wt && !co) {
|
if (extruders_count > 1 && wt && !co) {
|
||||||
// Height of a print (Show at least a slab)
|
// Height of a print (Show at least a slab)
|
||||||
double height = std::max(m_model->bounding_box().max(2), 10.0);
|
const double height = std::max(m_model->bounding_box().max.z(), 10.0);
|
||||||
|
|
||||||
float x = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_x"))->value;
|
const float x = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_x"))->value;
|
||||||
float y = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_y"))->value;
|
const float y = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_y"))->value;
|
||||||
float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
|
const float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
|
||||||
float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
|
const float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
|
||||||
|
const float bw = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_brim_width"))->value;
|
||||||
|
|
||||||
const Print *print = m_process->fff_print();
|
const Print *print = m_process->fff_print();
|
||||||
|
const float depth = print->wipe_tower_data(extruders_count).depth;
|
||||||
float depth = print->wipe_tower_data(extruders_count).depth;
|
|
||||||
float brim_width = print->wipe_tower_data(extruders_count).brim_width;
|
|
||||||
|
|
||||||
#if ENABLE_OPENGL_ES
|
#if ENABLE_OPENGL_ES
|
||||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||||
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
|
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
|
||||||
brim_width, &m_wipe_tower_mesh);
|
bw, &m_wipe_tower_mesh);
|
||||||
#else
|
#else
|
||||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||||
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
|
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
|
||||||
brim_width);
|
bw);
|
||||||
#endif // ENABLE_OPENGL_ES
|
#endif // ENABLE_OPENGL_ES
|
||||||
if (volume_idx_wipe_tower_old != -1)
|
if (volume_idx_wipe_tower_old != -1)
|
||||||
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
|
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
|
||||||
|
|
|
@ -2175,6 +2175,10 @@ void ObjectList::split()
|
||||||
|
|
||||||
take_snapshot(_(L("Split to Parts")));
|
take_snapshot(_(L("Split to Parts")));
|
||||||
|
|
||||||
|
// Before splitting volume we have to remove all custom supports, seams, and multimaterial painting.
|
||||||
|
wxGetApp().plater()->clear_before_change_mesh(obj_idx, _u8L("Custom supports, seams and multimaterial painting were "
|
||||||
|
"removed after splitting the object."));
|
||||||
|
|
||||||
volume->split(nozzle_dmrs_cnt);
|
volume->split(nozzle_dmrs_cnt);
|
||||||
|
|
||||||
(*m_objects)[obj_idx]->input_file.clear();
|
(*m_objects)[obj_idx]->input_file.clear();
|
||||||
|
@ -2186,6 +2190,10 @@ void ObjectList::split()
|
||||||
changed_object(obj_idx);
|
changed_object(obj_idx);
|
||||||
// update printable state for new volumes on canvas3D
|
// update printable state for new volumes on canvas3D
|
||||||
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object(obj_idx);
|
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object(obj_idx);
|
||||||
|
|
||||||
|
// After removing custom supports, seams, and multimaterial painting, we have to update info about the object to remove information about
|
||||||
|
// custom supports, seams, and multimaterial painting in the right panel.
|
||||||
|
wxGetApp().obj_list()->update_info_items(obj_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::merge(bool to_multipart_object)
|
void ObjectList::merge(bool to_multipart_object)
|
||||||
|
@ -4682,7 +4690,8 @@ void ObjectList::fix_through_netfabb()
|
||||||
msg += "\n";
|
msg += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
plater->clear_before_change_mesh(obj_idx);
|
plater->clear_before_change_mesh(obj_idx, _u8L("Custom supports, seams and multimaterial painting were "
|
||||||
|
"removed after repairing the mesh."));
|
||||||
std::string res;
|
std::string res;
|
||||||
if (!fix_model_by_win10_sdk_gui(*(object(obj_idx)), vol_idx, progress_dlg, msg, res))
|
if (!fix_model_by_win10_sdk_gui(*(object(obj_idx)), vol_idx, progress_dlg, msg, res))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -360,11 +360,12 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::shift_cut_z(double delta)
|
void GLGizmoCut3D::shift_cut(double delta)
|
||||||
{
|
{
|
||||||
Vec3d new_cut_center = m_plane_center;
|
Vec3d starting_vec = m_rotation_m * Vec3d::UnitZ();
|
||||||
new_cut_center[Z] += delta;
|
if (starting_vec.norm() != 0.0)
|
||||||
set_center(new_cut_center);
|
starting_vec.normalize();
|
||||||
|
set_center(m_plane_center + starting_vec * delta, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec)
|
void GLGizmoCut3D::rotate_vec3d_around_plane_center(Vec3d&vec)
|
||||||
|
@ -453,15 +454,9 @@ void GLGizmoCut3D::update_clipper()
|
||||||
update_raycasters_for_picking_transform();
|
update_raycasters_for_picking_transform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::update_clipper_on_render()
|
void GLGizmoCut3D::set_center(const Vec3d& center, bool update_tbb /*=false*/)
|
||||||
{
|
{
|
||||||
update_clipper();
|
set_center_pos(center, update_tbb);
|
||||||
force_update_clipper_on_render = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLGizmoCut3D::set_center(const Vec3d& center)
|
|
||||||
{
|
|
||||||
set_center_pos(center);
|
|
||||||
update_clipper();
|
update_clipper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +579,7 @@ void GLGizmoCut3D::render_move_center_input(int axis)
|
||||||
|
|
||||||
if (in_val != val) {
|
if (in_val != val) {
|
||||||
move[axis] = val;
|
move[axis] = val;
|
||||||
set_center(move);
|
set_center(move, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,21 +883,17 @@ bool GLGizmoCut3D::on_init()
|
||||||
|
|
||||||
void GLGizmoCut3D::on_load(cereal::BinaryInputArchive& ar)
|
void GLGizmoCut3D::on_load(cereal::BinaryInputArchive& ar)
|
||||||
{
|
{
|
||||||
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,//m_selected,
|
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,
|
||||||
// m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id,
|
|
||||||
m_ar_plane_center, m_rotation_m);
|
m_ar_plane_center, m_rotation_m);
|
||||||
|
|
||||||
set_center_pos(m_ar_plane_center, true);
|
set_center_pos(m_ar_plane_center, true);
|
||||||
|
|
||||||
force_update_clipper_on_render = true;
|
|
||||||
|
|
||||||
m_parent.request_extra_frame();
|
m_parent.request_extra_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::on_save(cereal::BinaryOutputArchive& ar) const
|
void GLGizmoCut3D::on_save(cereal::BinaryOutputArchive& ar) const
|
||||||
{
|
{
|
||||||
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,//m_selected,
|
ar( m_keep_upper, m_keep_lower, m_rotate_lower, m_rotate_upper, m_hide_cut_plane, m_mode, m_connectors_editing,
|
||||||
// m_connector_depth_ratio, m_connector_size, m_connector_mode, m_connector_type, m_connector_style, m_connector_shape_id,
|
|
||||||
m_ar_plane_center, m_start_dragging_m);
|
m_ar_plane_center, m_start_dragging_m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,6 +914,7 @@ void GLGizmoCut3D::on_set_state()
|
||||||
// initiate archived values
|
// initiate archived values
|
||||||
m_ar_plane_center = m_plane_center;
|
m_ar_plane_center = m_plane_center;
|
||||||
m_start_dragging_m = m_rotation_m;
|
m_start_dragging_m = m_rotation_m;
|
||||||
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
||||||
|
|
||||||
m_parent.request_extra_frame();
|
m_parent.request_extra_frame();
|
||||||
}
|
}
|
||||||
|
@ -934,7 +926,6 @@ void GLGizmoCut3D::on_set_state()
|
||||||
m_selected.clear();
|
m_selected.clear();
|
||||||
m_parent.set_use_color_clip_plane(false);
|
m_parent.set_use_color_clip_plane(false);
|
||||||
}
|
}
|
||||||
force_update_clipper_on_render = m_state == On;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::on_register_raycasters_for_picking()
|
void GLGizmoCut3D::on_register_raycasters_for_picking()
|
||||||
|
@ -1146,7 +1137,7 @@ void GLGizmoCut3D::dragging_grabber_z(const GLGizmoBase::UpdateData &data)
|
||||||
const Vec3d shift = starting_vec * projection;
|
const Vec3d shift = starting_vec * projection;
|
||||||
|
|
||||||
// move cut plane center
|
// move cut plane center
|
||||||
set_center(m_plane_center + shift);
|
set_center(m_plane_center + shift, true);
|
||||||
|
|
||||||
m_was_cut_plane_dragged = true;
|
m_was_cut_plane_dragged = true;
|
||||||
}
|
}
|
||||||
|
@ -1185,9 +1176,10 @@ void GLGizmoCut3D::dragging_grabber_xy(const GLGizmoBase::UpdateData &data)
|
||||||
rotation[m_hover_id] = theta;
|
rotation[m_hover_id] = theta;
|
||||||
|
|
||||||
const Transform3d rotation_tmp = m_start_dragging_m * rotation_transform(rotation);
|
const Transform3d rotation_tmp = m_start_dragging_m * rotation_transform(rotation);
|
||||||
if (m_rotation_m.rotation() != rotation_tmp.rotation())
|
const bool update_tbb = m_rotation_m.rotation() != rotation_tmp.rotation();
|
||||||
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
|
||||||
m_rotation_m = rotation_tmp;
|
m_rotation_m = rotation_tmp;
|
||||||
|
if (update_tbb)
|
||||||
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
||||||
|
|
||||||
m_angle = theta;
|
m_angle = theta;
|
||||||
while (m_angle > two_pi)
|
while (m_angle > two_pi)
|
||||||
|
@ -1247,16 +1239,19 @@ void GLGizmoCut3D::on_stop_dragging()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool force/* = false*/)
|
void GLGizmoCut3D::set_center_pos(const Vec3d& center_pos, bool update_tbb /*=false*/)
|
||||||
{
|
{
|
||||||
if (m_plane_center == center_pos)
|
BoundingBoxf3 tbb = m_transformed_bounding_box;
|
||||||
return;
|
if (update_tbb) {
|
||||||
|
Vec3d normal = m_rotation_m.inverse() * Vec3d(m_plane_center - center_pos);
|
||||||
|
tbb.translate(normal.z() * Vec3d::UnitZ());
|
||||||
|
}
|
||||||
|
const Vec3d& instance_offset = m_parent.get_selection().get_first_volume()->get_instance_offset();
|
||||||
|
const Vec3d trans_center_pos = (m_rotation_m.inverse() * (center_pos - instance_offset)) + tbb.center();
|
||||||
|
|
||||||
bool can_set_center_pos = force;
|
bool can_set_center_pos = tbb.contains(trans_center_pos);
|
||||||
BoundingBoxf3 tbb;
|
|
||||||
if (!can_set_center_pos) {
|
if (!can_set_center_pos) {
|
||||||
tbb = transformed_bounding_box(center_pos);
|
if (tbb.max.z() > -.5 && tbb.min.z() < .5)
|
||||||
if (tbb.max.z() > -1. && tbb.min.z() < 1.)
|
|
||||||
can_set_center_pos = true;
|
can_set_center_pos = true;
|
||||||
else {
|
else {
|
||||||
const double old_dist = (m_bb_center - m_plane_center).norm();
|
const double old_dist = (m_bb_center - m_plane_center).norm();
|
||||||
|
@ -1290,55 +1285,31 @@ BoundingBoxf3 GLGizmoCut3D::bounding_box() const
|
||||||
|
|
||||||
BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center) const
|
BoundingBoxf3 GLGizmoCut3D::transformed_bounding_box(const Vec3d& plane_center) const
|
||||||
{
|
{
|
||||||
// #ysFIXME !!!
|
|
||||||
BoundingBoxf3 ret;
|
|
||||||
|
|
||||||
const CommonGizmosDataObjects::SelectionInfo* sel_info = m_c->selection_info();
|
|
||||||
if (!sel_info)
|
|
||||||
return ret;
|
|
||||||
const ModelObject* mo = sel_info->model_object();
|
|
||||||
if (!mo)
|
|
||||||
return ret;
|
|
||||||
const int instance_idx = sel_info->get_active_instance();
|
|
||||||
if (instance_idx < 0 || mo->instances.empty())
|
|
||||||
return ret;
|
|
||||||
const ModelInstance* mi = mo->instances[instance_idx];
|
|
||||||
|
|
||||||
const Vec3d& instance_offset = mi->get_offset();
|
|
||||||
Vec3d cut_center_offset = plane_center - instance_offset;
|
|
||||||
cut_center_offset[Z] -= sel_info->get_sla_shift();
|
|
||||||
|
|
||||||
const auto cut_matrix = Transform3d::Identity() * m_rotation_m.inverse() * translation_transform(-cut_center_offset);
|
|
||||||
|
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
|
|
||||||
|
const Vec3d& instance_offset = selection.get_first_volume()->get_instance_offset();
|
||||||
|
const auto cut_matrix = Transform3d::Identity() * m_rotation_m.inverse() * translation_transform(instance_offset - plane_center);
|
||||||
|
|
||||||
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
||||||
|
BoundingBoxf3 ret;
|
||||||
for (unsigned int i : idxs) {
|
for (unsigned int i : idxs) {
|
||||||
const GLVolume* volume = selection.get_volume(i);
|
const GLVolume* volume = selection.get_volume(i);
|
||||||
// respect just to the solid parts for FFF and ignore pad and supports for SLA
|
// respect just to the solid parts for FFF and ignore pad and supports for SLA
|
||||||
if (!volume->is_modifier && !volume->is_sla_pad() && !volume->is_sla_support()) {
|
if (!volume->is_modifier && !volume->is_sla_pad() && !volume->is_sla_support()) {
|
||||||
|
|
||||||
#if ENABLE_WORLD_COORDINATE
|
|
||||||
const auto instance_matrix = volume->get_instance_transformation().get_matrix_no_offset();
|
const auto instance_matrix = volume->get_instance_transformation().get_matrix_no_offset();
|
||||||
#else
|
|
||||||
const auto instance_matrix = assemble_transform(
|
|
||||||
Vec3d::Zero(), // don't apply offset
|
|
||||||
volume->get_instance_rotation().cwiseProduct(Vec3d(1.0, 1.0, 1.0)),
|
|
||||||
volume->get_instance_scaling_factor(),
|
|
||||||
volume->get_instance_mirror()
|
|
||||||
);
|
|
||||||
#endif // ENABLE_WORLD_COORDINATE
|
|
||||||
|
|
||||||
auto volume_trafo = instance_matrix * volume->get_volume_transformation().get_matrix();
|
auto volume_trafo = instance_matrix * volume->get_volume_transformation().get_matrix();
|
||||||
|
|
||||||
ret.merge(volume->transformed_convex_hull_bounding_box(cut_matrix * volume_trafo));
|
ret.merge(volume->transformed_convex_hull_bounding_box(cut_matrix * volume_trafo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoCut3D::update_bb()
|
void GLGizmoCut3D::update_bb()
|
||||||
{
|
{
|
||||||
const BoundingBoxf3 box = bounding_box();
|
const BoundingBoxf3 box = bounding_box();
|
||||||
|
if (!box.defined)
|
||||||
|
return;
|
||||||
if (m_max_pos != box.max || m_min_pos != box.min) {
|
if (m_max_pos != box.max || m_min_pos != box.min) {
|
||||||
|
|
||||||
m_bounding_box = box;
|
m_bounding_box = box;
|
||||||
|
@ -1348,10 +1319,11 @@ bool GLGizmoCut3D::update_bb()
|
||||||
m_max_pos = box.max;
|
m_max_pos = box.max;
|
||||||
m_min_pos = box.min;
|
m_min_pos = box.min;
|
||||||
m_bb_center = box.center();
|
m_bb_center = box.center();
|
||||||
|
m_transformed_bounding_box = transformed_bounding_box(m_bb_center);
|
||||||
if (box.contains(m_center_offset))
|
if (box.contains(m_center_offset))
|
||||||
set_center_pos(m_bb_center + m_center_offset, true);
|
set_center_pos(m_bb_center + m_center_offset);
|
||||||
else
|
else
|
||||||
set_center_pos(m_bb_center, true);
|
set_center_pos(m_bb_center);
|
||||||
|
|
||||||
m_radius = box.radius();
|
m_radius = box.radius();
|
||||||
m_grabber_connection_len = 0.5 * m_radius;// std::min<double>(0.75 * m_radius, 35.0);
|
m_grabber_connection_len = 0.5 * m_radius;// std::min<double>(0.75 * m_radius, 35.0);
|
||||||
|
@ -1376,10 +1348,7 @@ bool GLGizmoCut3D::update_bb()
|
||||||
clear_selection();
|
clear_selection();
|
||||||
if (CommonGizmosDataObjects::SelectionInfo* selection = m_c->selection_info())
|
if (CommonGizmosDataObjects::SelectionInfo* selection = m_c->selection_info())
|
||||||
m_selected.resize(selection->model_object()->cut_connectors.size(), false);
|
m_selected.resize(selection->model_object()->cut_connectors.size(), false);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::init_picking_models()
|
void GLGizmoCut3D::init_picking_models()
|
||||||
|
@ -1435,12 +1404,7 @@ void GLGizmoCut3D::render_clipper_cut()
|
||||||
|
|
||||||
void GLGizmoCut3D::on_render()
|
void GLGizmoCut3D::on_render()
|
||||||
{
|
{
|
||||||
if (update_bb() || force_update_clipper_on_render) {
|
update_clipper();
|
||||||
update_clipper_on_render();
|
|
||||||
m_c->object_clipper()->set_behavior(m_connectors_editing, m_connectors_editing, 0.4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
update_clipper();
|
|
||||||
|
|
||||||
init_picking_models();
|
init_picking_models();
|
||||||
|
|
||||||
|
@ -1653,10 +1617,10 @@ void GLGizmoCut3D::render_build_size()
|
||||||
|
|
||||||
void GLGizmoCut3D::reset_cut_plane()
|
void GLGizmoCut3D::reset_cut_plane()
|
||||||
{
|
{
|
||||||
set_center(m_bb_center);
|
|
||||||
m_rotation_m = Transform3d::Identity();
|
m_rotation_m = Transform3d::Identity();
|
||||||
m_angle_arc.reset();
|
m_angle_arc.reset();
|
||||||
update_clipper();
|
m_transformed_bounding_box = transformed_bounding_box(m_bb_center);
|
||||||
|
set_center(m_bb_center);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoCut3D::invalidate_cut_plane()
|
void GLGizmoCut3D::invalidate_cut_plane()
|
||||||
|
@ -1671,6 +1635,9 @@ void GLGizmoCut3D::invalidate_cut_plane()
|
||||||
|
|
||||||
void GLGizmoCut3D::set_connectors_editing(bool connectors_editing)
|
void GLGizmoCut3D::set_connectors_editing(bool connectors_editing)
|
||||||
{
|
{
|
||||||
|
if (m_connectors_editing == connectors_editing)
|
||||||
|
return;
|
||||||
|
|
||||||
m_connectors_editing = connectors_editing;
|
m_connectors_editing = connectors_editing;
|
||||||
update_raycasters_for_picking();
|
update_raycasters_for_picking();
|
||||||
|
|
||||||
|
@ -1682,6 +1649,8 @@ void GLGizmoCut3D::set_connectors_editing(bool connectors_editing)
|
||||||
void GLGizmoCut3D::flip_cut_plane()
|
void GLGizmoCut3D::flip_cut_plane()
|
||||||
{
|
{
|
||||||
m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX());
|
m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX());
|
||||||
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
||||||
|
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||||
m_start_dragging_m = m_rotation_m;
|
m_start_dragging_m = m_rotation_m;
|
||||||
|
|
||||||
|
@ -2338,9 +2307,11 @@ bool GLGizmoCut3D::process_cut_line(SLAGizmoEventType action, const Vec2d& mouse
|
||||||
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), cross_dir).toRotationMatrix();
|
m.matrix().block(0, 0, 3, 3) = q.setFromTwoVectors(Vec3d::UnitZ(), cross_dir).toRotationMatrix();
|
||||||
|
|
||||||
m_rotation_m = m;
|
m_rotation_m = m;
|
||||||
|
// update transformed bb
|
||||||
|
m_transformed_bounding_box = transformed_bounding_box(m_plane_center);
|
||||||
m_angle_arc.reset();
|
m_angle_arc.reset();
|
||||||
|
|
||||||
set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center)));
|
set_center(m_plane_center + cross_dir * (cross_dir.dot(pt - m_plane_center)), true);
|
||||||
|
|
||||||
discard_cut_line_processing();
|
discard_cut_line_processing();
|
||||||
}
|
}
|
||||||
|
@ -2542,6 +2513,7 @@ CommonGizmosDataID GLGizmoCut3D::on_get_requirements() const {
|
||||||
|
|
||||||
void GLGizmoCut3D::data_changed()
|
void GLGizmoCut3D::data_changed()
|
||||||
{
|
{
|
||||||
|
update_bb();
|
||||||
if (auto oc = m_c->object_clipper())
|
if (auto oc = m_c->object_clipper())
|
||||||
oc->set_behavior(m_connectors_editing, m_connectors_editing, double(m_contour_width));
|
oc->set_behavior(m_connectors_editing, m_connectors_editing, double(m_contour_width));
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,6 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||||
float m_label_width{ 150.0 };
|
float m_label_width{ 150.0 };
|
||||||
float m_control_width{ 200.0 };
|
float m_control_width{ 200.0 };
|
||||||
bool m_imperial_units{ false };
|
bool m_imperial_units{ false };
|
||||||
bool force_update_clipper_on_render{false};
|
|
||||||
|
|
||||||
float m_contour_width{ 0.4f };
|
float m_contour_width{ 0.4f };
|
||||||
float m_cut_plane_radius_koef{ 1.5f };
|
float m_cut_plane_radius_koef{ 1.5f };
|
||||||
|
@ -188,11 +187,10 @@ public:
|
||||||
/// <returns>Return True when use the information otherwise False.</returns>
|
/// <returns>Return True when use the information otherwise False.</returns>
|
||||||
bool on_mouse(const wxMouseEvent &mouse_event) override;
|
bool on_mouse(const wxMouseEvent &mouse_event) override;
|
||||||
|
|
||||||
void shift_cut_z(double delta);
|
void shift_cut(double delta);
|
||||||
void rotate_vec3d_around_plane_center(Vec3d&vec);
|
void rotate_vec3d_around_plane_center(Vec3d&vec);
|
||||||
void put_connectors_on_cut_plane(const Vec3d& cp_normal, double cp_offset);
|
void put_connectors_on_cut_plane(const Vec3d& cp_normal, double cp_offset);
|
||||||
void update_clipper();
|
void update_clipper();
|
||||||
void update_clipper_on_render();
|
|
||||||
void invalidate_cut_plane();
|
void invalidate_cut_plane();
|
||||||
|
|
||||||
BoundingBoxf3 bounding_box() const;
|
BoundingBoxf3 bounding_box() const;
|
||||||
|
@ -258,7 +256,7 @@ protected:
|
||||||
void data_changed() override;
|
void data_changed() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_center(const Vec3d& center);
|
void set_center(const Vec3d& center, bool update_tbb = false);
|
||||||
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
bool render_combo(const std::string& label, const std::vector<std::string>& lines, size_t& selection_idx);
|
||||||
bool render_double_input(const std::string& label, double& value_in);
|
bool render_double_input(const std::string& label, double& value_in);
|
||||||
bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in);
|
bool render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in);
|
||||||
|
@ -284,8 +282,8 @@ private:
|
||||||
void render_cut_plane_grabbers();
|
void render_cut_plane_grabbers();
|
||||||
void render_cut_line();
|
void render_cut_line();
|
||||||
void perform_cut(const Selection&selection);
|
void perform_cut(const Selection&selection);
|
||||||
void set_center_pos(const Vec3d¢er_pos, bool force = false);
|
void set_center_pos(const Vec3d¢er_pos, bool update_tbb = false);
|
||||||
bool update_bb();
|
void update_bb();
|
||||||
void init_picking_models();
|
void init_picking_models();
|
||||||
void init_rendering_items();
|
void init_rendering_items();
|
||||||
void render_clipper_cut();
|
void render_clipper_cut();
|
||||||
|
|
|
@ -540,7 +540,11 @@ void GLGizmoSimplify::apply_simplify() {
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
auto plater = wxGetApp().plater();
|
auto plater = wxGetApp().plater();
|
||||||
plater->take_snapshot(_u8L("Simplify ") + create_volumes_name(m_volume_ids, selection));
|
plater->take_snapshot(_u8L("Simplify ") + create_volumes_name(m_volume_ids, selection));
|
||||||
plater->clear_before_change_mesh(selection.get_object_idx());
|
plater->clear_before_change_mesh(selection.get_object_idx(), _u8L("Custom supports, seams and multimaterial painting were "
|
||||||
|
"removed after simplifying the mesh."));
|
||||||
|
// After removing custom supports, seams, and multimaterial painting, we have to update info about the object to remove information about
|
||||||
|
// custom supports, seams, and multimaterial painting in the right panel.
|
||||||
|
wxGetApp().obj_list()->update_info_items(selection.get_object_idx());
|
||||||
|
|
||||||
for (const auto &item: m_state.result) {
|
for (const auto &item: m_state.result) {
|
||||||
const ObjectID &id = item.first;
|
const ObjectID &id = item.first;
|
||||||
|
|
|
@ -623,7 +623,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
||||||
else if (m_current == Cut) {
|
else if (m_current == Cut) {
|
||||||
auto do_move = [this, &processed](double delta_z) {
|
auto do_move = [this, &processed](double delta_z) {
|
||||||
GLGizmoCut3D* cut = dynamic_cast<GLGizmoCut3D*>(get_current());
|
GLGizmoCut3D* cut = dynamic_cast<GLGizmoCut3D*>(get_current());
|
||||||
cut->shift_cut_z(delta_z);
|
cut->shift_cut(delta_z);
|
||||||
processed = true;
|
processed = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1082,7 +1082,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
|
||||||
// The press on Esc key invokes editing of InputText (removes last changes)
|
// The press on Esc key invokes editing of InputText (removes last changes)
|
||||||
// So we should save previous value...
|
// So we should save previous value...
|
||||||
std::string str = search_str;
|
std::string str = search_str;
|
||||||
ImGui::InputTextEx("", NULL, search_str, 40, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL);
|
ImGui::InputTextEx("", NULL, search_str, 240, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL);
|
||||||
edited = ImGui::IsItemEdited();
|
edited = ImGui::IsItemEdited();
|
||||||
if (edited)
|
if (edited)
|
||||||
hovered_id = 0;
|
hovered_id = 0;
|
||||||
|
@ -2056,7 +2056,11 @@ const char* ImGuiWrapper::clipboard_get(void* user_data)
|
||||||
const char* res = "";
|
const char* res = "";
|
||||||
|
|
||||||
if (wxTheClipboard->Open()) {
|
if (wxTheClipboard->Open()) {
|
||||||
if (wxTheClipboard->IsSupported(wxDF_TEXT)) {
|
if (wxTheClipboard->IsSupported(wxDF_TEXT)
|
||||||
|
#if wxUSE_UNICODE
|
||||||
|
|| wxTheClipboard->IsSupported(wxDF_UNICODETEXT)
|
||||||
|
#endif // wxUSE_UNICODE
|
||||||
|
) {
|
||||||
wxTextDataObject data;
|
wxTextDataObject data;
|
||||||
wxTheClipboard->GetData(data);
|
wxTheClipboard->GetData(data);
|
||||||
|
|
||||||
|
|
|
@ -3127,6 +3127,10 @@ void Plater::priv::split_object()
|
||||||
Model new_model = model;
|
Model new_model = model;
|
||||||
ModelObject* current_model_object = new_model.objects[obj_idx];
|
ModelObject* current_model_object = new_model.objects[obj_idx];
|
||||||
|
|
||||||
|
// Before splitting object we have to remove all custom supports, seams, and multimaterial painting.
|
||||||
|
wxGetApp().plater()->clear_before_change_mesh(obj_idx, _u8L("Custom supports, seams and multimaterial painting were "
|
||||||
|
"removed after splitting the object."));
|
||||||
|
|
||||||
wxBusyCursor wait;
|
wxBusyCursor wait;
|
||||||
ModelObjectPtrs new_objects;
|
ModelObjectPtrs new_objects;
|
||||||
current_model_object->split(&new_objects);
|
current_model_object->split(&new_objects);
|
||||||
|
@ -7338,7 +7342,7 @@ bool Plater::set_printer_technology(PrinterTechnology printer_technology)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plater::clear_before_change_mesh(int obj_idx)
|
void Plater::clear_before_change_mesh(int obj_idx, const std::string ¬ification_msg)
|
||||||
{
|
{
|
||||||
ModelObject* mo = model().objects[obj_idx];
|
ModelObject* mo = model().objects[obj_idx];
|
||||||
|
|
||||||
|
@ -7356,8 +7360,7 @@ void Plater::clear_before_change_mesh(int obj_idx)
|
||||||
get_notification_manager()->push_notification(
|
get_notification_manager()->push_notification(
|
||||||
NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
|
NotificationType::CustomSupportsAndSeamRemovedAfterRepair,
|
||||||
NotificationManager::NotificationLevel::PrintInfoNotificationLevel,
|
NotificationManager::NotificationLevel::PrintInfoNotificationLevel,
|
||||||
_u8L("Custom supports, seams and multimaterial painting were "
|
notification_msg);
|
||||||
"removed after repairing the mesh."));
|
|
||||||
// _u8L("Undo the repair"),
|
// _u8L("Undo the repair"),
|
||||||
// [this, snapshot_time](wxEvtHandler*){
|
// [this, snapshot_time](wxEvtHandler*){
|
||||||
// // Make sure the snapshot is still available and that
|
// // Make sure the snapshot is still available and that
|
||||||
|
|
|
@ -273,7 +273,7 @@ public:
|
||||||
void reslice_FFF_until_step(PrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false);
|
void reslice_FFF_until_step(PrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false);
|
||||||
void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false);
|
void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false);
|
||||||
|
|
||||||
void clear_before_change_mesh(int obj_idx);
|
void clear_before_change_mesh(int obj_idx, const std::string ¬ification_msg);
|
||||||
void changed_mesh(int obj_idx);
|
void changed_mesh(int obj_idx);
|
||||||
|
|
||||||
void changed_object(int obj_idx);
|
void changed_object(int obj_idx);
|
||||||
|
|
Loading…
Reference in a new issue