Merge branch 'master' into fs_fix_for_Allura_script_font
This commit is contained in:
commit
9f525da15e
22 changed files with 202 additions and 105 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue