Merge branch 'master' into fs_fix_for_Allura_script_font

This commit is contained in:
Filip Sykala - NTB T15p 2023-01-26 16:33:03 +01:00
commit 9f525da15e
22 changed files with 202 additions and 105 deletions

View file

@ -2308,7 +2308,8 @@ void GCode::process_layer_single_object(
ExtrusionEntitiesPtr temp_fill_extrusions;
if (const Layer *layer = layer_to_print.object_layer; layer)
for (const LayerSlice &lslice : layer->lslices_ex) {
for (size_t idx : layer->lslice_indices_sorted_by_print_order) {
const LayerSlice &lslice = layer->lslices_ex[idx];
auto extrude_infill_range = [&](
const LayerRegion &layerm, const ExtrusionEntityCollection &fills,
LayerExtrusionRanges::const_iterator it_fill_ranges_begin, LayerExtrusionRanges::const_iterator it_fill_ranges_end, bool ironing) {

View file

@ -728,7 +728,7 @@ void Transformation::reset_skew()
const double average_scale = std::cbrt(scale(0, 0) * scale(1, 1) * scale(2, 2));
scale(0, 0) = average_scale;
scale(0, 0) = is_left_handed() ? -average_scale : average_scale;
scale(1, 1) = average_scale;
scale(2, 2) = average_scale;

View file

@ -470,7 +470,7 @@ public:
Transform3d get_mirror_matrix() const;
bool is_left_handed() const {
return m_matrix.affine().determinant() < 0;
return m_matrix.linear().determinant() < 0;
}
#else
bool is_scaling_uniform() const { return std::abs(m_scaling_factor.x() - m_scaling_factor.y()) < 1e-8 && std::abs(m_scaling_factor.x() - m_scaling_factor.z()) < 1e-8; }

View file

@ -38,32 +38,37 @@ LayerRegion* Layer::add_region(const PrintRegion *print_region)
// merge all regions' slices to get islands
void Layer::make_slices()
{
ExPolygons slices;
if (m_regions.size() == 1) {
// optimization: if we only have one region, take its slices
slices = to_expolygons(m_regions.front()->slices().surfaces);
} else {
Polygons slices_p;
for (LayerRegion *layerm : m_regions)
polygons_append(slices_p, to_polygons(layerm->slices().surfaces));
slices = union_safety_offset_ex(slices_p);
{
ExPolygons slices;
if (m_regions.size() == 1) {
// optimization: if we only have one region, take its slices
slices = to_expolygons(m_regions.front()->slices().surfaces);
} else {
Polygons slices_p;
for (LayerRegion *layerm : m_regions)
polygons_append(slices_p, to_polygons(layerm->slices().surfaces));
slices = union_safety_offset_ex(slices_p);
}
// lslices are sorted by topological order from outside to inside from the clipper union used above
this->lslices = slices;
}
this->lslices.clear();
this->lslices.reserve(slices.size());
// prepare lslices ordered by print order
this->lslice_indices_sorted_by_print_order.clear();
this->lslice_indices_sorted_by_print_order.reserve(lslices.size());
// prepare ordering points
Points ordering_points;
ordering_points.reserve(slices.size());
for (const ExPolygon &ex : slices)
ordering_points.reserve( this->lslices.size());
for (const ExPolygon &ex : this->lslices)
ordering_points.push_back(ex.contour.first_point());
// sort slices
std::vector<Points::size_type> order = chain_points(ordering_points);
// populate slices vector
for (size_t i : order)
this->lslices.emplace_back(std::move(slices[i]));
for (size_t i : order) {
this->lslice_indices_sorted_by_print_order.emplace_back(i);
}
}
// used by Layer::build_up_down_graph()

View file

@ -336,6 +336,7 @@ public:
// These lslices are also used to detect overhangs and overlaps between successive layers, therefore it is important
// that the 1st lslice is not compensated by the Elephant foot compensation algorithm.
ExPolygons lslices;
std::vector<size_t> lslice_indices_sorted_by_print_order;
LayerSlices lslices_ex;
size_t region_count() const { return m_regions.size(); }

View file

@ -444,7 +444,7 @@ static std::vector<std::string> s_Preset_print_options {
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
"min_skirt_length", "brim_width", "brim_separation", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
"min_skirt_length", "brim_width", "brim_separation", "brim_type", "check_for_issues_mode", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_closing_radius", "support_material_style",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_bottom_interface_layers",

View file

@ -537,7 +537,7 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloat(60));
def = this->add("enable_dynamic_overhang_speeds", coBool);
def->label = L("Enable dynamic overhang speeds (Experimental)");
def->label = L("Enable dynamic overhang speeds");
def->category = L("Speed");
def->tooltip = L("This setting enables dynamic speed control on overhangs.");
def->mode = comAdvanced;
@ -2589,6 +2589,14 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
def = this->add("check_for_issues_mode", coBool);
def->label = L("Check for issues: ");
def->category = L("Support material");
def->tooltip = L("Check for supportable issues that may appear during printing. "
"If enabled, slicer will make alerts when it detects "
"issues that may be resolved with supports and/or brim.");
def->set_default_value(new ConfigOptionBool(true));
def = this->add("support_material", coBool);
def->label = L("Generate support material");
def->category = L("Support material");

View file

@ -516,6 +516,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInt, wall_distribution_count))
((ConfigOptionFloatOrPercent, min_feature_size))
((ConfigOptionFloatOrPercent, min_bead_width))
((ConfigOptionBool, check_for_issues_mode))
((ConfigOptionBool, support_material))
// Automatic supports (generated based fdm support point generator).
((ConfigOptionBool, support_material_auto))

View file

@ -462,7 +462,7 @@ void PrintObject::generate_support_spots()
}
};
if (!this->has_support()) {
if (!this->has_support() && this->config().check_for_issues_mode.getBool()) {
SupportSpotsGenerator::raise_alerts_for_issues(supp_points, partial_objects, alert_fn);
}
}
@ -619,6 +619,8 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posSupportSpotsSearch);
// Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial);
}else if (opt_key == "check_for_issues_mode") {
steps.emplace_back(posSupportSpotsSearch);
} else if (
opt_key == "perimeters"
|| opt_key == "extra_perimeters"

View file

@ -799,7 +799,7 @@ void PrintObject::slice_volumes()
layer->m_regions[region_id]->trim_surfaces(trimming);
}
}
// Merge all regions' slices to get islands, chain them by a shortest path.
// Merge all regions' slices to get islands sorted topologically, chain them by a shortest path in separate index list
layer->make_slices();
}
});

View file

@ -260,8 +260,8 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
SupportPointCause potential_cause = std::abs(curr_point.curvature) > 0.1 ? SupportPointCause::FloatingBridgeAnchor :
SupportPointCause::LongBridge;
float line_len = i > 0 ? ((annotated_points[i - 1].position - curr_point.position).norm()) : 0.0f;
Vec2d line_dir = (curr_point.position - prev_point.position).normalized();
float line_len = i > 0 ? ((annotated_points[i - 1].position - curr_point.position).norm()) : 0.0f;
Vec2d line_dir = line_len > EPSILON ? Vec2d((curr_point.position - prev_point.position) / double(line_len)) : Vec2d::Zero();
ExtrusionLine line_out{i > 0 ? annotated_points[i - 1].position.cast<float>() : curr_point.position.cast<float>(),
curr_point.position.cast<float>(), line_len, entity};
@ -335,14 +335,6 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
line_out.form_quality = 0.8f;
bridged_distance += line_len;
if (bridged_distance > max_bridge_len) {
std::cout << "Problem found A: " << std::endl;
std::cout << "bridged_distance: " << bridged_distance << std::endl;
std::cout << "max_bridge_len: " << max_bridge_len << std::endl;
std::cout << "line_out.form_quality: " << line_out.form_quality << std::endl;
std::cout << "curr_point.distance: " << curr_point.distance << std::endl;
std::cout << "curr_point.curvature: " << curr_point.curvature << std::endl;
std::cout << "flow_width: " << flow_width << std::endl;
line_out.support_point_generated = potential_cause;
bridged_distance = 0.0f;
}
@ -350,14 +342,6 @@ std::vector<ExtrusionLine> check_extrusion_entity_stability(const ExtrusionEntit
bridged_distance += line_len;
line_out.form_quality = nearest_prev_layer_line.form_quality - 0.3f;
if (line_out.form_quality < 0 && bridged_distance > max_bridge_len) {
std::cout << "Problem found B: " << std::endl;
std::cout << "bridged_distance: " << bridged_distance << std::endl;
std::cout << "max_bridge_len: " << max_bridge_len << std::endl;
std::cout << "line_out.form_quality: " << line_out.form_quality << std::endl;
std::cout << "curr_point.distance: " << curr_point.distance << std::endl;
std::cout << "curr_point.curvature: " << curr_point.curvature << std::endl;
std::cout << "flow_width: " << flow_width << std::endl;
line_out.support_point_generated = potential_cause;
line_out.form_quality = 0.5f;
bridged_distance = 0.0f;
@ -662,7 +646,8 @@ std::tuple<ObjectPart, float> build_object_part_from_slice(const size_t &slice_i
}
// BRIM HANDLING
if (layer->id() == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim) {
if (layer->id() == params.raft_layers_count && params.raft_layers_count == 0 && params.brim_type != BrimType::btNoBrim &&
params.brim_width > 0.0) {
// TODO: The algorithm here should take into account that multiple slices may have coliding Brim areas and the final brim area is
// smaller,
// thus has lower adhesion. For now this effect will be neglected.
@ -921,7 +906,8 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject *po,
for (const auto &perimeter_idx : island.perimeters) {
const ExtrusionEntity *entity = perimeter_region->perimeters().entities[perimeter_idx];
std::vector<ExtrusionLine> perims = check_extrusion_entity_stability(entity, perimeter_region,
prev_layer_ext_perim_lines,prev_layer_boundary, params);
prev_layer_ext_perim_lines, prev_layer_boundary,
params);
for (const ExtrusionLine &perim : perims) {
if (perim.support_point_generated.has_value()) {
reckon_new_support_point(*perim.support_point_generated, create_support_point_position(perim.b), -EPSILON,
@ -932,6 +918,30 @@ std::tuple<SupportPoints, PartialObjects> check_stability(const PrintObject *po,
}
}
}
// DEBUG EXPORT, NOT USED NOW
// if (BR_bridge) {
// Lines scaledl;
// for (const auto &l : prev_layer_boundary.get_lines()) {
// scaledl.emplace_back(Point::new_scale(l.a), Point::new_scale(l.b));
// }
// Lines perimsl;
// for (const auto &l : current_slice_ext_perims_lines) {
// perimsl.emplace_back(Point::new_scale(l.a), Point::new_scale(l.b));
// }
// BoundingBox bb = get_extents(scaledl);
// bb.merge(get_extents(perimsl));
// ::Slic3r::SVG svg(debug_out_path(
// ("slice" + std::to_string(slice_idx) + "_" + std::to_string(layer_idx).c_str()).c_str()),
// get_extents(scaledl));
// svg.draw(scaledl, "red", scale_(0.4));
// svg.draw(perimsl, "blue", scale_(0.25));
// svg.Close();
// }
}
LD current_slice_lines_distancer(current_slice_ext_perims_lines);
@ -1165,13 +1175,6 @@ void raise_alerts_for_issues(const SupportPoints
PartialObjects &partial_objects,
std::function<void(PrintStateBase::WarningLevel, SupportPointCause)> alert_fn)
{
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::SeparationFromBed) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::SeparationFromBed);
break;
}
}
std::reverse(partial_objects.begin(), partial_objects.end());
std::sort(partial_objects.begin(), partial_objects.end(),
[](const PartialObject &left, const PartialObject &right) { return left.volume > right.volume; });
@ -1221,21 +1224,29 @@ void raise_alerts_for_issues(const SupportPoints
}
}
if (ext_supp_points.size() > 5) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::FloatingExtrusion);
}
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::LongBridge) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge);
break;
if (sp.cause == SupportPointCause::SeparationFromBed) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::SeparationFromBed);
return;
}
}
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::WeakObjectPart) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::WeakObjectPart);
break;
return;
}
}
if (ext_supp_points.size() > 5) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::FloatingExtrusion);
return;
}
for (const SupportPoint &sp : support_points) {
if (sp.cause == SupportPointCause::LongBridge) {
alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge);
return;
}
}
}

View file

@ -21,8 +21,6 @@
#include "MutablePolygon.hpp"
#include "SupportMaterial.hpp"
#include "TriangleMeshSlicer.hpp"
#include "OpenVDBUtilsLegacy.hpp"
#include <openvdb/tools/VolumeToSpheres.h>
#include <cassert>
#include <chrono>
@ -45,6 +43,14 @@
#define TREE_SUPPORT_SHOW_ERRORS_WIN32
#endif
// #define TREE_SUPPORT_ORGANIC_NUDGE_NEW 1
#ifndef TREE_SUPPORT_ORGANIC_NUDGE_NEW
// Old version using OpenVDB, works but it is extremely slow for complex meshes.
#include "OpenVDBUtilsLegacy.hpp"
#include <openvdb/tools/VolumeToSpheres.h>
#endif // TREE_SUPPORT_ORGANIC_NUDGE_NEW
namespace Slic3r
{
@ -3389,8 +3395,6 @@ static void extrude_branch(
}
#endif
// #define TREE_SUPPORT_ORGANIC_NUDGE_NEW 1
#ifdef TREE_SUPPORT_ORGANIC_NUDGE_NEW
// New version using per layer AABB trees of lines for nudging spheres away from an object.
static void organic_smooth_branches_avoid_collisions(

View file

@ -146,8 +146,7 @@ void Downloader::start_download(const std::string& full_url)
#else
std::string escaped_url = FileGet::escape_url(full_url.substr(24));
#endif
if (!boost::starts_with(escaped_url, "https://files.printables.com") && !boost::starts_with(escaped_url, "https://dev-files.printables.com")) {
if (!boost::starts_with(escaped_url, "https://") || !FileGet::is_subdomain(escaped_url, "printables.com")) {
std::string msg = format(_L("Download won't start. Download URL doesn't point to https://files.printables.com : %1%"), escaped_url);
BOOST_LOG_TRIVIAL(error) << msg;
NotificationManager* ntf_mngr = wxGetApp().notification_manager();

View file

@ -5,6 +5,7 @@
#include <boost/nowide/fstream.hpp>
#include <boost/format.hpp>
#include <boost/log/trivial.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include "format.hpp"
@ -30,6 +31,42 @@ std::string FileGet::escape_url(const std::string& unescaped)
}
return ret_val;
}
bool FileGet::is_subdomain(const std::string& url, const std::string& domain)
{
// domain should be f.e. printables.com (.com including)
char* host;
std::string host_string;
CURLUcode rc;
CURLU* curl = curl_url();
if (!curl) {
BOOST_LOG_TRIVIAL(error) << "Failed to init Curl library in function is_domain.";
return false;
}
rc = curl_url_set(curl, CURLUPART_URL, url.c_str(), 0);
if (rc != CURLUE_OK) {
curl_url_cleanup(curl);
return false;
}
rc = curl_url_get(curl, CURLUPART_HOST, &host, 0);
if (rc != CURLUE_OK || !host) {
curl_url_cleanup(curl);
return false;
}
host_string = std::string(host);
curl_free(host);
// now host should be subdomain.domain or just domain
if (domain == host_string) {
curl_url_cleanup(curl);
return true;
}
if(boost::ends_with(host_string, "." + domain)) {
curl_url_cleanup(curl);
return true;
}
curl_url_cleanup(curl);
return false;
}
namespace {
unsigned get_current_pid()
{

View file

@ -23,7 +23,8 @@ public:
void cancel();
void pause();
void resume();
static std::string escape_url(const std::string& url);
static std::string escape_url(const std::string& url);
static bool is_subdomain(const std::string& url, const std::string& domain);
private:
std::unique_ptr<priv> p;
};

View file

@ -3401,12 +3401,7 @@ void GUI_App::app_updater(bool from_user)
if (dialog_result != wxID_OK) {
return;
}
if (dwnld_dlg.get_download_path().parent_path().empty() || !boost::filesystem::exists(dwnld_dlg.get_download_path().parent_path())) {
show_error(nullptr,GUI::format_wxstr(_L("Download can't proceed. Target directory doesn't exists: %1%"), dwnld_dlg.get_download_path().parent_path().string()));
return;
}
app_data.target_path =dwnld_dlg.get_download_path();
// start download
this->plater_->get_notification_manager()->push_download_progress_notification(_utf8("Download"), std::bind(&AppUpdater::cancel_callback, this->m_app_updater.get()));
app_data.start_after = dwnld_dlg.run_after_download();

View file

@ -53,7 +53,7 @@ static SettingsFactory::Bundle FREQ_SETTINGS_BUNDLE_FFF =
{
{ L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } },
{ L("Infill") , { "fill_density", "fill_pattern" } },
{ L("Support material") , { "support_material", "support_material_auto", "support_material_threshold",
{ L("Support material") , { "check_for_issues_mode", "support_material", "support_material_auto", "support_material_threshold",
"support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
"support_material_spacing" } },
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }

View file

@ -235,7 +235,11 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
add_label(&m_scale_Label, L("Scale"), v_sizer);
wxStaticText* size_Label {nullptr};
add_label(&size_Label, L("Size"), v_sizer);
#if ENABLE_WORLD_COORDINATE
add_label(&size_Label, L("Size [World]"), v_sizer);
#else
add_label(&size_Label, L("Size"), v_sizer);
#endif // ENABLE_WORLD_COORDINATE
if (wxOSX) set_font_and_background_style(size_Label, wxGetApp().normal_font());
sizer->Add(v_sizer, 0, wxLEFT, border);
@ -479,11 +483,18 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
#if ENABLE_WORLD_COORDINATE
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
Selection& selection = canvas->get_selection();
if (selection.is_single_volume_or_modifier())
if (selection.is_single_volume_or_modifier()) {
const bool is_left_handed = selection.get_first_volume()->get_volume_transformation().is_left_handed();
const_cast<GLVolume*>(selection.get_first_volume())->set_volume_scaling_factor(Vec3d::Ones());
if (is_left_handed)
const_cast<GLVolume*>(selection.get_first_volume())->set_volume_mirror({ -1.0 , 1.0, 1.0 });
}
else if (selection.is_single_full_instance()) {
const bool is_left_handed = selection.get_first_volume()->get_instance_transformation().is_left_handed();
for (unsigned int idx : selection.get_volume_idxs()) {
const_cast<GLVolume*>(selection.get_volume(idx))->set_instance_scaling_factor(Vec3d::Ones());
if (is_left_handed)
const_cast<GLVolume*>(selection.get_volume(idx))->set_instance_mirror({ -1.0 , 1.0, 1.0 });
}
}
else
@ -712,21 +723,21 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
#if ENABLE_WORLD_COORDINATE
if (is_world_coordinates()) {
m_new_position = volume->get_instance_offset();
m_new_scale_label_string = L("Scale");
m_new_scale = Vec3d(100.0, 100.0, 100.0);
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0;
m_new_rotate_label_string = L("Rotate (relative)");
#else
if (m_world_coordinates) {
m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0;
m_new_size = selection.get_scaled_instance_bounding_box().size();
#endif // ENABLE_WORLD_COORDINATE
m_new_rotate_label_string = L("Rotate");
#endif // ENABLE_WORLD_COORDINATE
m_new_rotation = Vec3d::Zero();
}
else {
#if ENABLE_WORLD_COORDINATE
m_new_move_label_string = L("Translate");
m_new_rotate_label_string = L("Rotate");
m_new_move_label_string = L("Translate (relative) [World]");
m_new_rotate_label_string = L("Rotate (relative)");
m_new_position = Vec3d::Zero();
m_new_rotation = Vec3d::Zero();
m_new_scale = Vec3d(100.0, 100.0, 100.0);
@ -768,15 +779,15 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
const Vec3d& offset = trafo.get_offset();
m_new_position = offset;
m_new_rotate_label_string = L("Rotate");
m_new_rotate_label_string = L("Rotate (relative)");
m_new_scale_label_string = L("Scale");
m_new_scale = Vec3d(100.0, 100.0, 100.0);
m_new_rotation = Vec3d::Zero();
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
}
else if (is_local_coordinates()) {
m_new_move_label_string = L("Translate");
m_new_rotate_label_string = L("Rotate");
m_new_move_label_string = L("Translate (relative) [World]");
m_new_rotate_label_string = L("Rotate (relative)");
m_new_position = Vec3d::Zero();
m_new_rotation = Vec3d::Zero();
m_new_scale = volume->get_volume_scaling_factor() * 100.0;
@ -785,7 +796,11 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
else {
#endif // ENABLE_WORLD_COORDINATE
m_new_position = volume->get_volume_offset();
#if ENABLE_WORLD_COORDINATE
m_new_rotate_label_string = L("Rotate (relative)");
#else
m_new_rotate_label_string = L("Rotate");
#endif // ENABLE_WORLD_COORDINATE
m_new_rotation = Vec3d::Zero();
#if ENABLE_WORLD_COORDINATE
m_new_scale_label_string = L("Scale");
@ -1221,10 +1236,8 @@ void ObjectManipulation::change_scale_value(int axis, double value)
scale = scale.cwiseQuotient(ref_scale);
ref_scale = Vec3d::Ones();
}
else if (selection.is_single_full_instance()) {
scale = scale.cwiseQuotient(ref_scale);
ref_scale = Vec3d::Ones();
}
else if (selection.is_single_full_instance())
ref_scale = 100.0 * Vec3d::Ones();
this->do_scale(axis, scale.cwiseQuotient(ref_scale));
#else
@ -1276,9 +1289,9 @@ void ObjectManipulation::change_size_value(int axis, double value)
else if (selection.is_single_full_instance()) {
#if ENABLE_WORLD_COORDINATE
if (is_world_coordinates())
ref_size = selection.get_unscaled_instance_bounding_box().size();
size = size.cwiseQuotient(ref_size);
ref_size = Vec3d::Ones();
ref_size = selection.get_full_unscaled_instance_bounding_box().size();
else
ref_size = selection.get_full_unscaled_instance_local_bounding_box().size();
#else
ref_size = m_world_coordinates ?
selection.get_unscaled_instance_bounding_box().size() :
@ -1311,8 +1324,7 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
else if (is_instance_coordinates())
transformation_type.set_instance();
if (!(selection.is_single_volume_or_modifier() && is_local_coordinates()) &&
!(selection.is_single_full_instance() && is_instance_coordinates()))
if (selection.is_single_volume_or_modifier() && !is_local_coordinates())
transformation_type.set_relative();
const Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale;

View file

@ -969,7 +969,7 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor
v.set_instance_offset(inst_trafo.get_offset() + inst_trafo.get_rotation_matrix() * displacement);
}
else
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
transform_instance_relative_world(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
}
else {
if (transformation_type.local() && transformation_type.absolute()) {
@ -1066,7 +1066,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * inst_trafo.get_offset_matrix() * trafo * Transform3d(inst_scale) * Geometry::translation_transform(-local_inst_pivot));
}
else
transform_instance_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
transform_instance_relative_world(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
}
else {
if (!is_single_volume_or_modifier()) {
@ -1471,6 +1471,26 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
const VolumeCache& volume_data = m_cache.volumes_data[i];
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
Vec3d relative_scale = scale;
if (transformation_type.absolute()) {
if (m_mode == Instance) {
if (is_single_full_instance()) {
BoundingBoxf3 current_box = m_box.get_bounding_box();
BoundingBoxf3 original_box;
if (transformation_type.world())
original_box = get_full_unscaled_instance_bounding_box();
else
original_box = get_full_unscaled_instance_local_bounding_box();
relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(current_box.size());
transformation_type.set_relative();
}
}
else {
}
}
if (m_mode == Instance) {
if (transformation_type.instance()) {
const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset();
@ -1478,11 +1498,11 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
Matrix3d inst_rotation, inst_scale;
inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + inst_rotation * translation);
const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(scale);
const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale);
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot));
}
else
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
transform_instance_relative_world(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
}
else {
if (!is_single_volume_or_modifier()) {
@ -1509,9 +1529,9 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance)
synchronize_unselected_instances(SyncRotationType::NONE);
synchronize_unselected_instances(SyncRotationType::NONE);
else if (m_mode == Volume)
synchronize_unselected_volumes();
synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
ensure_on_bed();
@ -3297,7 +3317,7 @@ void Selection::paste_objects_from_clipboard()
}
#if ENABLE_WORLD_COORDINATE
void Selection::transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
void Selection::transform_instance_relative_world(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
const Transform3d& transform, const Vec3d& world_pivot)
{
assert(transformation_type.relative());

View file

@ -514,7 +514,7 @@ private:
void paste_objects_from_clipboard();
#if ENABLE_WORLD_COORDINATE
void transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
void transform_instance_relative_world(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
const Transform3d& transform, const Vec3d& world_pivot);
void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
const Transform3d& transform, const Vec3d& world_pivot);

View file

@ -1495,6 +1495,7 @@ void TabPrint::build()
page = add_options_page(L("Support material"), "support");
category_path = "support-material_1698#";
optgroup = page->new_optgroup(L("Support material"));
optgroup->append_single_option_line("check_for_issues_mode", category_path + "check-for-issues-mode");
optgroup->append_single_option_line("support_material", category_path + "generate-support-material");
optgroup->append_single_option_line("support_material_auto", category_path + "auto-generated-supports");
optgroup->append_single_option_line("support_material_threshold", category_path + "overhang-threshold");
@ -2190,10 +2191,9 @@ void TabFilament::clear_pages()
void TabFilament::msw_rescale()
{
for (const auto& over_opt : m_overrides_options) {
wxWindow* win = over_opt.second;
win->SetInitialSize(win->GetBestSize());
}
for (const auto& over_opt : m_overrides_options)
if (wxWindow* win = over_opt.second)
win->SetInitialSize(win->GetBestSize());
Tab::msw_rescale();
}

View file

@ -257,7 +257,7 @@ bool AppUpdateDownloadDialog::run_after_download() const
boost::filesystem::path AppUpdateDownloadDialog::get_download_path() const
{
boost::system::error_code ec;
std::string input = GUI::format(txtctrl_path->GetValue());
std::string input = GUI::into_u8(txtctrl_path->GetValue());
boost::filesystem::path dir = boost::filesystem::absolute(boost::filesystem::path(input), ec);
if (ec)
dir = boost::filesystem::path(input);