Merge branch 'master' into pm_support_spots_generator
This commit is contained in:
commit
52a7703447
16 changed files with 187 additions and 77 deletions
|
@ -395,8 +395,7 @@ struct GlobalModelInfo {
|
|||
;
|
||||
|
||||
//Extract perimeter polygons of the given layer
|
||||
Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition configured_seam_preference,
|
||||
std::vector<const LayerRegion*> &corresponding_regions_out) {
|
||||
Polygons extract_perimeter_polygons(const Layer *layer, std::vector<const LayerRegion*> &corresponding_regions_out) {
|
||||
Polygons polygons;
|
||||
for (const LayerRegion *layer_region : layer->regions()) {
|
||||
for (const ExtrusionEntity *ex_entity : layer_region->perimeters.entities) {
|
||||
|
@ -411,9 +410,7 @@ Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition confi
|
|||
}
|
||||
}
|
||||
|
||||
if (role == ExtrusionRole::erExternalPerimeter
|
||||
|| (is_perimeter(role)
|
||||
&& configured_seam_preference == spRandom)) { //for random seam alignment, extract all perimeters
|
||||
if (role == ExtrusionRole::erExternalPerimeter) {
|
||||
Points p;
|
||||
perimeter->collect_points(p);
|
||||
polygons.emplace_back(std::move(p));
|
||||
|
@ -1044,14 +1041,13 @@ public:
|
|||
// Parallel process and extract each perimeter polygon of the given print object.
|
||||
// Gather SeamCandidates of each layer into vector and build KDtree over them
|
||||
// Store results in the SeamPlacer variables m_seam_per_object
|
||||
void SeamPlacer::gather_seam_candidates(const PrintObject *po,
|
||||
const SeamPlacerImpl::GlobalModelInfo &global_model_info, const SeamPosition configured_seam_preference) {
|
||||
void SeamPlacer::gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info) {
|
||||
using namespace SeamPlacerImpl;
|
||||
PrintObjectSeamData &seam_data = m_seam_per_object.emplace(po, PrintObjectSeamData { }).first->second;
|
||||
seam_data.layers.resize(po->layer_count());
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, po->layers().size()),
|
||||
[po, configured_seam_preference, &global_model_info, &seam_data]
|
||||
[po, &global_model_info, &seam_data]
|
||||
(tbb::blocked_range<size_t> r) {
|
||||
for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) {
|
||||
PrintObjectSeamData::LayerSeams &layer_seams = seam_data.layers[layer_idx];
|
||||
|
@ -1059,7 +1055,7 @@ void SeamPlacer::gather_seam_candidates(const PrintObject *po,
|
|||
auto unscaled_z = layer->slice_z;
|
||||
std::vector<const LayerRegion*> regions;
|
||||
//NOTE corresponding region ptr may be null, if the layer has zero perimeters
|
||||
Polygons polygons = extract_perimeter_polygons(layer, configured_seam_preference, regions);
|
||||
Polygons polygons = extract_perimeter_polygons(layer, regions);
|
||||
for (size_t poly_index = 0; poly_index < polygons.size(); ++poly_index) {
|
||||
process_perimeter_polygon(polygons[poly_index], unscaled_z,
|
||||
regions[poly_index], global_model_info, layer_seams);
|
||||
|
@ -1468,7 +1464,7 @@ void SeamPlacer::init(const Print &print, std::function<void(void)> throw_if_can
|
|||
throw_if_canceled_func();
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "SeamPlacer: gather_seam_candidates: start";
|
||||
gather_seam_candidates(po, global_model_info, configured_seam_preference);
|
||||
gather_seam_candidates(po, global_model_info);
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "SeamPlacer: gather_seam_candidates: end";
|
||||
throw_if_canceled_func();
|
||||
|
@ -1533,7 +1529,7 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
|
|||
const size_t layer_index = layer->id() - po->slicing_parameters().raft_layers();
|
||||
const double unscaled_z = layer->slice_z;
|
||||
|
||||
auto get_next_loop_point = [&loop](ExtrusionLoop::ClosestPathPoint current) {
|
||||
auto get_next_loop_point = [loop](ExtrusionLoop::ClosestPathPoint current) {
|
||||
current.segment_idx += 1;
|
||||
if (current.segment_idx >= loop.paths[current.path_idx].polyline.points.size()) {
|
||||
current.path_idx = next_idx_modulo(current.path_idx, loop.paths.size());
|
||||
|
@ -1556,7 +1552,7 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
|
|||
size_t points_count = std::accumulate(loop.paths.begin(), loop.paths.end(), 0, [](size_t acc,const ExtrusionPath& p) {
|
||||
return acc + p.polyline.points.size();
|
||||
});
|
||||
for (size_t _ = 0; _ < points_count; ++_) {
|
||||
for (size_t i = 0; i < points_count; ++i) {
|
||||
Vec2f unscaled_p = unscaled<float>(closest_point.foot_pt);
|
||||
closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(),
|
||||
to_3d(unscaled_p, float(unscaled_z)));
|
||||
|
@ -1586,13 +1582,12 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
|
|||
|
||||
Point seam_point = Point::new_scale(seam_position.x(), seam_position.y());
|
||||
|
||||
if (const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index];
|
||||
(po->config().seam_position == spNearest || po->config().seam_position == spAligned) &&
|
||||
loop.role() == ExtrusionRole::erPerimeter && //Hopefully internal perimeter
|
||||
(seam_position - perimeter_point.position).squaredNorm() < 4.0f && // seam is on perimeter point
|
||||
perimeter_point.local_ccw_angle < -EPSILON // In concave angles
|
||||
) { // In this case, we are at internal perimeter, where the external perimeter has seam in concave angle. We want to align
|
||||
// the internal seam into the concave corner, and not on the perpendicular projection on the closest edge (which is what the split_at function does)
|
||||
if (loop.role() == ExtrusionRole::erPerimeter) { //Hopefully inner perimeter
|
||||
const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index];
|
||||
ExtrusionLoop::ClosestPathPoint projected_point = loop.get_closest_path_and_point(seam_point, false);
|
||||
// determine depth of the seam point.
|
||||
float depth = (float) unscale(Point(seam_point - projected_point.foot_pt)).norm();
|
||||
float beta_angle = cos(perimeter_point.local_ccw_angle / 2.0f);
|
||||
size_t index_of_prev =
|
||||
seam_index == perimeter_point.perimeter.start_index ?
|
||||
perimeter_point.perimeter.end_index - 1 :
|
||||
|
@ -1602,18 +1597,46 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
|
|||
perimeter_point.perimeter.start_index :
|
||||
seam_index + 1;
|
||||
|
||||
Vec2f dir_to_middle =
|
||||
((perimeter_point.position - layer_perimeters.points[index_of_prev].position).head<2>().normalized()
|
||||
+ (perimeter_point.position - layer_perimeters.points[index_of_next].position).head<2>().normalized())
|
||||
* 0.5;
|
||||
if ((seam_position - perimeter_point.position).squaredNorm() < depth && // seam is on perimeter point
|
||||
perimeter_point.local_ccw_angle < -EPSILON // In concave angles
|
||||
) { // In this case, we are at internal perimeter, where the external perimeter has seam in concave angle. We want to align
|
||||
// the internal seam into the concave corner, and not on the perpendicular projection on the closest edge (which is what the split_at function does)
|
||||
Vec2f dir_to_middle =
|
||||
((perimeter_point.position - layer_perimeters.points[index_of_prev].position).head<2>().normalized()
|
||||
+ (perimeter_point.position - layer_perimeters.points[index_of_next].position).head<2>().normalized())
|
||||
* 0.5;
|
||||
depth = 1.4142 * depth / beta_angle;
|
||||
// There are some nice geometric identities in determination of the correct depth of new seam point.
|
||||
//overshoot the target depth, in concave angles it will correctly snap to the corner; TODO: find out why such big overshoot is needed.
|
||||
Vec2f final_pos = perimeter_point.position.head<2>() + depth * dir_to_middle;
|
||||
projected_point = loop.get_closest_path_and_point(Point::new_scale(final_pos.x(), final_pos.y()), false);
|
||||
} else { // not concave angle, in that case the nearest point is the good candidate
|
||||
// but for staggering, we also need to recompute depth of the inner perimter, because in convex corners, the distance is larger than layer width
|
||||
// we want the perpendicular depth, not distance to nearest point
|
||||
depth = depth * beta_angle / 1.4142;
|
||||
}
|
||||
|
||||
ExtrusionLoop::ClosestPathPoint projected_point = loop.get_closest_path_and_point(seam_point, true);
|
||||
//get closest projected point, determine depth of the seam point.
|
||||
float depth = (float) unscale(Point(seam_point - projected_point.foot_pt)).norm();
|
||||
float angle_factor = cos(-perimeter_point.local_ccw_angle / 2.0f); // There are some nice geometric identities in determination of the correct depth of new seam point.
|
||||
//overshoot the target depth, in concave angles it will correctly snap to the corner; TODO: find out why such big overshoot is needed.
|
||||
Vec2f final_pos = perimeter_point.position.head<2>() + (1.4142 * depth / angle_factor) * dir_to_middle;
|
||||
seam_point = Point::new_scale(final_pos.x(), final_pos.y());
|
||||
seam_point = projected_point.foot_pt;
|
||||
|
||||
//lastly, for internal perimeters, do the staggering if requested
|
||||
if (po->config().staggered_inner_seams && loop.length() > 0.0) {
|
||||
//fix depth, it is sometimes strongly underestimated
|
||||
depth = std::max(loop.paths[projected_point.path_idx].width, depth);
|
||||
|
||||
while (depth > 0.0f) {
|
||||
auto next_point = get_next_loop_point(projected_point);
|
||||
Vec2f a = unscale(projected_point.foot_pt).cast<float>();
|
||||
Vec2f b = unscale(next_point.foot_pt).cast<float>();
|
||||
float dist = (a - b).norm();
|
||||
if (dist > depth) {
|
||||
Vec2f final_pos = a + (b - a) * depth / dist;
|
||||
next_point.foot_pt = Point::new_scale(final_pos.x(), final_pos.y());
|
||||
}
|
||||
depth -= dist;
|
||||
projected_point = next_point;
|
||||
}
|
||||
seam_point = projected_point.foot_pt;
|
||||
}
|
||||
}
|
||||
|
||||
// Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns,
|
||||
|
|
|
@ -143,8 +143,7 @@ public:
|
|||
void place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first, const Point &last_pos) const;
|
||||
|
||||
private:
|
||||
void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info,
|
||||
const SeamPosition configured_seam_preference);
|
||||
void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info);
|
||||
void calculate_candidates_visibility(const PrintObject *po,
|
||||
const SeamPlacerImpl::GlobalModelInfo &global_model_info);
|
||||
void calculate_overhangs_and_layer_embedding(const PrintObject *po);
|
||||
|
|
|
@ -550,12 +550,16 @@ void Transformation::set_rotation(Axis axis, double rotation)
|
|||
Vec3d Transformation::get_scaling_factor() const
|
||||
{
|
||||
const Transform3d scale = extract_scale(m_matrix);
|
||||
return { scale(0, 0), scale(1, 1), scale(2, 2) };
|
||||
return { std::abs(scale(0, 0)), std::abs(scale(1, 1)), std::abs(scale(2, 2)) };
|
||||
}
|
||||
|
||||
Transform3d Transformation::get_scaling_factor_matrix() const
|
||||
{
|
||||
return extract_scale(m_matrix);
|
||||
Transform3d scale = extract_scale(m_matrix);
|
||||
scale(0, 0) = std::abs(scale(0, 0));
|
||||
scale(1, 1) = std::abs(scale(1, 1));
|
||||
scale(2, 2) = std::abs(scale(2, 2));
|
||||
return scale;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
|
@ -577,6 +581,8 @@ void Transformation::set_scaling_factor(const Vec3d& scaling_factor)
|
|||
void Transformation::set_scaling_factor(Axis axis, double scaling_factor)
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
assert(scaling_factor > 0.0);
|
||||
|
||||
auto [rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
scale(axis, axis) = scaling_factor;
|
||||
|
||||
|
@ -600,8 +606,11 @@ Vec3d Transformation::get_mirror() const
|
|||
|
||||
Transform3d Transformation::get_mirror_matrix() const
|
||||
{
|
||||
const Vec3d scale = get_scaling_factor();
|
||||
return scale_transform({ scale.x() / std::abs(scale.x()), scale.y() / std::abs(scale.y()), scale.z() / std::abs(scale.z()) });
|
||||
Transform3d scale = extract_scale(m_matrix);
|
||||
scale(0, 0) = scale(0, 0) / std::abs(scale(0, 0));
|
||||
scale(1, 1) = scale(1, 1) / std::abs(scale(1, 1));
|
||||
scale(2, 2) = scale(2, 2) / std::abs(scale(2, 2));
|
||||
return scale;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
|
||||
|
@ -617,13 +626,17 @@ void Transformation::set_mirror(const Vec3d& mirror)
|
|||
copy(i) /= abs_mirror(i);
|
||||
}
|
||||
|
||||
const Vec3d curr_scale = get_scaling_factor();
|
||||
const Vec3d signs = curr_scale.cwiseProduct(copy);
|
||||
set_scaling_factor({
|
||||
signs.x() < 0.0 ? std::abs(curr_scale.x()) * copy.x() : curr_scale.x(),
|
||||
signs.y() < 0.0 ? std::abs(curr_scale.y()) * copy.y() : curr_scale.y(),
|
||||
signs.z() < 0.0 ? std::abs(curr_scale.z()) * copy.z() : curr_scale.z()
|
||||
});
|
||||
auto [rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
const Vec3d curr_scales = { scale(0, 0), scale(1, 1), scale(2, 2) };
|
||||
const Vec3d signs = curr_scales.cwiseProduct(copy);
|
||||
|
||||
if (signs[0] < 0.0) scale(0, 0) = -scale(0, 0);
|
||||
if (signs[1] < 0.0) scale(1, 1) = -scale(1, 1);
|
||||
if (signs[2] < 0.0) scale(2, 2) = -scale(2, 2);
|
||||
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation * scale;
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
set_mirror(X, mirror.x());
|
||||
set_mirror(Y, mirror.y());
|
||||
|
@ -640,9 +653,15 @@ void Transformation::set_mirror(Axis axis, double mirror)
|
|||
mirror /= abs_mirror;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
const double curr_scale = get_scaling_factor(axis);
|
||||
auto [rotation, scale] = extract_rotation_scale(m_matrix);
|
||||
const double curr_scale = scale(axis, axis);
|
||||
const double sign = curr_scale * mirror;
|
||||
set_scaling_factor(axis, sign < 0.0 ? std::abs(curr_scale) * mirror : curr_scale);
|
||||
|
||||
if (sign < 0.0) scale(axis, axis) = -scale(axis, axis);
|
||||
|
||||
const Vec3d offset = get_offset();
|
||||
m_matrix = rotation * scale;
|
||||
m_matrix.translation() = offset;
|
||||
#else
|
||||
if (m_mirror(axis) != mirror) {
|
||||
m_mirror(axis) = mirror;
|
||||
|
@ -746,7 +765,6 @@ Transform3d Transformation::get_matrix_no_scaling_factor() const
|
|||
{
|
||||
Transformation copy(*this);
|
||||
copy.reset_scaling_factor();
|
||||
copy.reset_mirror();
|
||||
return copy.get_matrix();
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -421,7 +421,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "slicing_mode",
|
||||
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
|
||||
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
|
||||
"seam_position","staggered_inner_seams", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
|
||||
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
|
||||
"ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing",
|
||||
|
|
|
@ -2253,6 +2253,12 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spAligned));
|
||||
|
||||
def = this->add("staggered_inner_seams", coBool);
|
||||
def->label = L("Staggered inner seams");
|
||||
def->tooltip = L("This option causes the inner seams to be shifted backwards based on their depth, forming a zigzag pattern.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
#if 0
|
||||
def = this->add("seam_preferred_direction", coFloat);
|
||||
// def->gui_type = ConfigOptionDef::GUIType::slider;
|
||||
|
|
|
@ -503,6 +503,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloat, raft_first_layer_expansion))
|
||||
((ConfigOptionInt, raft_layers))
|
||||
((ConfigOptionEnum<SeamPosition>, seam_position))
|
||||
((ConfigOptionBool, staggered_inner_seams))
|
||||
// ((ConfigOptionFloat, seam_preferred_direction))
|
||||
// ((ConfigOptionFloat, seam_preferred_direction_jitter))
|
||||
((ConfigOptionFloat, slice_closing_radius))
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
#include "SVG.hpp"
|
||||
#endif
|
||||
|
||||
#pragma message ("TODO: Wrap svg usages in DEBUG ifdef and remove the following include")
|
||||
#include "SVG.hpp"
|
||||
|
||||
// #undef NDEBUG
|
||||
#include <cassert>
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||
{
|
||||
bool have_perimeters = config->opt_int("perimeters") > 0;
|
||||
for (auto el : { "extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
|
||||
"seam_position","staggered_inner_seams", "external_perimeters_first", "external_perimeter_extrusion_width",
|
||||
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" })
|
||||
toggle_field(el, have_perimeters);
|
||||
|
||||
|
|
|
@ -5496,28 +5496,41 @@ void GLCanvas3D::_picking_pass()
|
|||
}
|
||||
default: { break; }
|
||||
}
|
||||
|
||||
auto add_strings_row_to_table = [&imgui](const std::string& col_1, const ImVec4& col_1_color, const std::string& col_2, const ImVec4& col_2_color) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
imgui.text_colored(col_1_color, col_1.c_str());
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
imgui.text_colored(col_2_color, col_2.c_str());
|
||||
};
|
||||
|
||||
char buf[1024];
|
||||
if (hit.type != SceneRaycaster::EType::None) {
|
||||
sprintf(buf, "Object ID: %d", hit.raycaster_id);
|
||||
imgui.text(std::string(buf));
|
||||
sprintf(buf, "Type: %s", object_type.c_str());
|
||||
imgui.text(std::string(buf));
|
||||
sprintf(buf, "Position: %.3f, %.3f, %.3f", hit.position.x(), hit.position.y(), hit.position.z());
|
||||
imgui.text(std::string(buf));
|
||||
sprintf(buf, "Normal: %.3f, %.3f, %.3f", hit.normal.x(), hit.normal.y(), hit.normal.z());
|
||||
imgui.text(std::string(buf));
|
||||
if (ImGui::BeginTable("Hit", 2)) {
|
||||
add_strings_row_to_table("Object ID", ImGuiWrapper::COL_ORANGE_LIGHT, std::to_string(hit.raycaster_id), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
add_strings_row_to_table("Type", ImGuiWrapper::COL_ORANGE_LIGHT, object_type, ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
sprintf(buf, "%.3f, %.3f, %.3f", hit.position.x(), hit.position.y(), hit.position.z());
|
||||
add_strings_row_to_table("Position", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
sprintf(buf, "%.3f, %.3f, %.3f", hit.normal.x(), hit.normal.y(), hit.normal.z());
|
||||
add_strings_row_to_table("Normal", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
else
|
||||
imgui.text("NO HIT");
|
||||
|
||||
ImGui::Separator();
|
||||
imgui.text("Registered for picking:");
|
||||
sprintf(buf, "Beds: %d", (int)m_scene_raycaster.beds_count());
|
||||
imgui.text(std::string(buf));
|
||||
sprintf(buf, "Volumes: %d", (int)m_scene_raycaster.volumes_count());
|
||||
imgui.text(std::string(buf));
|
||||
sprintf(buf, "Gizmo elements: %d", (int)m_scene_raycaster.gizmos_count());
|
||||
imgui.text(std::string(buf));
|
||||
if (ImGui::BeginTable("Raycasters", 2)) {
|
||||
sprintf(buf, "%d (%d)", (int)m_scene_raycaster.beds_count(), (int)m_scene_raycaster.active_beds_count());
|
||||
add_strings_row_to_table("Beds", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
sprintf(buf, "%d (%d)", (int)m_scene_raycaster.volumes_count(), (int)m_scene_raycaster.active_volumes_count());
|
||||
add_strings_row_to_table("Volumes", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
sprintf(buf, "%d (%d)", (int)m_scene_raycaster.gizmos_count(), (int)m_scene_raycaster.active_gizmos_count());
|
||||
add_strings_row_to_table("Gizmo elements", ImGuiWrapper::COL_ORANGE_LIGHT, std::string(buf), ImGui::GetStyleColorVec4(ImGuiCol_Text));
|
||||
ImGui::EndTable();
|
||||
}
|
||||
imgui.end();
|
||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||
}
|
||||
|
|
|
@ -56,6 +56,9 @@ static const std::map<const wchar_t, std::string> font_icons = {
|
|||
{ImGui::PreferencesHoverButton, "notification_preferences_hover"},
|
||||
{ImGui::SliderFloatEditBtnIcon, "edit_button" },
|
||||
{ImGui::SliderFloatEditBtnPressedIcon, "edit_button_pressed" },
|
||||
};
|
||||
|
||||
static const std::map<const wchar_t, std::string> font_icons_large = {
|
||||
#if ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
{ImGui::LegendTravel , "legend_travel" },
|
||||
{ImGui::LegendWipe , "legend_wipe" },
|
||||
|
@ -70,9 +73,6 @@ static const std::map<const wchar_t, std::string> font_icons = {
|
|||
{ImGui::LegendShells , "legend_shells" },
|
||||
{ImGui::LegendToolMarker , "legend_toolmarker" },
|
||||
#endif // ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
};
|
||||
|
||||
static const std::map<const wchar_t, std::string> font_icons_large = {
|
||||
{ImGui::CloseNotifButton , "notification_close" },
|
||||
{ImGui::CloseNotifHoverButton , "notification_close_hover" },
|
||||
{ImGui::EjectButton , "notification_eject_sd" },
|
||||
|
@ -94,7 +94,6 @@ static const std::map<const wchar_t, std::string> font_icons_large = {
|
|||
|
||||
static const std::map<const wchar_t, std::string> font_icons_extra_large = {
|
||||
{ImGui::ClippyMarker , "notification_clippy" },
|
||||
|
||||
};
|
||||
|
||||
const ImVec4 ImGuiWrapper::COL_GREY_DARK = { 0.33f, 0.33f, 0.33f, 1.0f };
|
||||
|
|
|
@ -203,6 +203,35 @@ int SceneRaycaster::base_id(EType type)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if ENABLE_RAYCAST_PICKING_DEBUG
|
||||
size_t SceneRaycaster::active_beds_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (const auto& item : m_bed) {
|
||||
if (item->is_active()) ++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t SceneRaycaster::active_volumes_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (const auto& item : m_volumes) {
|
||||
if (item->is_active()) ++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t SceneRaycaster::active_gizmos_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (const auto& item : m_gizmos) {
|
||||
if (item->is_active()) ++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||
|
||||
int SceneRaycaster::encode_id(EType type, int id) { return base_id(type) + id; }
|
||||
int SceneRaycaster::decode_id(EType type, int id) { return id - base_id(type); }
|
||||
|
||||
|
|
|
@ -100,6 +100,9 @@ public:
|
|||
size_t beds_count() const { return m_bed.size(); }
|
||||
size_t volumes_count() const { return m_volumes.size(); }
|
||||
size_t gizmos_count() const { return m_gizmos.size(); }
|
||||
size_t active_beds_count() const;
|
||||
size_t active_volumes_count() const;
|
||||
size_t active_gizmos_count() const;
|
||||
#endif // ENABLE_RAYCAST_PICKING_DEBUG
|
||||
|
||||
private:
|
||||
|
|
|
@ -2981,6 +2981,7 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
|||
const Geometry::Transformation& curr_inst_trafo_i = volume_i->get_instance_transformation();
|
||||
const Vec3d curr_inst_rotation_i = curr_inst_trafo_i.get_rotation();
|
||||
const Vec3d& curr_inst_scaling_factor_i = curr_inst_trafo_i.get_scaling_factor();
|
||||
const Vec3d& curr_inst_mirror_i = curr_inst_trafo_i.get_mirror();
|
||||
const Vec3d old_inst_rotation_i = m_cache.volumes_data[i].get_instance_transform().get_rotation();
|
||||
#else
|
||||
const Vec3d& rotation = volume_i->get_instance_rotation();
|
||||
|
@ -3053,7 +3054,7 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
|
|||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
volume_j->set_instance_transformation(Geometry::assemble_transform(new_inst_offset_j, new_inst_rotation_j,
|
||||
curr_inst_scaling_factor_i));
|
||||
curr_inst_scaling_factor_i, curr_inst_mirror_i));
|
||||
#else
|
||||
volume_j->set_instance_scaling_factor(scaling_factor);
|
||||
volume_j->set_instance_mirror(mirror);
|
||||
|
|
|
@ -1440,6 +1440,7 @@ void TabPrint::build()
|
|||
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup->append_single_option_line("seam_position", category_path + "seam-position");
|
||||
optgroup->append_single_option_line("staggered_inner_seams", category_path + "staggered-inner-seams");
|
||||
optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
|
||||
optgroup->append_single_option_line("gap_fill_enabled", category_path + "fill-gaps");
|
||||
optgroup->append_single_option_line("perimeter_generator");
|
||||
|
|
|
@ -35,6 +35,24 @@ Repetier::Repetier(DynamicPrintConfig *config) :
|
|||
|
||||
const char* Repetier::get_name() const { return "Repetier"; }
|
||||
|
||||
|
||||
|
||||
static bool validate_repetier(const boost::optional<std::string>& name,
|
||||
const boost::optional<std::string>& soft)
|
||||
{
|
||||
if (soft) {
|
||||
// See https://github.com/prusa3d/PrusaSlicer/issues/7807:
|
||||
// Repetier allows "rebranding", so the "name" value is not reliable when detecting
|
||||
// server type. Newer Repetier versions send "software", which should be invariant.
|
||||
return ((*soft) == "Repetier-Server");
|
||||
} else {
|
||||
// If there is no "software" value, validate as we did before:
|
||||
return name ? boost::starts_with(*name, "Repetier") : true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Repetier::test(wxString &msg) const
|
||||
{
|
||||
// Since the request is performed synchronously here,
|
||||
|
@ -62,11 +80,12 @@ bool Repetier::test(wxString &msg) const
|
|||
std::stringstream ss(body);
|
||||
pt::ptree ptree;
|
||||
pt::read_json(ss, ptree);
|
||||
|
||||
|
||||
const auto text = ptree.get_optional<std::string>("name");
|
||||
res = validate_version_text(text);
|
||||
const auto soft = ptree.get_optional<std::string>("software");
|
||||
res = validate_repetier(text, soft);
|
||||
if (! res) {
|
||||
msg = GUI::from_u8((boost::format(_utf8(L("Mismatched type of print host: %s"))) % (text ? *text : "Repetier")).str());
|
||||
msg = GUI::from_u8((boost::format(_utf8(L("Mismatched type of print host: %s"))) % (soft ? *soft : (text ? *text : "Repetier"))).str());
|
||||
}
|
||||
}
|
||||
catch (const std::exception &) {
|
||||
|
@ -129,6 +148,7 @@ bool Repetier::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error
|
|||
|
||||
if(upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||
http.form_add("name", upload_filename.string());
|
||||
http.form_add("autostart", "true"); // See https://github.com/prusa3d/PrusaSlicer/issues/7807#issuecomment-1235519371
|
||||
}
|
||||
|
||||
http.form_add("a", "upload")
|
||||
|
@ -154,10 +174,7 @@ bool Repetier::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, Error
|
|||
return res;
|
||||
}
|
||||
|
||||
bool Repetier::validate_version_text(const boost::optional<std::string> &version_text) const
|
||||
{
|
||||
return version_text ? boost::starts_with(*version_text, "Repetier") : true;
|
||||
}
|
||||
|
||||
|
||||
void Repetier::set_auth(Http &http) const
|
||||
{
|
||||
|
|
|
@ -33,9 +33,6 @@ public:
|
|||
bool get_groups(wxArrayString &groups) const override;
|
||||
bool get_printers(wxArrayString &printers) const override;
|
||||
|
||||
protected:
|
||||
virtual bool validate_version_text(const boost::optional<std::string> &version_text) const;
|
||||
|
||||
private:
|
||||
std::string host;
|
||||
std::string apikey;
|
||||
|
|
Loading…
Add table
Reference in a new issue