Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_sequential
This commit is contained in:
commit
b6c1c45940
4
deps/wxWidgets/wxWidgets.cmake
vendored
4
deps/wxWidgets/wxWidgets.cmake
vendored
@ -13,8 +13,8 @@ if (UNIX AND NOT APPLE) # wxWidgets will not use char as the underlying type for
|
||||
endif()
|
||||
|
||||
prusaslicer_add_cmake_project(wxWidgets
|
||||
URL https://github.com/prusa3d/wxWidgets/archive/4fd2120c913c20c3bb66ee9d01d8ff5087a8b90a.zip
|
||||
URL_HASH SHA256=5b59e8b4dccf73e109c6588f6a69bcfe4e02e930af53c43d5d1329c1f3d83ec9
|
||||
URL https://github.com/prusa3d/wxWidgets/archive/0b49beaacce17d90f0c370ecd73221abd089667a.zip
|
||||
URL_HASH SHA256=8fa978a76d6bd811b30eecc5124186b9ad54290b820f3a354e85bfa9dae6a5ce
|
||||
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG dep_NanoSVG
|
||||
CMAKE_ARGS
|
||||
-DwxBUILD_PRECOMP=ON
|
||||
|
@ -1492,7 +1492,7 @@ void ModelObject::process_connector_cut(ModelVolume* volume, const Transform3d&
|
||||
|
||||
// Perform cut
|
||||
TriangleMesh upper_mesh, lower_mesh;
|
||||
process_volume_cut(volume, instance_matrix, cut_matrix, attributes, upper_mesh, lower_mesh);
|
||||
process_volume_cut(volume, Transform3d::Identity(), cut_matrix, attributes, upper_mesh, lower_mesh);
|
||||
|
||||
// add small Z offset to better preview
|
||||
upper_mesh.translate((-0.05 * Vec3d::UnitZ()).cast<float>());
|
||||
|
@ -267,29 +267,34 @@ ThickLines ThickPolyline::thicklines() const
|
||||
// Removes the given distance from the end of the ThickPolyline
|
||||
void ThickPolyline::clip_end(double distance)
|
||||
{
|
||||
while (distance > 0) {
|
||||
Vec2d last_point = this->last_point().cast<double>();
|
||||
coordf_t last_width = this->width.back();
|
||||
this->points.pop_back();
|
||||
this->width.pop_back();
|
||||
if (this->points.empty())
|
||||
break;
|
||||
|
||||
Vec2d vec = this->last_point().cast<double>() - last_point;
|
||||
coordf_t width_diff = this->width.back() - last_width;
|
||||
double vec_length_sqr = vec.squaredNorm();
|
||||
if (vec_length_sqr > distance * distance) {
|
||||
double t = (distance / std::sqrt(vec_length_sqr));
|
||||
this->points.emplace_back((last_point + vec * t).cast<coord_t>());
|
||||
this->width.emplace_back(last_width + width_diff * t);
|
||||
assert(this->width.size() == (this->points.size() - 1) * 2);
|
||||
return;
|
||||
} else
|
||||
if (! this->empty()) {
|
||||
assert(this->width.size() == (this->points.size() - 1) * 2);
|
||||
while (distance > 0) {
|
||||
Vec2d last_point = this->last_point().cast<double>();
|
||||
this->points.pop_back();
|
||||
if (this->points.empty()) {
|
||||
assert(this->width.empty());
|
||||
break;
|
||||
}
|
||||
coordf_t last_width = this->width.back();
|
||||
this->width.pop_back();
|
||||
|
||||
distance -= std::sqrt(vec_length_sqr);
|
||||
Vec2d vec = this->last_point().cast<double>() - last_point;
|
||||
coordf_t width_diff = this->width.back() - last_width;
|
||||
double vec_length_sqr = vec.squaredNorm();
|
||||
if (vec_length_sqr > distance * distance) {
|
||||
double t = (distance / std::sqrt(vec_length_sqr));
|
||||
this->points.emplace_back((last_point + vec * t).cast<coord_t>());
|
||||
this->width.emplace_back(last_width + width_diff * t);
|
||||
assert(this->width.size() == (this->points.size() - 1) * 2);
|
||||
return;
|
||||
} else
|
||||
this->width.pop_back();
|
||||
|
||||
distance -= std::sqrt(vec_length_sqr);
|
||||
}
|
||||
}
|
||||
assert(this->width.size() == (this->points.size() - 1) * 2);
|
||||
assert(this->points.empty() ? this->width.empty() : this->width.size() == (this->points.size() - 1) * 2);
|
||||
}
|
||||
|
||||
void ThickPolyline::start_at_index(int index)
|
||||
|
@ -187,6 +187,7 @@ struct ThickPolyline {
|
||||
const Point& last_point() const { return this->points.back(); }
|
||||
size_t size() const { return this->points.size(); }
|
||||
bool is_valid() const { return this->points.size() >= 2; }
|
||||
bool empty() const { return this->points.empty(); }
|
||||
double length() const { return Slic3r::length(this->points); }
|
||||
|
||||
void clear() { this->points.clear(); this->width.clear(); }
|
||||
|
@ -452,7 +452,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops",
|
||||
"support_material_contact_distance", "support_material_bottom_contact_distance",
|
||||
"support_material_buildplate_only",
|
||||
"support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", "support_tree_branch_diameter_angle", "support_tree_top_rate", "support_tree_tip_diameter",
|
||||
"support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", "support_tree_branch_diameter_angle", "support_tree_top_rate", "support_tree_branch_distance", "support_tree_tip_diameter",
|
||||
"dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "perimeter_extruder",
|
||||
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
|
||||
|
@ -2910,6 +2910,18 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(5));
|
||||
|
||||
// Tree Support Branch Distance
|
||||
// How far apart the branches need to be when they touch the model. Making this distance small will cause
|
||||
// the tree support to touch the model at more points, causing better overhang but making support harder to remove.
|
||||
def = this->add("support_tree_branch_distance", coFloat);
|
||||
def->label = L("Branch Distance");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("How far apart the branches need to be when they touch the model. "
|
||||
"Making this distance small will cause the tree support to touch the model at more points, "
|
||||
"causing better overhang but making support harder to remove.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(1.));
|
||||
|
||||
def = this->add("support_tree_top_rate", coPercent);
|
||||
def->label = L("Branch Density");
|
||||
def->category = L("Support material");
|
||||
@ -2921,7 +2933,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 5;
|
||||
def->max_literal = 35;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionPercent(30));
|
||||
def->set_default_value(new ConfigOptionPercent(15));
|
||||
|
||||
def = this->add("temperature", coInts);
|
||||
def->label = L("Other layers");
|
||||
|
@ -555,6 +555,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, support_tree_branch_diameter))
|
||||
((ConfigOptionFloat, support_tree_branch_diameter_angle))
|
||||
((ConfigOptionPercent, support_tree_top_rate))
|
||||
((ConfigOptionFloat, support_tree_branch_distance))
|
||||
((ConfigOptionFloat, support_tree_tip_diameter))
|
||||
// The rest
|
||||
((ConfigOptionBool, thick_bridges))
|
||||
|
@ -693,6 +693,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "support_tree_branch_diameter"
|
||||
|| opt_key == "support_tree_branch_diameter_angle"
|
||||
|| opt_key == "support_tree_top_rate"
|
||||
|| opt_key == "support_tree_branch_distance"
|
||||
|| opt_key == "support_tree_tip_diameter"
|
||||
|| opt_key == "raft_expansion"
|
||||
|| opt_key == "raft_first_layer_density"
|
||||
@ -1658,7 +1659,9 @@ void PrintObject::bridge_over_infill()
|
||||
}
|
||||
|
||||
// generate sparse infill polylines from lower layers to get anchorable polylines
|
||||
Polylines lower_layer_polylines = po->get_layer(lidx)->lower_layer->generate_sparse_infill_polylines_for_anchoring();
|
||||
Polylines lower_layer_polylines = po->get_layer(lidx)->lower_layer
|
||||
? po->get_layer(lidx)->lower_layer->generate_sparse_infill_polylines_for_anchoring()
|
||||
: Polylines();
|
||||
|
||||
for (std::pair<const LayerSlice *, SurfacesPtr> candidates : bridging_surface_candidates) {
|
||||
if (candidates.second.empty()) {
|
||||
|
@ -89,7 +89,7 @@ TreeSupportMeshGroupSettings::TreeSupportMeshGroupSettings(const PrintObject &pr
|
||||
// this->minimum_support_area =
|
||||
// this->minimum_bottom_area =
|
||||
// this->support_offset =
|
||||
// this->support_tree_branch_distance = 2.5 * line_width ??
|
||||
this->support_tree_branch_distance = scaled<coord_t>(config.support_tree_branch_distance.value);
|
||||
this->support_tree_angle = std::clamp<double>(config.support_tree_angle * M_PI / 180., 0., 0.5 * M_PI - EPSILON);
|
||||
this->support_tree_angle_slow = std::clamp<double>(config.support_tree_angle_slow * M_PI / 180., 0., this->support_tree_angle - EPSILON);
|
||||
this->support_tree_branch_diameter = scaled<coord_t>(config.support_tree_branch_diameter.value);
|
||||
@ -329,6 +329,7 @@ void TreeModelVolumes::precalculate(const PrintObject& print_object, const coord
|
||||
for (int k = int(j - 1); k >= int(i); -- k) {
|
||||
std::string legend = format("radius-%1%", unscaled<float>(sorted[k].first.first));
|
||||
expolygons_with_attributes.push_back({ union_ex(sorted[k].second), SVG::ExPolygonAttributes(legend, std::string(colors[(k - int(i)) % num_colors]), 1.) });
|
||||
SVG::export_expolygons(debug_out_path("treesupport_cache-%s-%d-%s.svg", name.data(), sorted[i].first.second, legend.c_str()), { expolygons_with_attributes.back() });
|
||||
}
|
||||
// Render the range of per radius collision polygons into a common SVG.
|
||||
SVG::export_expolygons(debug_out_path("treesupport_cache-%s-%d.svg", name.data(), sorted[i].first.second), expolygons_with_attributes);
|
||||
@ -416,9 +417,6 @@ const Polygons& TreeModelVolumes::getAvoidance(const coord_t orig_radius, LayerI
|
||||
|
||||
const Polygons& TreeModelVolumes::getPlaceableAreas(const coord_t orig_radius, LayerIndex layer_idx, std::function<void()> throw_on_cancel) const
|
||||
{
|
||||
if (orig_radius == 0)
|
||||
return this->getCollision(0, layer_idx, true);
|
||||
|
||||
const coord_t radius = ceilRadius(orig_radius);
|
||||
if (std::optional<std::reference_wrapper<const Polygons>> result = m_placeable_areas_cache.getArea({ radius, layer_idx }); result)
|
||||
return (*result).get();
|
||||
@ -426,7 +424,11 @@ const Polygons& TreeModelVolumes::getPlaceableAreas(const coord_t orig_radius, L
|
||||
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate Placeable Areas at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
|
||||
tree_supports_show_error("Not precalculated Placeable areas requested."sv, false);
|
||||
}
|
||||
const_cast<TreeModelVolumes*>(this)->calculatePlaceables(radius, layer_idx, throw_on_cancel);
|
||||
if (orig_radius == 0)
|
||||
// Placable areas for radius 0 are calculated in the general collision code.
|
||||
return this->getCollision(0, layer_idx, true);
|
||||
else
|
||||
const_cast<TreeModelVolumes*>(this)->calculatePlaceables(radius, layer_idx, throw_on_cancel);
|
||||
return getPlaceableAreas(orig_radius, layer_idx, throw_on_cancel);
|
||||
}
|
||||
|
||||
@ -470,6 +472,7 @@ void TreeModelVolumes::calculateCollision(const std::vector<RadiusLayerPair> &ke
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate collisions and placable areas for radius and for layer 0 to max_layer_idx inclusive.
|
||||
void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex max_layer_idx, std::function<void()> throw_on_cancel)
|
||||
{
|
||||
// assert(radius == this->ceilRadius(radius));
|
||||
@ -480,12 +483,14 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
std::sort(layer_outline_indices.begin(), layer_outline_indices.end(),
|
||||
[this](size_t i, size_t j) { return m_layer_outlines[i].second.size() < m_layer_outlines[j].second.size(); });
|
||||
|
||||
const LayerIndex min_layer_last = m_collision_cache.getMaxCalculatedLayer(radius);
|
||||
std::vector<Polygons> data(max_layer_idx + 1 - min_layer_last, Polygons{});
|
||||
// Layer range for which the collisions will be calculated.
|
||||
LayerPolygonCache data;
|
||||
data.allocate(m_collision_cache.getMaxCalculatedLayer(radius) + 1, max_layer_idx + 1);
|
||||
|
||||
const bool calculate_placable = m_support_rests_on_model && radius == 0;
|
||||
std::vector<Polygons> data_placeable;
|
||||
LayerPolygonCache data_placeable;
|
||||
if (calculate_placable)
|
||||
data_placeable = std::vector<Polygons>(max_layer_idx + 1 - min_layer_last, Polygons{});
|
||||
data_placeable.allocate(data.idx_begin, data.idx_end);
|
||||
|
||||
for (size_t outline_idx : layer_outline_indices)
|
||||
if (const std::vector<Polygons> &outlines = m_layer_outlines[outline_idx].second; ! outlines.empty()) {
|
||||
@ -493,8 +498,6 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
const coord_t layer_height = settings.layer_height;
|
||||
const int z_distance_bottom_layers = int(round(double(settings.support_bottom_distance) / double(layer_height)));
|
||||
const int z_distance_top_layers = int(round(double(settings.support_top_distance) / double(layer_height)));
|
||||
const LayerIndex max_required_layer = std::min<LayerIndex>(outlines.size(), max_layer_idx + std::max(coord_t(1), z_distance_top_layers));
|
||||
const LayerIndex min_layer_bottom = std::max<LayerIndex>(0, min_layer_last - int(z_distance_bottom_layers));
|
||||
const coord_t xy_distance = outline_idx == m_current_outline_idx ? m_current_min_xy_dist :
|
||||
// technically this causes collision for the normal xy_distance to be larger by m_current_min_xy_dist_delta for all
|
||||
// not currently processing meshes as this delta will be added at request time.
|
||||
@ -505,35 +508,40 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
settings.support_xy_distance;
|
||||
|
||||
// 1) Calculate offsets of collision areas in parallel.
|
||||
std::vector<Polygons> collision_areas_offsetted(max_required_layer + 1 - min_layer_bottom);
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_bottom, max_required_layer + 1),
|
||||
[&outlines, &machine_border = std::as_const(m_machine_border), offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel]
|
||||
LayerPolygonCache collision_areas_offsetted;
|
||||
collision_areas_offsetted.allocate(
|
||||
std::max<LayerIndex>(0, data.idx_begin - z_distance_bottom_layers),
|
||||
std::min<LayerIndex>(outlines.size(), data.idx_end + z_distance_top_layers));
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(collision_areas_offsetted.idx_begin, collision_areas_offsetted.idx_end),
|
||||
[&outlines, &machine_border = std::as_const(m_machine_border), offset_value = radius + xy_distance, &collision_areas_offsetted, &throw_on_cancel]
|
||||
(const tbb::blocked_range<LayerIndex> &range) {
|
||||
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) {
|
||||
Polygons collision_areas = machine_border;
|
||||
append(collision_areas, outlines[layer_idx]);
|
||||
// jtRound is not needed here, as the overshoot can not cause errors in the algorithm, because no assumptions are made about the model.
|
||||
// if a key does not exist when it is accessed it is added!
|
||||
collision_areas_offsetted[layer_idx - min_layer_bottom] = offset_value == 0 ? union_(collision_areas) : offset(union_ex(collision_areas), offset_value, ClipperLib::jtMiter, 1.2);
|
||||
collision_areas_offsetted[layer_idx] = offset_value == 0 ?
|
||||
union_(collision_areas) :
|
||||
offset(union_ex(collision_areas), offset_value, ClipperLib::jtMiter, 1.2);
|
||||
throw_on_cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// 2) Sum over top / bottom ranges.
|
||||
const bool last = outline_idx == layer_outline_indices.size();
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_last + 1, max_layer_idx + 1),
|
||||
[&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, min_layer_bottom, radius,
|
||||
xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel]
|
||||
(const tbb::blocked_range<LayerIndex>& range) {
|
||||
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) {
|
||||
const bool processing_last_mesh = outline_idx == layer_outline_indices.size();
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(data.idx_begin, data.idx_end),
|
||||
[&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, radius,
|
||||
xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, processing_last_mesh, &throw_on_cancel]
|
||||
(const tbb::blocked_range<LayerIndex>& range) {
|
||||
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) {
|
||||
Polygons collisions;
|
||||
for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) {
|
||||
int j = layer_idx + i - min_layer_bottom;
|
||||
if (j >= 0 && j < int(collision_areas_offsetted.size()) && i <= 0)
|
||||
for (int i = - z_distance_bottom_layers; i <= 0; ++ i)
|
||||
if (int j = layer_idx + i; collision_areas_offsetted.has(j))
|
||||
append(collisions, collision_areas_offsetted[j]);
|
||||
else if (j >= 0 && layer_idx + i < int(outlines.size()) && i > 0) {
|
||||
for (int i = 1; i <= z_distance_top_layers; ++ i)
|
||||
if (int j = layer_idx + i; j < int(outlines.size())) {
|
||||
Polygons collision_areas_original = machine_border;
|
||||
append(collision_areas_original, outlines[layer_idx + i]);
|
||||
append(collision_areas_original, outlines[j]);
|
||||
|
||||
// If just the collision (including the xy distance) of the layers above is accumulated, it leads to the
|
||||
// following issue:
|
||||
@ -566,37 +574,37 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
// the conditional -0.5 ensures that plastic can never touch on the diagonal
|
||||
// downward when the z_distance_top_layers = 1. It is assumed to be better to
|
||||
// not support an overhang<90 degree than to risk fusing to it.
|
||||
|
||||
collision_areas_original = offset(union_ex(collision_areas_original), radius + required_range_x, ClipperLib::jtMiter, 1.2);
|
||||
append(collisions, collision_areas_original);
|
||||
append(collisions, offset(union_ex(collision_areas_original), radius + required_range_x, ClipperLib::jtMiter, 1.2));
|
||||
}
|
||||
}
|
||||
collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions);
|
||||
auto &dst = data[layer_idx - (min_layer_last + 1)];
|
||||
if (last) {
|
||||
collisions = processing_last_mesh && layer_idx < int(anti_overhang.size()) ?
|
||||
union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) :
|
||||
union_(collisions);
|
||||
auto &dst = data[layer_idx];
|
||||
if (processing_last_mesh) {
|
||||
if (! dst.empty())
|
||||
collisions = union_(collisions, dst);
|
||||
dst = polygons_simplify(collisions, min_resolution);
|
||||
} else
|
||||
append(dst, collisions);
|
||||
append(dst, std::move(collisions));
|
||||
throw_on_cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// 3) Optionally calculate placables.
|
||||
if (calculate_placable) {
|
||||
// Calculating both the collision areas and placable areas.
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(std::max(min_layer_last + 1, z_distance_bottom_layers + 1), max_layer_idx + 1),
|
||||
[&collision_areas_offsetted, &anti_overhang = m_anti_overhang, min_layer_bottom, z_distance_bottom_layers, last, min_resolution = m_min_resolution, &data_placeable, min_layer_last, &throw_on_cancel]
|
||||
// Now calculate the placable areas.
|
||||
tbb::parallel_for(tbb::blocked_range<LayerIndex>(std::max(data.idx_begin, 1), data.idx_end),
|
||||
[&collision_areas_offsetted, &anti_overhang = m_anti_overhang, processing_last_mesh,
|
||||
min_resolution = m_min_resolution, &data_placeable, &throw_on_cancel]
|
||||
(const tbb::blocked_range<LayerIndex>& range) {
|
||||
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) {
|
||||
LayerIndex layer_idx_below = layer_idx - (z_distance_bottom_layers + 1) - min_layer_bottom;
|
||||
LayerIndex layer_idx_below = layer_idx - 1;
|
||||
assert(layer_idx_below >= 0);
|
||||
auto ¤t = collision_areas_offsetted[layer_idx - min_layer_bottom];
|
||||
auto &below = collision_areas_offsetted[layer_idx_below];
|
||||
auto placable = diff(below, layer_idx < int(anti_overhang.size()) ? union_(current, anti_overhang[layer_idx - (z_distance_bottom_layers + 1)]) : current);
|
||||
auto &dst = data_placeable[layer_idx - (min_layer_last + 1)];
|
||||
if (last) {
|
||||
const Polygons ¤t = collision_areas_offsetted[layer_idx];
|
||||
const Polygons &below = collision_areas_offsetted[layer_idx_below];
|
||||
Polygons placable = diff(below, layer_idx_below < int(anti_overhang.size()) ? union_(current, anti_overhang[layer_idx_below]) : current);
|
||||
auto &dst = data_placeable[layer_idx];
|
||||
if (processing_last_mesh) {
|
||||
if (! dst.empty())
|
||||
placable = union_(placable, dst);
|
||||
dst = polygons_simplify(placable, min_resolution);
|
||||
@ -619,9 +627,9 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
|
||||
}
|
||||
#endif
|
||||
throw_on_cancel();
|
||||
m_collision_cache.insert(std::move(data), min_layer_last + 1, radius);
|
||||
m_collision_cache.insert(std::move(data), radius);
|
||||
if (calculate_placable)
|
||||
m_placeable_areas_cache.insert(std::move(data_placeable), min_layer_last + 1, radius);
|
||||
m_placeable_areas_cache.insert(std::move(data_placeable), radius);
|
||||
}
|
||||
|
||||
void TreeModelVolumes::calculateCollisionHolefree(const std::vector<RadiusLayerPair> &keys, std::function<void()> throw_on_cancel)
|
||||
|
@ -328,6 +328,26 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// Caching polygons for a range of layers.
|
||||
struct LayerPolygonCache {
|
||||
std::vector<Polygons> polygons;
|
||||
LayerIndex idx_begin;
|
||||
LayerIndex idx_end;
|
||||
|
||||
void allocate(LayerIndex aidx_begin, LayerIndex aidx_end) {
|
||||
this->idx_begin = aidx_begin;
|
||||
this->idx_end = aidx_end;
|
||||
this->polygons.assign(aidx_end - aidx_begin, {});
|
||||
}
|
||||
|
||||
LayerIndex begin() const { return idx_begin; }
|
||||
LayerIndex end() const { return idx_end; }
|
||||
size_t size() const { return polygons.size(); }
|
||||
|
||||
bool has(LayerIndex idx) const { return idx >= idx_begin && idx < idx_end; }
|
||||
Polygons& operator[](LayerIndex idx) { return polygons[idx + idx_begin]; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Convenience typedef for the keys to the caches
|
||||
*/
|
||||
@ -363,6 +383,13 @@ private:
|
||||
for (auto &d : in)
|
||||
m_data[first_layer_idx ++].emplace(radius, std::move(d));
|
||||
}
|
||||
void insert(LayerPolygonCache &&in, coord_t radius) {
|
||||
std::lock_guard<std::mutex> guard(m_mutex);
|
||||
LayerIndex i = in.idx_begin;
|
||||
allocate_layers(i + LayerIndex(in.size()));
|
||||
for (auto &d : in.polygons)
|
||||
m_data[i ++].emplace(radius, std::move(d));
|
||||
}
|
||||
/*!
|
||||
* \brief Checks a cache for a given RadiusLayerPair and returns it if it is found
|
||||
* \param key RadiusLayerPair of the requested areas. The radius will be calculated up to the provided layer.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -122,7 +122,7 @@ struct SupportElementStateBits {
|
||||
bool use_min_xy_dist : 1;
|
||||
|
||||
/*!
|
||||
* \brief True if this Element or any parent provides support to a support roof.
|
||||
* \brief True if this Element or any parent (element above) provides support to a support roof.
|
||||
*/
|
||||
bool supports_roof : 1;
|
||||
|
||||
@ -193,7 +193,7 @@ struct SupportElementState : public SupportElementStateBits
|
||||
double elephant_foot_increases;
|
||||
|
||||
/*!
|
||||
* \brief The element trys not to move until this dtt is reached, is set to 0 if the element had to move.
|
||||
* \brief The element tries to not move until this dtt is reached, is set to 0 if the element had to move.
|
||||
*/
|
||||
uint32_t dont_move_until;
|
||||
|
||||
@ -218,6 +218,8 @@ struct SupportElementState : public SupportElementStateBits
|
||||
dst.skip_ovalisation = false;
|
||||
return dst;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool locked() const { return this->distance_to_top < this->dont_move_until; }
|
||||
};
|
||||
|
||||
struct SupportElement
|
||||
|
@ -109,26 +109,23 @@ Point Bed3D::point_projection(const Point& point) const
|
||||
return m_polygon.point_projection(point);
|
||||
}
|
||||
|
||||
void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture)
|
||||
void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_texture)
|
||||
{
|
||||
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture, false);
|
||||
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_texture, false);
|
||||
}
|
||||
|
||||
void Bed3D::render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor)
|
||||
{
|
||||
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, false, true);
|
||||
render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, true);
|
||||
}
|
||||
|
||||
void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
|
||||
bool show_axes, bool show_texture, bool picking)
|
||||
bool show_texture, bool picking)
|
||||
{
|
||||
m_scale_factor = scale_factor;
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
if (show_axes)
|
||||
render_axes();
|
||||
|
||||
m_model.model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
|
||||
|
||||
switch (m_type)
|
||||
@ -314,9 +311,6 @@ std::tuple<Bed3D::Type, std::string, std::string> Bed3D::detect_type(const Point
|
||||
|
||||
void Bed3D::render_axes()
|
||||
{
|
||||
if (!m_show_axes)
|
||||
return;
|
||||
|
||||
if (m_build_volume.valid())
|
||||
m_axes.render(Transform3d::Identity(), 0.25f);
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ private:
|
||||
CoordAxes m_axes;
|
||||
|
||||
float m_scale_factor{ 1.0f };
|
||||
bool m_show_axes{ true };
|
||||
|
||||
public:
|
||||
Bed3D() = default;
|
||||
@ -78,9 +77,8 @@ public:
|
||||
bool contains(const Point& point) const;
|
||||
Point point_projection(const Point& point) const;
|
||||
|
||||
void toggle_show_axes() { m_show_axes = !m_show_axes; }
|
||||
|
||||
void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture);
|
||||
void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_texture);
|
||||
void render_axes();
|
||||
void render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor);
|
||||
|
||||
private:
|
||||
@ -91,8 +89,7 @@ private:
|
||||
void init_contourlines();
|
||||
static std::tuple<Type, std::string, std::string> detect_type(const Pointfs& shape);
|
||||
void render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
|
||||
bool show_axes, bool show_texture, bool picking);
|
||||
void render_axes();
|
||||
bool show_texture, bool picking);
|
||||
void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture);
|
||||
void render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
void render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
|
@ -291,7 +291,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
(config->opt_bool("support_material") ||
|
||||
config->opt_int("support_material_enforce_layers") > 0);
|
||||
for (const std::string& key : { "support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter",
|
||||
"support_tree_branch_diameter_angle", "support_tree_tip_diameter", "support_tree_top_rate" })
|
||||
"support_tree_branch_diameter_angle", "support_tree_tip_diameter", "support_tree_branch_distance", "support_tree_top_rate" })
|
||||
toggle_field(key, has_organic_supports);
|
||||
|
||||
for (auto el : { "support_material_bottom_interface_layers", "support_material_interface_spacing", "support_material_interface_extruder",
|
||||
|
@ -1571,8 +1571,10 @@ void GLCanvas3D::render()
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque);
|
||||
_render_sla_slices();
|
||||
_render_selection();
|
||||
if (m_show_bed_axes)
|
||||
_render_bed_axes();
|
||||
if (is_looking_downward)
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), false, true);
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), false);
|
||||
if (!m_main_toolbar.is_enabled())
|
||||
_render_gcode();
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent);
|
||||
@ -1595,7 +1597,7 @@ void GLCanvas3D::render()
|
||||
_render_selection_sidebar_hints();
|
||||
_render_current_gizmo();
|
||||
if (!is_looking_downward)
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), true, true);
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), true);
|
||||
|
||||
#if ENABLE_RAYCAST_PICKING_DEBUG
|
||||
if (m_picking_enabled && !m_mouse.dragging && !m_gizmos.is_dragging() && !m_rectangle_selection.is_dragging())
|
||||
@ -2353,7 +2355,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||
#else /* __APPLE__ */
|
||||
case WXK_CONTROL_D:
|
||||
#endif /* __APPLE__ */
|
||||
m_bed.toggle_show_axes();
|
||||
m_show_bed_axes = !m_show_bed_axes;
|
||||
m_dirty = true;
|
||||
break;
|
||||
#ifdef __APPLE__
|
||||
@ -4357,7 +4359,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
if (thumbnail_params.show_bed)
|
||||
_render_bed(view_matrix, projection_matrix, !camera.is_looking_downward(), false);
|
||||
_render_bed(view_matrix, projection_matrix, !camera.is_looking_downward());
|
||||
|
||||
// restore background color
|
||||
if (thumbnail_params.transparent_background)
|
||||
@ -5411,7 +5413,7 @@ void GLCanvas3D::_render_background()
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes)
|
||||
void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom)
|
||||
{
|
||||
float scale_factor = 1.0;
|
||||
#if ENABLE_RETINA_GL
|
||||
@ -5425,7 +5427,12 @@ void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d&
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::Seam
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::MmuSegmentation);
|
||||
|
||||
m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture);
|
||||
m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_texture);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_bed_axes()
|
||||
{
|
||||
m_bed.render_axes();
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom)
|
||||
|
@ -520,6 +520,7 @@ private:
|
||||
ECursorType m_cursor_type;
|
||||
GLSelectionRectangle m_rectangle_selection;
|
||||
std::vector<int> m_hover_volume_idxs;
|
||||
bool m_show_bed_axes{ true };
|
||||
|
||||
// Following variable is obsolete and it should be safe to remove it.
|
||||
// I just don't want to do it now before a release (Lukas Matena 24.3.2019)
|
||||
@ -976,7 +977,8 @@ private:
|
||||
void _picking_pass();
|
||||
void _rectangular_selection_picking_pass();
|
||||
void _render_background();
|
||||
void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes);
|
||||
void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom);
|
||||
void _render_bed_axes();
|
||||
void _render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom);
|
||||
void _render_objects(GLVolumeCollection::ERenderType type);
|
||||
void _render_gcode();
|
||||
|
@ -1531,6 +1531,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("support_tree_branch_diameter", category_path + "tree_branch_diameter");
|
||||
optgroup->append_single_option_line("support_tree_branch_diameter_angle", category_path + "tree_branch_diameter_angle");
|
||||
optgroup->append_single_option_line("support_tree_tip_diameter", category_path + "tree_tip_diameter");
|
||||
optgroup->append_single_option_line("support_tree_branch_distance", category_path + "tree_branch_distance");
|
||||
optgroup->append_single_option_line("support_tree_top_rate", category_path + "tree_top_rate");
|
||||
|
||||
page = add_options_page(L("Speed"), "time");
|
||||
|
Loading…
Reference in New Issue
Block a user