mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 06:38:58 +08:00
Merge branch 'lm_seq_ht90'
This commit is contained in:
commit
0d9a72416e
@ -281,6 +281,62 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"printer_notes_regex": ".*PRINTER_MODEL_HT90.*",
|
||||
"gantry_model_filename": "prusa3d_ht90_actuator.stl",
|
||||
"slices": [
|
||||
{
|
||||
"height": "0",
|
||||
"type": "convex",
|
||||
"polygons": [
|
||||
"-5,-5; 5,-5; 5,5; -5,5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"height": "1",
|
||||
"type": "convex",
|
||||
"polygons": [
|
||||
"-33,-2; 33,-2; 33,48; -33,48",
|
||||
"-46,-37; 46,-37; 46,2; -46,2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"height": "20",
|
||||
"type": "convex",
|
||||
"polygons": [
|
||||
"-55,-55; 55,-55; 55,55; -55,55"
|
||||
]
|
||||
},
|
||||
{
|
||||
"height": "28",
|
||||
"type": "convex",
|
||||
"polygons": [
|
||||
"-76,-68; 76,-68; 76,65; -76,65"
|
||||
]
|
||||
},
|
||||
{
|
||||
"height": "40",
|
||||
"type": "convex",
|
||||
"polygons": [
|
||||
"-120,-118; 120,-118; 120,94; -120,94"
|
||||
]
|
||||
},
|
||||
{
|
||||
"height": "60",
|
||||
"type": "box",
|
||||
"polygons": [
|
||||
"-170,-164; 170,-164; 170,130; -170,130"
|
||||
]
|
||||
},
|
||||
{
|
||||
"height": "80",
|
||||
"type": "box",
|
||||
"polygons": [
|
||||
"-400,-400; 400,-400; 400,400; -400,400"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
BIN
resources/data/printer_gantries/prusa3d_ht90_actuator.stl
Normal file
BIN
resources/data/printer_gantries/prusa3d_ht90_actuator.stl
Normal file
Binary file not shown.
@ -28,7 +28,6 @@ using namespace Slic3r;
|
||||
namespace Sequential
|
||||
{
|
||||
class ObjectTooLargeException : public std::runtime_error { public: explicit ObjectTooLargeException(const std::string& msg) : std::runtime_error(msg) {}};
|
||||
class InternalErrorException : public std::runtime_error { public: explicit InternalErrorException(const std::string& msg) : std::runtime_error(msg) {} };
|
||||
|
||||
|
||||
|
||||
|
@ -86,6 +86,7 @@ bool PrinterGeometry::convert_Geometry2PlateBounds(Slic3r::BoundingBox &plate_bo
|
||||
plate_bounding_polygon.points.insert(plate_bounding_polygon.points.begin() + i, Point(plate.points[i].x() / SEQ_SLICER_SCALE_FACTOR,
|
||||
plate.points[i].y() / SEQ_SLICER_SCALE_FACTOR));
|
||||
}
|
||||
plate_bounding_polygon.make_counter_clockwise();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -742,7 +742,7 @@ void prepare_ExtruderPolygons(const SolverConfiguration &solver
|
||||
}
|
||||
else
|
||||
{
|
||||
throw InternalErrorException("MISMATCH BETWEEN OBJECT AND PRINTER SLICE HEIGHTS.");
|
||||
throw std::runtime_error("MISMATCH BETWEEN OBJECT AND PRINTER SLICE HEIGHTS.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,6 +148,19 @@ void assume_BedBoundingPolygon(z3::context &Context,
|
||||
{
|
||||
BoundingBox box = get_extents(polygon);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
printf("Polygon box: [%d,%d] [%d,%d]\n", box.min.x(), box.min.y(), box.max.x(), box.max.y());
|
||||
|
||||
printf("Bed bounding polygon: %ld\n", bed_bounding_polygon.points.size());
|
||||
for (unsigned int i = 0; i < bed_bounding_polygon.points.size(); ++i)
|
||||
{
|
||||
printf("[%d,%d] ", bed_bounding_polygon.points[i].x(), bed_bounding_polygon.points[i].y());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
assume_PointInsidePolygon(Context,
|
||||
dec_var_X + box.min.x(),
|
||||
dec_var_Y + box.min.y(),
|
||||
@ -470,7 +483,8 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
||||
#endif
|
||||
for (unsigned int j = 1; j < undecided.size(); ++j)
|
||||
{
|
||||
Solver.add(dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
//Solver.add(dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
Solver.add(dec_vars_T[undecided[j]] < 0 || dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
}
|
||||
}
|
||||
else if (is_fixed(0, fixed))
|
||||
@ -481,8 +495,9 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
||||
}
|
||||
#endif
|
||||
for (unsigned int j = 0; j < undecided.size(); ++j)
|
||||
{
|
||||
Solver.add(Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
{
|
||||
//Solver.add(Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
Solver.add(dec_vars_T[undecided[j]] < 0 || Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -506,7 +521,8 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
||||
printf("Undecided --> Undecided: %d --> %d standard\n", undecided[i], next_i);
|
||||
}
|
||||
#endif
|
||||
Solver.add(dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]);
|
||||
//Solver.add(dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]);
|
||||
Solver.add((dec_vars_T[undecided[i]] < 0 || dec_vars_T[next_i] < 0) || dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]);
|
||||
}
|
||||
/* Undecided --> missing */
|
||||
else
|
||||
@ -520,12 +536,14 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
||||
{
|
||||
if (i != j)
|
||||
{
|
||||
Solver.add(dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]);
|
||||
//Solver.add(dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]);
|
||||
Solver.add(dec_vars_T[undecided[j]] < 0 || dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]);
|
||||
}
|
||||
}
|
||||
for (unsigned int j = 0; j < fixed.size(); ++j)
|
||||
{
|
||||
Solver.add(Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]);
|
||||
//Solver.add(Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]);
|
||||
Solver.add(dec_vars_T[undecided[i]] < 0 || Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,8 +562,12 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
||||
printf("Fixed --> Undecided: %d --> %d standard\n", fixed[i], next_i);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
Solver.add( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread < dec_vars_T[next_i]
|
||||
&& Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]);
|
||||
*/
|
||||
Solver.add(dec_vars_T[next_i] < 0 || ( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread < dec_vars_T[next_i]
|
||||
&& Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]));
|
||||
}
|
||||
/* Fixed --> Fixed */
|
||||
else if (is_fixed(next_i, fixed))
|
||||
@ -557,8 +579,12 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver
|
||||
#endif
|
||||
for (unsigned int j = 0; j < undecided.size(); ++j)
|
||||
{
|
||||
/*
|
||||
Solver.add( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) > dec_vars_T[undecided[j]] + temporal_spread
|
||||
|| Context.real_val(dec_values_T[next_i].numerator, dec_values_T[next_i].denominator) + temporal_spread < dec_vars_T[undecided[j]]);
|
||||
*/
|
||||
Solver.add(dec_vars_T[undecided[j]] < 0 || ( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) > dec_vars_T[undecided[j]] + temporal_spread
|
||||
|| Context.real_val(dec_values_T[next_i].numerator, dec_values_T[next_i].denominator) + temporal_spread < dec_vars_T[undecided[j]]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1431,7 +1457,7 @@ void assume_PointInsidePolygon(z3::context &Context,
|
||||
z3::expr inside_half_plane( (normal.x() * dec_var_X)
|
||||
+ (normal.y() * dec_var_Y)
|
||||
- (normal.x() * line.a.x())
|
||||
- (normal.y() * line.a.y()) < 0);
|
||||
- (normal.y() * line.a.y()) < 0);
|
||||
|
||||
if (point == polygon.points.begin())
|
||||
{
|
||||
@ -1442,7 +1468,6 @@ void assume_PointInsidePolygon(z3::context &Context,
|
||||
in_conjunction = in_conjunction && inside_half_plane;
|
||||
}
|
||||
}
|
||||
|
||||
constraints.push_back(in_conjunction);
|
||||
}
|
||||
}
|
||||
@ -9488,8 +9513,6 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
||||
|
||||
bool size_solvable = false;
|
||||
|
||||
z3::expr_vector bounding_box_assumptions(Context);
|
||||
|
||||
coord_t box_min_x = (_outer_half_box.min.x() + _inner_half_box.min.x()) / 2;
|
||||
coord_t box_max_x = (_outer_half_box.max.x() + _inner_half_box.max.x()) / 2;
|
||||
|
||||
@ -9770,6 +9793,8 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
||||
std::vector<Rational> local_dec_values_Y = dec_values_Y;
|
||||
std::vector<Rational> local_dec_values_T = dec_values_T;
|
||||
|
||||
assert(inner_half_polygon.points.size() == solver_configuration.plate_bounding_polygon.points.size());
|
||||
|
||||
Polygon _inner_half_polygon = inner_half_polygon;
|
||||
Polygon _outer_half_polygon = solver_configuration.plate_bounding_polygon;
|
||||
|
||||
@ -9839,7 +9864,6 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
||||
|
||||
bool size_solvable = false;
|
||||
|
||||
z3::expr_vector bounding_box_assumptions(Context);
|
||||
Polygon bounding_polygon;
|
||||
|
||||
for (unsigned int i = 0; i < _outer_half_polygon.points.size(); ++i)
|
||||
@ -9883,7 +9907,7 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver
|
||||
undecided,
|
||||
polygons,
|
||||
unreachable_polygons))
|
||||
{
|
||||
{
|
||||
switch (Solver.check(complete_assumptions))
|
||||
{
|
||||
case z3::sat:
|
||||
@ -11102,7 +11126,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
BoundingBox inner_half_box({box_center_x, box_center_y}, {box_center_x, box_center_y});
|
||||
|
||||
for (unsigned int curr_polygon = 0; curr_polygon < polygons.size(); /* nothing */)
|
||||
{
|
||||
{
|
||||
bool optimized = false;
|
||||
z3::set_param("timeout", solver_configuration.optimization_timeout.c_str());
|
||||
|
||||
@ -11311,7 +11335,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
if (!optimized)
|
||||
{
|
||||
if (curr_polygon <= 0)
|
||||
{
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@ -11328,7 +11352,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
return true;
|
||||
}
|
||||
}
|
||||
assert(remaining_polygons.empty());
|
||||
}
|
||||
assert(remaining_polygons.empty());
|
||||
|
||||
@ -11398,7 +11421,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
}
|
||||
|
||||
for (unsigned int curr_polygon = 0; curr_polygon < solvable_objects.size(); /* nothing */)
|
||||
{
|
||||
{
|
||||
bool optimized = false;
|
||||
z3::set_param("timeout", solver_configuration.optimization_timeout.c_str());
|
||||
|
||||
@ -11477,12 +11500,11 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
polygons,
|
||||
lepox_to_next,
|
||||
trans_bed_lepox);
|
||||
|
||||
std::vector<int> missing;
|
||||
std::vector<int> remaining_local;
|
||||
|
||||
while(object_group_size > 0)
|
||||
{
|
||||
{
|
||||
z3::expr_vector presence_assumptions(z_context);
|
||||
assume_ConsequentialObjectPresence(z_context, local_dec_vars_T, undecided, missing, presence_assumptions);
|
||||
|
||||
@ -11493,6 +11515,11 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
{
|
||||
printf(" %d\n", undecided[j]);
|
||||
}
|
||||
printf("Missing\n");
|
||||
for (unsigned int j = 0; j < missing.size(); ++j)
|
||||
{
|
||||
printf(" %d\n", missing[j]);
|
||||
}
|
||||
printf("Decided\n");
|
||||
for (unsigned int j = 0; j < decided_polygons.size(); ++j)
|
||||
{
|
||||
@ -11579,7 +11606,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
}
|
||||
|
||||
if (optimized)
|
||||
{
|
||||
{
|
||||
for (unsigned int i = 0; i < undecided.size(); ++i)
|
||||
{
|
||||
dec_values_X[undecided[i]] = local_values_X[undecided[i]];
|
||||
@ -11650,7 +11677,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So
|
||||
return true;
|
||||
}
|
||||
}
|
||||
assert(remaining_polygons.empty());
|
||||
}
|
||||
assert(remaining_polygons.empty());
|
||||
|
||||
|
@ -71,7 +71,7 @@ static Sequential::PrinterGeometry get_printer_geometry(const ConfigBase& config
|
||||
{
|
||||
if (! printer_notes.empty()) {
|
||||
try {
|
||||
boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.txt");
|
||||
boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.json");
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_json(in, pt);
|
||||
for (const auto& printer : pt.get_child("printers")) {
|
||||
|
@ -217,12 +217,13 @@ int GCodeViewer::SequentialView::ActualSpeedImguiWidget::plot(const char* label,
|
||||
}
|
||||
#endif // ENABLE_ACTUAL_SPEED_DEBUG
|
||||
|
||||
void GCodeViewer::SequentialView::Marker::init(std::optional<std::unique_ptr<GLModel>>& model_opt)
|
||||
void GCodeViewer::SequentialView::Marker::init(std::optional<std::unique_ptr<GLModel>>& model_opt, bool is_ht90)
|
||||
{
|
||||
if (! model_opt.has_value())
|
||||
return;
|
||||
|
||||
m_model.reset();
|
||||
m_is_ht90 = is_ht90;
|
||||
|
||||
m_generic_marker = (model_opt->get() == nullptr);
|
||||
if (m_generic_marker)
|
||||
@ -233,6 +234,85 @@ void GCodeViewer::SequentialView::Marker::init(std::optional<std::unique_ptr<GLM
|
||||
m_model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f });
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// This does not do any scaling!
|
||||
static Transform3d align_cylinder(const Vec3d& p1, const Vec3d& p2, double r) {
|
||||
Vec3d direction = p2 - p1;
|
||||
Vec3d axis = direction.normalized();
|
||||
Vec3d z0(0, 0, 1);
|
||||
Matrix3d rotation;
|
||||
if (axis.isApprox(z0))
|
||||
rotation = Eigen::Matrix3d::Identity(); // Already aligned, use identity rotation
|
||||
else if (axis.isApprox(-z0)) {
|
||||
// 180-degree rotation around x or y (choose any perpendicular axis)
|
||||
rotation = Eigen::AngleAxisd(M_PI, Vec3d(1, 0, 0)).toRotationMatrix();
|
||||
} else {
|
||||
Vec3d rotationAxis = z0.cross(axis);
|
||||
double angle = acos(z0.dot(axis));
|
||||
rotation = Eigen::AngleAxisd(angle, rotationAxis.normalized()).toRotationMatrix();
|
||||
}
|
||||
Transform3d transform = Transform3d::Identity();
|
||||
transform.linear() = rotation;// * Geometry::scale_transform(Vec3d(2*r,2*r,length)).matrix().block<3,3>(0,0);
|
||||
transform.translation() = p1;
|
||||
return transform;
|
||||
}
|
||||
|
||||
static void render_ht90_rods(const Vec3d& pos, GLShaderProgram* shader, const Transform3d& view_matrix, const Vec3d& bed_offset, GLModel& model)
|
||||
{
|
||||
Vec3d start(30.06, 27.70, 35); // Position of the back-right ball bearing, on the extruder head.
|
||||
Vec3d end(32.33, 212.92, 338.8); // The other ball bearing, on the printer.
|
||||
double r=4.725; // Diameter of the rod.
|
||||
double rods_spacing = 60.;
|
||||
double height = (end-start).norm();
|
||||
|
||||
|
||||
if (!model.is_initialized()) {
|
||||
auto t0 = its_make_sphere(r, 0.5);
|
||||
auto t1 = its_make_sphere(r, 0.5);
|
||||
auto t2 = its_make_cylinder(r, height);
|
||||
its_translate(t1, Vec3f(0., 0., height));
|
||||
its_merge(t2, t0);
|
||||
its_merge(t2, t1);
|
||||
model.init_from(t2);
|
||||
model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f });
|
||||
}
|
||||
|
||||
|
||||
// trans transforms extruder to world coord system of the first bed
|
||||
Transform3d trans = Geometry::translation_transform(pos);
|
||||
|
||||
Vec3d p1 = trans * start;
|
||||
Vec3d p2 = end; // already in world coords
|
||||
|
||||
for (int j=0; j<6; ++j) {
|
||||
if (j == 3) {
|
||||
p1.x() = p1.x() - rods_spacing;
|
||||
p2.x() = p2.x() - rods_spacing;
|
||||
}
|
||||
|
||||
p1 = trans * Geometry::rotation_transform(Vec3d(0,0,2*M_PI/3)) * trans.inverse() * p1;
|
||||
p2 = Geometry::rotation_transform(Vec3d(0,0,2*M_PI/3)) * p2;
|
||||
|
||||
double dx = p2.x() - p1.x();
|
||||
double dy = p2.y() - p1.y();
|
||||
double dz = std::sqrt(height * height - dx * dx - dy * dy);
|
||||
p2.z() = p1.z() + dz;
|
||||
|
||||
Transform3d wm = align_cylinder(p1, p2, r);
|
||||
shader->set_uniform("view_model_matrix", view_matrix * wm);
|
||||
shader->set_uniform("volume_world_matrix", Geometry::translation_transform(bed_offset) * wm);
|
||||
model.render();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GCodeViewer::SequentialView::Marker::render()
|
||||
{
|
||||
if (!m_visible)
|
||||
@ -263,7 +343,7 @@ void GCodeViewer::SequentialView::Marker::render()
|
||||
BoundingBoxf box = s_multiple_beds.get_build_volume_box();
|
||||
box.translate(to_2d(bed_inst_offset));
|
||||
// add a bit on both sides
|
||||
box = box.inflated(40.0f);
|
||||
box = box.inflated(m_is_ht90 ? 60.f : 40.f);
|
||||
clip_planes = {{ { 1.0f, 0.0f, 0.0f, -box.min.cast<float>().x() } , { -1.0f, 0.0f, 0.0f, box.max.cast<float>().x() }}};
|
||||
}
|
||||
|
||||
@ -287,8 +367,12 @@ void GCodeViewer::SequentialView::Marker::render()
|
||||
shader->set_uniform("clipping_planes[0]", clip_planes[0]);
|
||||
shader->set_uniform("clipping_planes[1]", clip_planes[1]);
|
||||
|
||||
shader->set_uniform("volume_world_matrix", volume_world_matrix);
|
||||
m_model.render();
|
||||
|
||||
if (m_is_ht90 && ! m_generic_marker)
|
||||
render_ht90_rods(m_world_position.cast<double>(), shader, view_matrix, bed_inst_offset, m_model_ht90_rod);
|
||||
|
||||
shader->stop_using();
|
||||
|
||||
if (curr_cull_face)
|
||||
@ -1204,8 +1288,8 @@ void GCodeViewer::render()
|
||||
m_sequential_view.marker.set_z_offset(m_z_offset);
|
||||
|
||||
// Following just makes sure that the shown marker is correct.
|
||||
auto marker_model_opt = wxGetApp().plater()->get_current_canvas3D()->get_current_marker_model();
|
||||
m_sequential_view.marker.init(marker_model_opt);
|
||||
auto [marker_model_opt, is_ht90] = wxGetApp().plater()->get_current_canvas3D()->get_current_marker_model();
|
||||
m_sequential_view.marker.init(marker_model_opt, is_ht90);
|
||||
if (marker_model_opt.has_value())
|
||||
m_max_bounding_box.reset();
|
||||
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
class Marker
|
||||
{
|
||||
GLModel m_model;
|
||||
GLModel m_model_ht90_rod;
|
||||
Vec3f m_world_position;
|
||||
// For seams, the position of the marker is on the last endpoint of the toolpath containing it.
|
||||
// This offset is used to show the correct value of tool position in the "ToolPosition" window.
|
||||
@ -128,14 +129,20 @@ public:
|
||||
bool m_fixed_screen_size{ false };
|
||||
float m_scale_factor{ 1.0f };
|
||||
bool m_generic_marker{ true };
|
||||
bool m_is_ht90{false};
|
||||
#if ENABLE_ACTUAL_SPEED_DEBUG
|
||||
ActualSpeedImguiWidget m_actual_speed_imgui_widget;
|
||||
#endif // ENABLE_ACTUAL_SPEED_DEBUG
|
||||
|
||||
public:
|
||||
void init(std::optional<std::unique_ptr<GLModel>>& model_opt);
|
||||
void init(std::optional<std::unique_ptr<GLModel>>& model_opt, bool is_ht90);
|
||||
|
||||
const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); }
|
||||
BoundingBoxf3 get_bounding_box() const {
|
||||
auto bb = m_model.get_bounding_box();
|
||||
if (m_is_ht90)
|
||||
bb.max.z() += scale_(400);
|
||||
return bb;
|
||||
}
|
||||
|
||||
void set_world_position(const Vec3f& position) { m_world_position = position; }
|
||||
void set_world_offset(const Vec3f& offset) { m_world_offset = offset; }
|
||||
|
@ -162,9 +162,10 @@ void GLCanvas3D::select_bed(int i, bool triggered_by_user)
|
||||
// - nullopt = same as before
|
||||
// - nullptr = none available, use generic
|
||||
// - GLModel = the model to use
|
||||
std::optional<std::unique_ptr<GLModel>> GLCanvas3D::get_current_marker_model() const
|
||||
// The other field is whether the printer is HT90.
|
||||
std::pair<std::optional<std::unique_ptr<GLModel>>, bool> GLCanvas3D::get_current_marker_model() const
|
||||
{
|
||||
std::optional<std::unique_ptr<GLModel>> out;
|
||||
auto out = std::make_pair<std::optional<std::unique_ptr<GLModel>>, bool>(std::nullopt, false);
|
||||
|
||||
static std::string last_printer_notes;
|
||||
static double old_r = 0.;
|
||||
@ -182,11 +183,13 @@ std::optional<std::unique_ptr<GLModel>> GLCanvas3D::get_current_marker_model() c
|
||||
old_h = h;
|
||||
old_seq = seq;
|
||||
|
||||
out = std::make_optional(nullptr);
|
||||
out.second = (printer_notes.find("PRINTER_MODEL_HT90") != std::string::npos);
|
||||
|
||||
out.first = std::make_optional(nullptr);
|
||||
if (! seq)
|
||||
return out;
|
||||
try {
|
||||
boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.txt");
|
||||
boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.json");
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::read_json(in, pt);
|
||||
for (const auto& printer : pt.get_child("printers")) {
|
||||
@ -197,7 +200,7 @@ std::optional<std::unique_ptr<GLModel>> GLCanvas3D::get_current_marker_model() c
|
||||
if (boost::filesystem::exists(filename)) {
|
||||
std::unique_ptr<GLModel> m = std::make_unique<GLModel>();
|
||||
if (m->init_from_file(filename))
|
||||
out = std::make_optional(std::move(m));
|
||||
out.first = std::make_optional(std::move(m));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -205,7 +208,7 @@ std::optional<std::unique_ptr<GLModel>> GLCanvas3D::get_current_marker_model() c
|
||||
} catch (...) {
|
||||
// Whatever happened, ignore it. We will return nullptr.
|
||||
}
|
||||
if (*out == nullptr && seq) {
|
||||
if (*(out.first) == nullptr && seq) {
|
||||
// Generic sequential extruder model.
|
||||
double gantry_height = 10;
|
||||
auto mesh = its_make_cylinder(r, h + gantry_height - 0.001);
|
||||
@ -215,7 +218,7 @@ std::optional<std::unique_ptr<GLModel>> GLCanvas3D::get_current_marker_model() c
|
||||
its_merge(mesh, mesh2);
|
||||
std::unique_ptr<GLModel> m = std::make_unique<GLModel>();
|
||||
m->init_from(mesh);
|
||||
out = std::make_optional(std::move(m));
|
||||
out.first = std::make_optional(std::move(m));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
@ -729,7 +729,7 @@ public:
|
||||
const libvgcode::Interval& get_gcode_view_visible_range() const { return m_gcode_viewer.get_gcode_view_visible_range(); }
|
||||
const libvgcode::PathVertex& get_gcode_vertex_at(size_t id) const { return m_gcode_viewer.get_gcode_vertex_at(id); }
|
||||
|
||||
std::optional<std::unique_ptr<GLModel>> get_current_marker_model() const;
|
||||
std::pair<std::optional<std::unique_ptr<GLModel>>, bool> get_current_marker_model() const;
|
||||
|
||||
void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
|
||||
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1, const ModelVolume* mv = nullptr);
|
||||
|
@ -33,8 +33,11 @@ void SeqArrangeJob::process(Ctl& ctl)
|
||||
}
|
||||
);
|
||||
} catch (const SeqArrangeJobException&) {
|
||||
// The task was canceled. Just make sure that the progress notification disappears.
|
||||
ctl.update_status(100, "");
|
||||
ctl.update_status(100, ""); // Hide progress notification.
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
ctl.update_status(100, ""); // Hide progress notification.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +63,7 @@ void SeqArrangeJob::finalize(bool canceled, std::exception_ptr& eptr)
|
||||
dlg.ShowModal();
|
||||
error = true;
|
||||
eptr = nullptr; // The exception is handled.
|
||||
} catch (const Sequential::InternalErrorException& ex) {
|
||||
} catch (const std::runtime_error& ex) {
|
||||
ErrorDialog dlg(wxGetApp().plater(), GUI::format_wxstr(_L("Internal error: %1%"), ex.what()), false);
|
||||
dlg.ShowModal();
|
||||
error = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user