mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-06 00:16:17 +08:00
Merge branch 'lm_wipe_tower_model'
This commit is contained in:
commit
1f3be0e0bb
@ -90,6 +90,7 @@ const std::string LAYER_CONFIG_RANGES_FILE = "Metadata/Prusa_Slicer_layer_config
|
||||
const std::string SLA_SUPPORT_POINTS_FILE = "Metadata/Slic3r_PE_sla_support_points.txt";
|
||||
const std::string SLA_DRAIN_HOLES_FILE = "Metadata/Slic3r_PE_sla_drain_holes.txt";
|
||||
const std::string CUSTOM_GCODE_PER_PRINT_Z_FILE = "Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml";
|
||||
const std::string WIPE_TOWER_INFORMATION_FILE = "Metadata/Prusa_Slicer_wipe_tower_information.xml";
|
||||
const std::string CUT_INFORMATION_FILE = "Metadata/Prusa_Slicer_cut_information.xml";
|
||||
|
||||
static constexpr const char *RELATIONSHIP_TAG = "Relationship";
|
||||
@ -554,6 +555,8 @@ namespace Slic3r {
|
||||
void _extract_sla_drain_holes_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
|
||||
|
||||
void _extract_custom_gcode_per_print_z_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
|
||||
void _extract_wipe_tower_information_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model);
|
||||
void _extract_wipe_tower_information_from_archive_legacy(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, Model& model);
|
||||
|
||||
void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, ConfigSubstitutionContext& subs_context, const std::string& archive_filename);
|
||||
bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model);
|
||||
@ -766,6 +769,9 @@ namespace Slic3r {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the wipe tower position (see the end of this function):
|
||||
model.wipe_tower.position.x() = std::numeric_limits<double>::max();
|
||||
|
||||
// Read root model file
|
||||
if (start_part_stat.m_file_index < num_entries) {
|
||||
try {
|
||||
@ -822,6 +828,10 @@ namespace Slic3r {
|
||||
// extract slic3r layer config ranges file
|
||||
_extract_custom_gcode_per_print_z_from_archive(archive, stat);
|
||||
}
|
||||
else if (boost::algorithm::iequals(name, WIPE_TOWER_INFORMATION_FILE)) {
|
||||
// extract wipe tower information file
|
||||
_extract_wipe_tower_information_from_archive(archive, stat, model);
|
||||
}
|
||||
else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) {
|
||||
// extract slic3r model config file
|
||||
if (!_extract_model_config_from_archive(archive, stat, model)) {
|
||||
@ -836,6 +846,28 @@ namespace Slic3r {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (model.wipe_tower.position.x() == std::numeric_limits<double>::max()) {
|
||||
// This is apparently an old project from before PS 2.9.0, which saved wipe tower pos and rotation
|
||||
// into config, not into Model. Try to load it from the config file.
|
||||
// First set default in case we do not find it (these were the default values of the config options).
|
||||
model.wipe_tower.position.x() = 180;
|
||||
model.wipe_tower.position.y() = 140;
|
||||
model.wipe_tower.rotation = 0.;
|
||||
|
||||
for (mz_uint i = 0; i < num_entries; ++i) {
|
||||
if (mz_zip_reader_file_stat(&archive, i, &stat)) {
|
||||
std::string name(stat.m_filename);
|
||||
std::replace(name.begin(), name.end(), '\\', '/');
|
||||
|
||||
if (boost::algorithm::iequals(name, PRINT_CONFIG_FILE)) {
|
||||
_extract_wipe_tower_information_from_archive_legacy(archive, stat, model);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close_zip_reader(&archive);
|
||||
|
||||
if (m_version == 0) {
|
||||
@ -1615,6 +1647,77 @@ namespace Slic3r {
|
||||
}
|
||||
}
|
||||
|
||||
void _3MF_Importer::_extract_wipe_tower_information_from_archive(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, Model& model)
|
||||
{
|
||||
if (stat.m_uncomp_size > 0) {
|
||||
std::string buffer((size_t)stat.m_uncomp_size, 0);
|
||||
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
|
||||
if (res == 0) {
|
||||
add_error("Error while reading wipe tower information data to buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
std::istringstream iss(buffer); // wrap returned xml to istringstream
|
||||
pt::ptree main_tree;
|
||||
pt::read_xml(iss, main_tree);
|
||||
|
||||
try {
|
||||
auto& node = main_tree.get_child("wipe_tower_information");
|
||||
double pos_x = node.get<double>("<xmlattr>.position_x");
|
||||
double pos_y = node.get<double>("<xmlattr>.position_y");
|
||||
double rot_deg = node.get<double>("<xmlattr>.rotation_deg");
|
||||
model.wipe_tower.position = Vec2d(pos_x, pos_y);
|
||||
model.wipe_tower.rotation = rot_deg;
|
||||
} catch (const boost::property_tree::ptree_bad_path&) {
|
||||
// Handles missing node or attribute.
|
||||
add_error("Error while reading wipe tower information.");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void _3MF_Importer::_extract_wipe_tower_information_from_archive_legacy(::mz_zip_archive &archive, const mz_zip_archive_file_stat &stat, Model& model)
|
||||
{
|
||||
if (stat.m_uncomp_size > 0) {
|
||||
std::string buffer((size_t)stat.m_uncomp_size, 0);
|
||||
mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
|
||||
if (res == 0) {
|
||||
add_error("Error while reading config data to buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find wipe tower data in the config, where pre-2.9.0 slicers saved them.
|
||||
// Do not load the config as usual, it no longer knows those values.
|
||||
std::istringstream iss(buffer);
|
||||
std::string line;
|
||||
|
||||
while (iss) {
|
||||
std::getline(iss, line);
|
||||
boost::algorithm::trim_left_if(line, [](char ch) { return std::isspace(ch) || ch == ';'; });
|
||||
if (boost::starts_with(line, "wipe_tower_x") || boost::starts_with(line, "wipe_tower_y") || boost::starts_with(line, "wipe_tower_rotation_angle")) {
|
||||
std::string value_str;
|
||||
try {
|
||||
value_str = line.substr(line.find("=") + 1, std::string::npos);
|
||||
} catch (const std::out_of_range&) {
|
||||
continue;
|
||||
}
|
||||
double val = 0.;
|
||||
std::istringstream value_ss(value_str);
|
||||
value_ss >> val;
|
||||
if (! value_ss.fail()) {
|
||||
if (boost::starts_with(line, "wipe_tower_x"))
|
||||
model.wipe_tower.position.x() = val;
|
||||
else if (boost::starts_with(line, "wipe_tower_y"))
|
||||
model.wipe_tower.position.y() = val;
|
||||
else
|
||||
model.wipe_tower.rotation = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XMLCALL _3MF_Importer::_handle_start_relationships_element(void *userData, const char *name, const char **attributes)
|
||||
{
|
||||
_3MF_Importer *importer = (_3MF_Importer *) userData;
|
||||
@ -2645,9 +2748,10 @@ namespace Slic3r {
|
||||
bool _add_layer_config_ranges_file_to_archive(mz_zip_archive& archive, Model& model);
|
||||
bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model);
|
||||
bool _add_sla_drain_holes_file_to_archive(mz_zip_archive& archive, Model& model);
|
||||
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config);
|
||||
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config, const Model& model);
|
||||
bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data);
|
||||
bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config);
|
||||
bool _add_wipe_tower_information_file_to_archive( mz_zip_archive& archive, Model& model);
|
||||
};
|
||||
|
||||
bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64)
|
||||
@ -2754,10 +2858,19 @@ namespace Slic3r {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Adds wipe tower information ("Metadata/Prusa_Slicer_wipe_tower_information.xml").
|
||||
if (!_add_wipe_tower_information_file_to_archive(archive, model)) {
|
||||
close_zip_writer(&archive);
|
||||
boost::filesystem::remove(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Adds slic3r print config file ("Metadata/Slic3r_PE.config").
|
||||
// This file contains the content of FullPrintConfing / SLAFullPrintConfig.
|
||||
if (config != nullptr) {
|
||||
if (!_add_print_config_file_to_archive(archive, *config)) {
|
||||
if (!_add_print_config_file_to_archive(archive, *config, model)) {
|
||||
close_zip_writer(&archive);
|
||||
boost::filesystem::remove(filename);
|
||||
return false;
|
||||
@ -3456,16 +3569,39 @@ namespace Slic3r {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config)
|
||||
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config, const Model& model)
|
||||
{
|
||||
assert(is_decimal_separator_point());
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "; %s\n\n", header_slic3r_generated().c_str());
|
||||
std::string out = buffer;
|
||||
|
||||
for (const std::string &key : config.keys())
|
||||
if (key != "compatible_printers")
|
||||
out += "; " + key + " = " + config.opt_serialize(key) + "\n";
|
||||
t_config_option_keys keys = config.keys();
|
||||
|
||||
// Wipe tower values were historically stored in the config, but they were moved into
|
||||
// Model in PS 2.9.0. Keep saving the old values to maintain forward compatibility.
|
||||
for (const std::string s : {"wipe_tower_x", "wipe_tower_y", "wipe_tower_rotation_angle"})
|
||||
if (! config.has(s))
|
||||
keys.emplace_back(s);
|
||||
sort_remove_duplicates(keys);
|
||||
|
||||
for (const std::string& key : keys) {
|
||||
if (key == "compatible_printers")
|
||||
continue;
|
||||
|
||||
std::string opt_serialized;
|
||||
|
||||
if (key == "wipe_tower_x")
|
||||
opt_serialized = float_to_string_decimal_point(model.wipe_tower.position.x());
|
||||
else if (key == "wipe_tower_y")
|
||||
opt_serialized = float_to_string_decimal_point(model.wipe_tower.position.y());
|
||||
else if (key == "wipe_tower_rotation_angle")
|
||||
opt_serialized = float_to_string_decimal_point(model.wipe_tower.rotation);
|
||||
else
|
||||
opt_serialized = config.opt_serialize(key);
|
||||
|
||||
out += "; " + key + " = " + opt_serialized + "\n";
|
||||
}
|
||||
|
||||
if (!out.empty()) {
|
||||
if (!mz_zip_writer_add_mem(&archive, PRINT_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
|
||||
@ -3663,6 +3799,34 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _3MF_Exporter::_add_wipe_tower_information_file_to_archive( mz_zip_archive& archive, Model& model)
|
||||
{
|
||||
std::string out = "";
|
||||
|
||||
pt::ptree tree;
|
||||
pt::ptree& main_tree = tree.add("wipe_tower_information", "");
|
||||
|
||||
main_tree.put("<xmlattr>.position_x", model.wipe_tower.position.x());
|
||||
main_tree.put("<xmlattr>.position_y", model.wipe_tower.position.y());
|
||||
main_tree.put("<xmlattr>.rotation_deg", model.wipe_tower.rotation);
|
||||
|
||||
std::ostringstream oss;
|
||||
boost::property_tree::write_xml(oss, tree);
|
||||
out = oss.str();
|
||||
|
||||
// Post processing("beautification") of the output string
|
||||
boost::replace_all(out, "><", ">\n<");
|
||||
|
||||
if (!out.empty()) {
|
||||
if (!mz_zip_writer_add_mem(&archive, WIPE_TOWER_INFORMATION_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
|
||||
add_error("Unable to add wipe tower information file to archive");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Perform conversions based on the config values available.
|
||||
static void handle_legacy_project_loaded(unsigned int version_project_file, DynamicPrintConfig& config, const boost::optional<Semver>& prusaslicer_generator_version)
|
||||
{
|
||||
|
@ -1312,7 +1312,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
|
||||
std::vector<std::pair<coordf_t, ObjectsLayerToPrint>> layers_to_print = collect_layers_to_print(print);
|
||||
// Prusa Multi-Material wipe tower.
|
||||
if (has_wipe_tower && ! layers_to_print.empty()) {
|
||||
m_wipe_tower = std::make_unique<GCode::WipeTowerIntegration>(print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get());
|
||||
m_wipe_tower = std::make_unique<GCode::WipeTowerIntegration>(print.model().wipe_tower.position.cast<float>(), print.model().wipe_tower.rotation, print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get());
|
||||
|
||||
// Set position for wipe tower generation.
|
||||
Vec3d new_position = this->writer().get_position();
|
||||
|
@ -151,8 +151,8 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_
|
||||
// Wipe tower extrusions are saved as if the tower was at the origin with no rotation
|
||||
// We need to get position and angle of the wipe tower to transform them to actual position.
|
||||
Transform2d trafo =
|
||||
Eigen::Translation2d(print.config().wipe_tower_x.value, print.config().wipe_tower_y.value) *
|
||||
Eigen::Rotation2Dd(Geometry::deg2rad(print.config().wipe_tower_rotation_angle.value));
|
||||
Eigen::Translation2d(print.model().wipe_tower.position.x(), print.model().wipe_tower.position.y()) *
|
||||
Eigen::Rotation2Dd(Geometry::deg2rad(print.model().wipe_tower.rotation));
|
||||
|
||||
BoundingBoxf bbox;
|
||||
for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.wipe_tower_data().tool_changes) {
|
||||
|
@ -541,11 +541,11 @@ WipeTower::ToolChangeResult WipeTower::construct_tcr(WipeTowerWriter& writer,
|
||||
|
||||
|
||||
|
||||
WipeTower::WipeTower(const PrintConfig& config, const PrintRegionConfig& default_region_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) :
|
||||
WipeTower::WipeTower(const Vec2f& pos, double rotation_deg, const PrintConfig& config, const PrintRegionConfig& default_region_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) :
|
||||
m_semm(config.single_extruder_multi_material.value),
|
||||
m_wipe_tower_pos(config.wipe_tower_x, config.wipe_tower_y),
|
||||
m_wipe_tower_pos(pos),
|
||||
m_wipe_tower_width(float(config.wipe_tower_width)),
|
||||
m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)),
|
||||
m_wipe_tower_rotation_angle(rotation_deg),
|
||||
m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)),
|
||||
m_wipe_tower_cone_angle(float(config.wipe_tower_cone_angle)),
|
||||
m_extra_flow(float(config.wipe_tower_extra_flow/100.)),
|
||||
|
@ -139,7 +139,9 @@ public:
|
||||
// y -- y coordinates of wipe tower in mm ( left bottom corner )
|
||||
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
|
||||
// wipe_area -- space available for one toolchange in mm
|
||||
WipeTower(const PrintConfig& config,
|
||||
WipeTower(const Vec2f& position,
|
||||
double rotation_deg,
|
||||
const PrintConfig& config,
|
||||
const PrintRegionConfig& default_region_config,
|
||||
const std::vector<std::vector<float>>& wiping_matrix,
|
||||
size_t initial_tool);
|
||||
|
@ -20,14 +20,16 @@ namespace GCode {
|
||||
class WipeTowerIntegration {
|
||||
public:
|
||||
WipeTowerIntegration(
|
||||
Vec2f pos,
|
||||
double rotation,
|
||||
const PrintConfig &print_config,
|
||||
const std::vector<WipeTower::ToolChangeResult> &priming,
|
||||
const std::vector<std::vector<WipeTower::ToolChangeResult>> &tool_changes,
|
||||
const WipeTower::ToolChangeResult &final_purge) :
|
||||
m_left(/*float(print_config.wipe_tower_x.value)*/ 0.f),
|
||||
m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)),
|
||||
m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)),
|
||||
m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)),
|
||||
m_left( 0.f),
|
||||
m_right(float(print_config.wipe_tower_width.value)),
|
||||
m_wipe_tower_pos(pos),
|
||||
m_wipe_tower_rotation(rotation),
|
||||
m_extruder_offsets(print_config.extruder_offset.values),
|
||||
m_priming(priming),
|
||||
m_tool_changes(tool_changes),
|
||||
|
@ -69,6 +69,7 @@ Model& Model::assign_copy(const Model &rhs)
|
||||
|
||||
// copy custom code per height
|
||||
this->custom_gcode_per_print_z = rhs.custom_gcode_per_print_z;
|
||||
this->wipe_tower = rhs.wipe_tower;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -90,6 +91,7 @@ Model& Model::assign_copy(Model &&rhs)
|
||||
|
||||
// copy custom code per height
|
||||
this->custom_gcode_per_print_z = std::move(rhs.custom_gcode_per_print_z);
|
||||
this->wipe_tower = rhs.wipe_tower;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1190,11 +1190,20 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// Note: The following class does not have to inherit from ObjectID, it is currently
|
||||
// only used for arrangement. It might be good to refactor this in future.
|
||||
class ModelWipeTower final : public ObjectBase
|
||||
{
|
||||
public:
|
||||
Vec2d position;
|
||||
double rotation;
|
||||
Vec2d position = Vec2d(180., 140.);
|
||||
double rotation = 0.;
|
||||
|
||||
bool operator==(const ModelWipeTower& other) const { return position == other.position && rotation == other.rotation; }
|
||||
bool operator!=(const ModelWipeTower& other) const { return !((*this) == other); }
|
||||
|
||||
// Assignment operator does not touch the ID!
|
||||
ModelWipeTower& operator=(const ModelWipeTower& rhs) { position = rhs.position; rotation = rhs.rotation; return *this; }
|
||||
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
@ -1210,9 +1219,8 @@ private:
|
||||
// Copy constructor copies the ID.
|
||||
explicit ModelWipeTower(const ModelWipeTower &cfg) = default;
|
||||
|
||||
// Disabled methods.
|
||||
ModelWipeTower(ModelWipeTower &&rhs) = delete;
|
||||
ModelWipeTower& operator=(const ModelWipeTower &rhs) = delete;
|
||||
// Disabled methods.
|
||||
ModelWipeTower(ModelWipeTower &&rhs) = delete;
|
||||
ModelWipeTower& operator=(ModelWipeTower &&rhs) = delete;
|
||||
|
||||
// For serialization / deserialization of ModelWipeTower composed into another class into the Undo / Redo stack as a separate object.
|
||||
|
@ -485,8 +485,8 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "resolution", "gcode_resolution", "arc_fitting",
|
||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
||||
"wipe_tower",
|
||||
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
||||
"mmu_segmented_region_interlocking_depth", "wipe_tower_extruder", "wipe_tower_no_sparse_layers", "wipe_tower_extra_flow", "wipe_tower_extra_spacing", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
|
||||
"wall_distribution_count", "min_feature_size", "min_bead_width",
|
||||
|
@ -199,10 +199,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
|| opt_key == "draft_shield"
|
||||
|| opt_key == "skirt_distance"
|
||||
|| opt_key == "min_skirt_length"
|
||||
|| opt_key == "ooze_prevention"
|
||||
|| opt_key == "wipe_tower_x"
|
||||
|| opt_key == "wipe_tower_y"
|
||||
|| opt_key == "wipe_tower_rotation_angle") {
|
||||
|| opt_key == "ooze_prevention") {
|
||||
steps.emplace_back(psSkirtBrim);
|
||||
} else if (
|
||||
opt_key == "first_layer_height"
|
||||
@ -1049,8 +1046,8 @@ void Print::process()
|
||||
if (this->has_wipe_tower()) {
|
||||
// These values have to be updated here, not during wipe tower generation.
|
||||
// When the wipe tower is moved/rotated, it is not regenerated.
|
||||
m_wipe_tower_data.position = { m_config.wipe_tower_x, m_config.wipe_tower_y };
|
||||
m_wipe_tower_data.rotation_angle = m_config.wipe_tower_rotation_angle;
|
||||
m_wipe_tower_data.position = model().wipe_tower.position;
|
||||
m_wipe_tower_data.rotation_angle = model().wipe_tower.rotation;
|
||||
}
|
||||
auto conflictRes = ConflictChecker::find_inter_of_lines_in_diff_objs(objects(), m_wipe_tower_data);
|
||||
|
||||
@ -1279,8 +1276,8 @@ Points Print::first_layer_wipe_tower_corners() const
|
||||
pts.emplace_back(center + r*Vec2d(std::cos(alpha)/cone_x_scale, std::sin(alpha)));
|
||||
|
||||
for (Vec2d& pt : pts) {
|
||||
pt = Eigen::Rotation2Dd(Geometry::deg2rad(m_config.wipe_tower_rotation_angle.value)) * pt;
|
||||
pt += Vec2d(m_config.wipe_tower_x.value, m_config.wipe_tower_y.value);
|
||||
pt = Eigen::Rotation2Dd(Geometry::deg2rad(model().wipe_tower.rotation)) * pt;
|
||||
pt += model().wipe_tower.position;
|
||||
pts_scaled.emplace_back(Point(scale_(pt.x()), scale_(pt.y())));
|
||||
}
|
||||
}
|
||||
@ -1554,7 +1551,7 @@ void Print::_make_wipe_tower()
|
||||
this->throw_if_canceled();
|
||||
|
||||
// Initialize the wipe tower.
|
||||
WipeTower wipe_tower(m_config, m_default_region_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder());
|
||||
WipeTower wipe_tower(model().wipe_tower.position.cast<float>(), model().wipe_tower.rotation, m_config, m_default_region_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder());
|
||||
|
||||
// Set the extruder & material properties at the wipe tower object.
|
||||
for (size_t i = 0; i < m_config.nozzle_diameter.size(); ++ i)
|
||||
|
@ -1066,7 +1066,12 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
num_extruders_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check the position and rotation of the wipe tower.
|
||||
if (model.wipe_tower != m_model.wipe_tower)
|
||||
update_apply_status(this->invalidate_step(psSkirtBrim));
|
||||
m_model.wipe_tower = model.wipe_tower;
|
||||
|
||||
ModelObjectStatusDB model_object_status_db;
|
||||
|
||||
// 1) Synchronize model objects.
|
||||
|
@ -3547,20 +3547,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = "";
|
||||
def->set_default_value(new ConfigOptionBool{ false });
|
||||
|
||||
def = this->add("wipe_tower_x", coFloat);
|
||||
def->label = L("Position X");
|
||||
def->tooltip = L("X coordinate of the left front corner of a wipe tower");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(180.));
|
||||
|
||||
def = this->add("wipe_tower_y", coFloat);
|
||||
def->label = L("Position Y");
|
||||
def->tooltip = L("Y coordinate of the left front corner of a wipe tower");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(140.));
|
||||
|
||||
def = this->add("wipe_tower_width", coFloat);
|
||||
def->label = L("Width");
|
||||
def->tooltip = L("Width of a wipe tower");
|
||||
@ -3568,13 +3554,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(60.));
|
||||
|
||||
def = this->add("wipe_tower_rotation_angle", coFloat);
|
||||
def->label = L("Wipe tower rotation angle");
|
||||
def->tooltip = L("Wipe tower rotation angle with respect to x-axis.");
|
||||
def->sidetext = L("°");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0.));
|
||||
|
||||
def = this->add("wipe_tower_brim_width", coFloat);
|
||||
def->label = L("Wipe tower brim width");
|
||||
def->tooltip = L("Wipe tower brim width");
|
||||
@ -4821,7 +4800,8 @@ static std::set<std::string> PrintConfigDef_ignore = {
|
||||
// Disabled in 2.6.0-alpha6, this option is problematic
|
||||
"infill_only_where_needed",
|
||||
"gcode_binary", // Introduced in 2.7.0-alpha1, removed in 2.7.1 (replaced by binary_gcode).
|
||||
"wiping_volumes_extruders" // Removed in 2.7.3-alpha1.
|
||||
"wiping_volumes_extruders", // Removed in 2.7.3-alpha1.
|
||||
"wipe_tower_x", "wipe_tower_y", "wipe_tower_rotation_angle" // Removed in 2.9.0
|
||||
};
|
||||
|
||||
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)
|
||||
|
@ -965,11 +965,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionBools, wipe))
|
||||
((ConfigOptionBool, wipe_tower))
|
||||
((ConfigOptionFloat, wipe_tower_acceleration))
|
||||
((ConfigOptionFloat, wipe_tower_x))
|
||||
((ConfigOptionFloat, wipe_tower_y))
|
||||
((ConfigOptionFloat, wipe_tower_width))
|
||||
((ConfigOptionFloat, wipe_tower_per_color_wipe))
|
||||
((ConfigOptionFloat, wipe_tower_rotation_angle))
|
||||
((ConfigOptionFloat, wipe_tower_brim_width))
|
||||
((ConfigOptionFloat, wipe_tower_cone_angle))
|
||||
((ConfigOptionPercent, wipe_tower_extra_spacing))
|
||||
|
@ -324,7 +324,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
toggle_field("standby_temperature_delta", have_ooze_prevention);
|
||||
|
||||
bool have_wipe_tower = config->opt_bool("wipe_tower");
|
||||
for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_cone_angle",
|
||||
for (auto el : { "wipe_tower_width", "wipe_tower_brim_width", "wipe_tower_cone_angle",
|
||||
"wipe_tower_extra_spacing", "wipe_tower_extra_flow", "wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming" })
|
||||
toggle_field(el, have_wipe_tower);
|
||||
|
||||
|
@ -1690,8 +1690,8 @@ void GCodeViewer::load_wipetower_shell(const Print& print)
|
||||
const std::vector<std::pair<float, float>> z_and_depth_pairs = print.wipe_tower_data(extruders_count).z_and_depth_pairs;
|
||||
const float brim_width = wipe_tower_data.brim_width;
|
||||
if (depth != 0.) {
|
||||
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, z_and_depth_pairs,
|
||||
max_z, config.wipe_tower_cone_angle, config.wipe_tower_rotation_angle, false, brim_width);
|
||||
m_shells.volumes.load_wipe_tower_preview(wxGetApp().plater()->model().wipe_tower.position.x(), wxGetApp().plater()->model().wipe_tower.position.y(), config.wipe_tower_width, depth, z_and_depth_pairs,
|
||||
max_z, config.wipe_tower_cone_angle, wxGetApp().plater()->model().wipe_tower.rotation, false, brim_width);
|
||||
GLVolume* volume = m_shells.volumes.volumes.back();
|
||||
volume->color.a(0.25f);
|
||||
volume->force_native_color = true;
|
||||
|
@ -1011,8 +1011,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MIRRORED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_TOUCHED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED, SimpleEvent);
|
||||
@ -2392,10 +2391,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
|
||||
if (extruders_count > 1 && wt && !co) {
|
||||
|
||||
const float x = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_x"))->value;
|
||||
const float y = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_y"))->value;
|
||||
const float x = m_model->wipe_tower.position.x();
|
||||
const float y = m_model->wipe_tower.position.y();
|
||||
const float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
|
||||
const float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
|
||||
const float a = m_model->wipe_tower.rotation;
|
||||
const float bw = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_brim_width"))->value;
|
||||
const float ca = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_cone_angle"))->value;
|
||||
|
||||
@ -3954,8 +3953,10 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||
if (object_moved)
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED));
|
||||
|
||||
if (wipe_tower_origin != Vec3d::Zero())
|
||||
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_MOVED, std::move(wipe_tower_origin)));
|
||||
if (wipe_tower_origin != Vec3d::Zero()) {
|
||||
m_model->wipe_tower.position = Vec2d(wipe_tower_origin[0], wipe_tower_origin[1]);
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_WIPETOWER_TOUCHED));
|
||||
}
|
||||
|
||||
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) {
|
||||
update_sequential_clearance(true);
|
||||
@ -3999,7 +4000,8 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||
const Vec3d offset = v->get_volume_offset();
|
||||
Vec3d rot_unit_x = v->get_volume_transformation().get_matrix().linear() * Vec3d::UnitX();
|
||||
double z_rot = std::atan2(rot_unit_x.y(), rot_unit_x.x());
|
||||
post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), z_rot)));
|
||||
m_model->wipe_tower.position = Vec2d(offset.x(), offset.y());
|
||||
m_model->wipe_tower.rotation = (180./M_PI) * z_rot;
|
||||
}
|
||||
const int object_idx = v->object_idx();
|
||||
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
|
||||
@ -4316,9 +4318,9 @@ GLCanvas3D::WipeTowerInfo GLCanvas3D::get_wipe_tower_info() const
|
||||
|
||||
for (const GLVolume* vol : m_volumes.volumes) {
|
||||
if (vol->is_wipe_tower) {
|
||||
wti.m_pos = Vec2d(m_config->opt_float("wipe_tower_x"),
|
||||
m_config->opt_float("wipe_tower_y"));
|
||||
wti.m_rotation = (M_PI/180.) * m_config->opt_float("wipe_tower_rotation_angle");
|
||||
wti.m_pos = Vec2d(m_model->wipe_tower.position.x(),
|
||||
m_model->wipe_tower.position.y());
|
||||
wti.m_rotation = (M_PI/180.) * m_model->wipe_tower.rotation;
|
||||
const BoundingBoxf3& bb = vol->bounding_box();
|
||||
wti.m_bb = BoundingBoxf{to_2d(bb.min), to_2d(bb.max)};
|
||||
break;
|
||||
@ -6885,11 +6887,8 @@ const SLAPrint* GLCanvas3D::sla_print() const
|
||||
|
||||
void GLCanvas3D::WipeTowerInfo::apply_wipe_tower(Vec2d pos, double rot)
|
||||
{
|
||||
DynamicPrintConfig cfg;
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = pos.x();
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = pos.y();
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_rotation_angle", true)->value = (180./M_PI) * rot;
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
|
||||
wxGetApp().plater()->model().wipe_tower.position = pos;
|
||||
wxGetApp().plater()->model().wipe_tower.rotation = (180./M_PI) * rot;
|
||||
}
|
||||
|
||||
void GLCanvas3D::RenderTimer::Notify()
|
||||
|
@ -163,12 +163,11 @@ wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); // data: +1 => increase, -1 => decrease
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_TOUCHED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MIRRORED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_STARTED, SimpleEvent);
|
||||
@ -919,8 +918,6 @@ public:
|
||||
inline double rotation() const { return m_rotation; }
|
||||
inline const Vec2d bb_size() const { return m_bb.size(); }
|
||||
inline const BoundingBoxf& bounding_box() const { return m_bb; }
|
||||
|
||||
void apply_wipe_tower() const { apply_wipe_tower(m_pos, m_rotation); }
|
||||
|
||||
static void apply_wipe_tower(Vec2d pos, double rot);
|
||||
};
|
||||
|
@ -427,8 +427,8 @@ public:
|
||||
if (wipe_tower_data.final_purge)
|
||||
m_final.emplace_back(*wipe_tower_data.final_purge.get());
|
||||
|
||||
m_angle = config.wipe_tower_rotation_angle.value / 180.0f * PI;
|
||||
m_position = Slic3r::Vec2f(config.wipe_tower_x.value, config.wipe_tower_y.value);
|
||||
m_angle = print.model().wipe_tower.rotation / 180.0f * PI;
|
||||
m_position = print.model().wipe_tower.position.cast<float>();
|
||||
m_layers_count = wipe_tower_data.tool_changes.size() + (m_priming.empty() ? 0 : 1);
|
||||
}
|
||||
|
||||
|
@ -614,7 +614,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
|
||||
"bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance",
|
||||
"brim_width", "brim_separation", "brim_type", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material",
|
||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extra_flow", "wipe_tower_extruder",
|
||||
"wipe_tower", "wipe_tower_width", "wipe_tower_brim_width", "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extra_flow", "wipe_tower_extruder",
|
||||
"extruder_colour", "filament_colour", "material_colour", "max_print_height", "printer_model", "printer_notes", "printer_technology",
|
||||
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
|
||||
"layer_height", "first_layer_height", "min_layer_height", "max_layer_height",
|
||||
@ -701,8 +701,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
{ if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_FORCE_UPDATE, [this](SimpleEvent&) { update(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_TOUCHED,[this](SimpleEvent&) { update(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_RESET_SKEW, [this](SimpleEvent&) { update(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); });
|
||||
@ -1301,8 +1300,10 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
if (! config_substitutions.empty())
|
||||
show_substitutions_info(config_substitutions.substitutions, filename.string());
|
||||
|
||||
if (load_config)
|
||||
if (load_config) {
|
||||
this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z;
|
||||
this->model.wipe_tower = model.wipe_tower;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_config) {
|
||||
@ -3234,19 +3235,13 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
|
||||
|
||||
void Plater::priv::on_wipetower_moved(Vec3dEvent &evt)
|
||||
{
|
||||
DynamicPrintConfig cfg;
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = evt.data(0);
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = evt.data(1);
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
|
||||
model.wipe_tower.position = Vec2d(evt.data[0], evt.data[1]);
|
||||
}
|
||||
|
||||
void Plater::priv::on_wipetower_rotated(Vec3dEvent& evt)
|
||||
{
|
||||
DynamicPrintConfig cfg;
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_x", true)->value = evt.data(0);
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_y", true)->value = evt.data(1);
|
||||
cfg.opt<ConfigOptionFloat>("wipe_tower_rotation_angle", true)->value = Geometry::rad2deg(evt.data(2));
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
|
||||
model.wipe_tower.position = Vec2d(evt.data[0], evt.data[1]);
|
||||
model.wipe_tower.rotation = Geometry::rad2deg(evt.data(2));
|
||||
}
|
||||
|
||||
void Plater::priv::on_update_geometry(Vec3dsEvent<2>&)
|
||||
@ -3789,13 +3784,6 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed
|
||||
if (view3D->get_canvas3d()->get_gizmos_manager().wants_reslice_supports_on_undo())
|
||||
snapshot_data.flags |= UndoRedo::SnapshotData::RECALCULATE_SLA_SUPPORTS;
|
||||
|
||||
//FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config.
|
||||
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
|
||||
if (this->printer_technology == ptFFF) {
|
||||
const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y"));
|
||||
model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle");
|
||||
}
|
||||
const GLGizmosManager& gizmos = view3D->get_canvas3d()->get_gizmos_manager();
|
||||
|
||||
if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator && get_config_bool("clear_undo_redo_stack_on_new_project"))
|
||||
@ -3865,13 +3853,6 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
||||
}
|
||||
// Save the last active preset name of a particular printer technology.
|
||||
((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name();
|
||||
//FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config.
|
||||
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
|
||||
if (this->printer_technology == ptFFF) {
|
||||
const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y"));
|
||||
model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle");
|
||||
}
|
||||
const int layer_range_idx = it_snapshot->snapshot_data.layer_range_idx;
|
||||
// Flags made of Snapshot::Flags enum values.
|
||||
unsigned int new_flags = it_snapshot->snapshot_data.flags;
|
||||
@ -3921,22 +3902,6 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
||||
// This also switches the printer technology based on the printer technology of the active printer profile.
|
||||
wxGetApp().load_current_presets();
|
||||
}
|
||||
//FIXME updating the Print config from the Wipe tower config values at the ModelWipeTower.
|
||||
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
|
||||
if (this->printer_technology == ptFFF) {
|
||||
const DynamicPrintConfig ¤t_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
Vec2d current_position(current_config.opt_float("wipe_tower_x"), current_config.opt_float("wipe_tower_y"));
|
||||
double current_rotation = current_config.opt_float("wipe_tower_rotation_angle");
|
||||
if (current_position != model.wipe_tower.position || current_rotation != model.wipe_tower.rotation) {
|
||||
DynamicPrintConfig new_config;
|
||||
new_config.set_key_value("wipe_tower_x", new ConfigOptionFloat(model.wipe_tower.position.x()));
|
||||
new_config.set_key_value("wipe_tower_y", new ConfigOptionFloat(model.wipe_tower.position.y()));
|
||||
new_config.set_key_value("wipe_tower_rotation_angle", new ConfigOptionFloat(model.wipe_tower.rotation));
|
||||
Tab *tab_print = wxGetApp().get_tab(Preset::TYPE_PRINT);
|
||||
tab_print->load_config(new_config);
|
||||
tab_print->update_dirty();
|
||||
}
|
||||
}
|
||||
// set selection mode for ObjectList on sidebar
|
||||
this->sidebar->obj_list()->set_selection_mode(new_selected_settings_on_sidebar ? ObjectList::SELECTION_MODE::smSettings :
|
||||
new_selected_layer_on_sidebar ? ObjectList::SELECTION_MODE::smLayer :
|
||||
|
@ -1635,10 +1635,7 @@ void TabPrint::build()
|
||||
|
||||
optgroup = page->new_optgroup(L("Wipe tower"));
|
||||
optgroup->append_single_option_line("wipe_tower");
|
||||
optgroup->append_single_option_line("wipe_tower_x");
|
||||
optgroup->append_single_option_line("wipe_tower_y");
|
||||
optgroup->append_single_option_line("wipe_tower_width");
|
||||
optgroup->append_single_option_line("wipe_tower_rotation_angle");
|
||||
optgroup->append_single_option_line("wipe_tower_width");
|
||||
optgroup->append_single_option_line("wipe_tower_brim_width");
|
||||
optgroup->append_single_option_line("wipe_tower_bridging");
|
||||
optgroup->append_single_option_line("wipe_tower_cone_angle");
|
||||
|
Loading…
x
Reference in New Issue
Block a user