ENH: dual_extruder: add logic to process extruder_printable_area

JIRA: STUDIO-7498
Change-Id: I1cf53db93acf41b06cb1b9569a0679487c9f1e41
(cherry picked from commit e5be69dedd1ba6dc289a14b89598c9a6101dacb3)
This commit is contained in:
lane.wei authored and Noisyfox committed 2025-08-24 23:18:12 +08:00
1 parent e433e49e2f
commit f702ad9fd2
20 files changed
+339 -76

No files matched your search

+15 -5
View File
@@ -251,7 +251,7 @@ void Bed3D::Axes::render()
}
//BBS: add part plate logic
bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_height, const std::string& custom_model, bool force_as_custom,
bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_height, std::vector<Pointfs> extruder_areas, const std::string& custom_model, bool force_as_custom,
const Vec2d& position, bool with_reset)
{
/*auto check_texture = [](const std::string& texture) {
@@ -289,7 +289,7 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
}
//BBS: add position related logic
if (m_bed_shape == printable_area && m_build_volume.printable_height() == printable_height && m_type == type && m_model_filename == model_filename && position == m_position)
if (m_bed_shape == printable_area && m_build_volume.printable_height() == printable_height && m_type == type && m_model_filename == model_filename && position == m_position && m_extruder_shapes == extruder_areas)
// No change, no need to update the UI.
return false;
@@ -297,16 +297,26 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":current position {%1%,%2%}, new position {%3%, %4%}") % m_position.x() % m_position.y() % position.x() % position.y();
m_position = position;
m_bed_shape = printable_area;
m_extruder_shapes = extruder_areas;
if ((position(0) != 0) || (position(1) != 0)) {
Pointfs new_bed_shape;
for (const Vec2d& p : m_bed_shape) {
Vec2d point(p(0) + m_position.x(), p(1) + m_position.y());
new_bed_shape.push_back(point);
}
m_build_volume = BuildVolume { new_bed_shape, printable_height };
std::vector<Pointfs> new_extruder_shapes;
for (const std::vector<Vec2d>& shape : m_extruder_shapes) {
std::vector<Vec2d> new_extruder_shape;
for (const Vec2d& p : shape) {
Vec2d point(p(0) + m_position.x(), p(1) + m_position.y());
new_extruder_shape.push_back(point);
}
new_extruder_shapes.push_back(new_extruder_shape);
}
m_build_volume = BuildVolume { new_bed_shape, printable_height, new_extruder_shapes };
}
else
m_build_volume = BuildVolume { printable_area, printable_height };
m_build_volume = BuildVolume { printable_area, printable_height, m_extruder_shapes };
m_type = type;
//m_texture_filename = texture_filename;
m_model_filename = model_filename;
@@ -342,7 +352,7 @@ bool Bed3D::set_shape(const Pointfs& printable_area, const double printable_heig
//BBS: add api to set position for partplate related bed
void Bed3D::set_position(Vec2d& position)
{
set_shape(m_bed_shape, m_build_volume.printable_height(), m_model_filename, false, position, false);
set_shape(m_bed_shape, m_build_volume.printable_height(), m_extruder_shapes, m_model_filename, false, position, false);
}
void Bed3D::set_axes_mode(bool origin)
+2 -1
View File
@@ -115,6 +115,7 @@ private:
//BBS: add part plate related logic
Vec2d m_position{ Vec2d::Zero() };
std::vector<Vec2d> m_bed_shape;
std::vector<std::vector<Vec2d>> m_extruder_shapes;
bool m_is_dark = false;
public:
@@ -126,7 +127,7 @@ public:
//FIXME if the build volume max print height is updated, this function still returns zero
// as this class does not use it, thus there is no need to update the UI.
// BBS
bool set_shape(const Pointfs& printable_area, const double printable_height, const std::string& custom_model, bool force_as_custom = false,
bool set_shape(const Pointfs& printable_area, const double printable_height, std::vector<Pointfs> extruder_areas, const std::string& custom_model, bool force_as_custom = false,
const Vec2d& position = Vec2d::Zero(), bool with_reset = true);
void set_position(Vec2d& position);
+30 -16
View File
@@ -1067,15 +1067,15 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
auto volume_convex_mesh = [volume_sinking, &model](GLVolume& volume) -> const TriangleMesh&
{ return volume_sinking(volume) ? model.objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : *volume.convex_hull(); };
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Inside;
ModelInstanceEPrintVolumeState overall_state = ModelInstancePVS_Fully_Outside;
bool contained_min_one = false;
//BBS: add instance judge logic, besides to original volume judge logic
std::map<int64_t, ModelInstanceEPrintVolumeState> model_state;
//std::map<int64_t, ModelInstanceEPrintVolumeState> model_state;
GUI::PartPlate* curr_plate = GUI::wxGetApp().plater()->get_partplate_list().get_selected_plate();
const Pointfs& pp_bed_shape = curr_plate->get_shape();
BuildVolume plate_build_volume(pp_bed_shape, build_volume.printable_height());
BuildVolume plate_build_volume(pp_bed_shape, build_volume.printable_height(), build_volume.extruder_areas());
const std::vector<BoundingBoxf3>& exclude_areas = curr_plate->get_exclude_areas();
for (GLVolume* volume : this->volumes)
@@ -1090,14 +1090,27 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
//FIXME this test does not evaluate collision of a build volume bounding box with non-convex objects.
const BoundingBoxf3& bb = volume_bbox(*volume);
state = plate_build_volume.volume_state_bbox(bb);
if ((state == BuildVolume::ObjectState::Inside) && (build_volume.get_extruder_area_count() > 0))
{
std::vector<bool> inside_extruders;
state = plate_build_volume.check_volume_bbox_state_with_extruder_areas(bb, inside_extruders);
}
break;
case BuildVolume_Type::Circle:
case BuildVolume_Type::Convex:
//FIXME doing test on convex hull until we learn to do test on non-convex polygons efficiently.
case BuildVolume_Type::Custom:
state = plate_build_volume.object_state(volume_convex_mesh(*volume).its, volume->world_matrix().cast<float>(), volume_sinking(*volume));
{
const indexed_triangle_set& convex_mesh_it = volume_convex_mesh(*volume).its;
const Transform3f trafo = volume->world_matrix().cast<float>();
state = plate_build_volume.object_state(convex_mesh_it, trafo, volume_sinking(*volume));
if ((state == BuildVolume::ObjectState::Inside) && (build_volume.get_extruder_area_count() > 0))
{
std::vector<bool> inside_extruders;
state = plate_build_volume.check_object_state_with_extruder_areas(convex_mesh_it, trafo, inside_extruders);
}
break;
}
default:
// Ignore, don't produce any collision.
state = BuildVolume::ObjectState::Inside;
@@ -1106,22 +1119,23 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
assert(state != BuildVolume::ObjectState::Below);
}
int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id);
volume->is_outside = state != BuildVolume::ObjectState::Inside;
//volume->partly_inside = (state == BuildVolume::ObjectState::Colliding);
//int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id);
volume->is_outside = (state != BuildVolume::ObjectState::Inside && state != BuildVolume::ObjectState::Limited);
volume->partly_inside = (state == BuildVolume::ObjectState::Colliding);
if (volume->printable) {
if (overall_state == ModelInstancePVS_Inside && volume->is_outside) {
overall_state = ModelInstancePVS_Fully_Outside;
}
if (overall_state == ModelInstancePVS_Fully_Outside && volume->is_outside && (state == BuildVolume::ObjectState::Colliding))
if (state == BuildVolume::ObjectState::Colliding)
{
overall_state = ModelInstancePVS_Partly_Outside;
}
else if ((state == BuildVolume::ObjectState::Limited) && (overall_state != ModelInstancePVS_Partly_Outside))
overall_state = ModelInstancePVS_Limited;
else if ((state == BuildVolume::ObjectState::Inside) && (overall_state == ModelInstancePVS_Fully_Outside)) {
overall_state = ModelInstancePVS_Fully_Outside;
}
contained_min_one |= !volume->is_outside;
}
ModelInstanceEPrintVolumeState volume_state;
/*ModelInstanceEPrintVolumeState volume_state;
//if (volume->is_outside && (plate_build_volume.bounding_volume().intersects(volume->bounding_box())))
if (volume->is_outside && (state == BuildVolume::ObjectState::Colliding))
volume_state = ModelInstancePVS_Partly_Outside;
@@ -1150,11 +1164,11 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
if (model_state[comp_id] == ModelInstancePVS_Partly_Outside) {
overall_state = ModelInstancePVS_Partly_Outside;
BOOST_LOG_TRIVIAL(debug) << "instance includes " << volume->name << " is partially outside of bed";
}
}*/
}
}
for (GLVolume* volume : this->volumes)
/*for (GLVolume* volume : this->volumes)
{
if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0)))
{
@@ -1168,7 +1182,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo
volume->partly_inside = false;
}
}
}
}*/
if (out_state != nullptr)
*out_state = overall_state;
+4 -4
View File
@@ -2,7 +2,7 @@
#include "GUI_App.hpp"
#include "OptionsGroup.hpp"
#include <wx/wx.h>
#include <wx/wx.h>
#include <wx/numformatter.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
@@ -25,7 +25,7 @@ namespace GUI {
BedShape::BedShape(const Pointfs& points)
{
m_build_volume = { points, 0. };
m_build_volume = { points, 0.f, {} };
}
static std::string get_option_label(BedShape::Parameter param)
@@ -283,7 +283,7 @@ ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(const wxString& tit
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) {
update_shape();
};
m_optgroups.push_back(optgroup);
// panel->SetSizerAndFit(optgroup->sizer);
m_shape_options_book->AddPage(panel, title);
@@ -522,7 +522,7 @@ void BedShapePanel::update_shape()
{
double diameter;
try { diameter = boost::any_cast<double>(opt_group->get_value("diameter")); }
catch (const std::exception & /* e */) { return; }
catch (const std::exception & /* e */) { return; }
if (diameter == 0.0) return ;
auto r = diameter / 2;
+5 -1
View File
@@ -1008,6 +1008,7 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
Pointfs printable_area;
//BBS: add bed exclude area
Pointfs bed_exclude_area = Pointfs();
std::vector<Pointfs> extruder_areas;
std::string texture;
std::string model;
@@ -1027,7 +1028,10 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
if (!gcode_result.bed_exclude_area.empty())
bed_exclude_area = gcode_result.bed_exclude_area;
wxGetApp().plater()->set_bed_shape(printable_area, bed_exclude_area, gcode_result.printable_height, texture, model, gcode_result.printable_area.empty());
if (!gcode_result.extruder_areas.empty())
extruder_areas = gcode_result.extruder_areas;
wxGetApp().plater()->set_bed_shape(printable_area, bed_exclude_area, gcode_result.printable_height, extruder_areas, texture, model, gcode_result.printable_area.empty());
}
/*else {
// adjust printbed size in dependence of toolpaths bbox
+12 -2
View File
@@ -2810,8 +2810,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
const bool contained_min_one = m_volumes.check_outside_state(m_bed.build_volume(), &state);
const bool partlyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Partly_Outside);
const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
const bool objectLimited = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Limited);
_set_warning_notification(EWarning::ObjectClashed, partlyOut);
_set_warning_notification(EWarning::ObjectLimited, objectLimited);
//BBS: turn off the warning when fully outside
//_set_warning_notification(EWarning::ObjectOutside, fullyOut);
if (printer_technology != ptSLA || !contained_min_one)
@@ -2823,6 +2825,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
else {
_set_warning_notification(EWarning::ObjectOutside, false);
_set_warning_notification(EWarning::ObjectClashed, false);
_set_warning_notification(EWarning::ObjectLimited, false);
_set_warning_notification(EWarning::SlaSupportsOutside, false);
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, false));
}
@@ -9650,6 +9653,11 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning)
_set_warning_notification(warning, show);
}
std::string object_limited_text = _u8L("An object is laid on the left/right extruder only area.\n"
"Please make sure the filaments used by this object on this area are not mapped to the other extruders.");
std::string object_clashed_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
{
enum ErrorType{
@@ -9686,10 +9694,12 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
case EWarning::SlaSupportsOutside: text = ("SLA supports outside the print area were detected."); error = ErrorType::PLATER_ERROR; break;
case EWarning::SomethingNotShown: text = _u8L("Only the object being edited is visible."); break;
case EWarning::ObjectClashed:
text = _u8L("An object is laid over the plate boundaries or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");
text = object_clashed_text;
error = ErrorType::PLATER_ERROR;
break;
case EWarning::ObjectLimited:
text = object_limited_text;
break;
}
//BBS: this may happened when exit the app, plater is null
if (!wxGetApp().plater())
+1
View File
@@ -380,6 +380,7 @@ class GLCanvas3D
SlaSupportsOutside,
SomethingNotShown,
ObjectClashed,
ObjectLimited,
GCodeConflict,
ToolHeightOutside
};
+1 -1
View File
@@ -846,7 +846,7 @@ void MainFrame::update_layout()
{
m_main_sizer->Add(m_plater, 1, wxEXPAND);
//BBS: add bed exclude area
m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, {}, 0.0, {}, {}, true);
m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, {}, 0.0, {}, {}, {}, true);
m_plater->get_collapse_toolbar().set_enabled(false);
m_plater->enable_sidebar(false);
m_plater->Show();
+24 -11
View File
@@ -2645,7 +2645,7 @@ void PartPlate::generate_exclude_polygon(ExPolygon &exclude_polygon)
exclude_polygon.contour.make_counter_clockwise();
}
bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod)
bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, const std::vector<Pointfs>& extruder_areas, Vec2d position, float height_to_lid, float height_to_rod)
{
Pointfs new_shape, new_exclude_areas;
for (const Vec2d& p : shape) {
@@ -2655,6 +2655,18 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve
for (const Vec2d& p : exclude_areas) {
new_exclude_areas.push_back(Vec2d(p.x() + position.x(), p.y() + position.y()));
}
std::vector<Pointfs> new_extruder_areas;
for (const Pointfs& shape : extruder_areas) {
Pointfs new_extruder_area;
for (const Vec2d& p : shape) {
Vec2d point(p(0) + position.x(), p(1) + position.y());
new_extruder_area.push_back(point);
}
new_extruder_areas.push_back(new_extruder_area);
}
m_extruder_areas = std::move(new_extruder_areas);
if ((m_shape == new_shape)&&(m_exclude_area == new_exclude_areas)
&&(m_height_to_lid == height_to_lid)&&(m_height_to_rod == height_to_rod)) {
BOOST_LOG_TRIVIAL(info) << "PartPlate same shape, skip directly";
@@ -3629,7 +3641,7 @@ void PartPlateList::reset_size(int width, int depth, int height, bool reload_obj
m_plate_height = height;
update_all_plates_pos_and_size(false, false, true);
if (update_shapes) {
set_shapes(m_shape, m_exclude_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
set_shapes(m_shape, m_exclude_areas, m_extruder_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
}
if (reload_objects)
reload_all_objects();
@@ -3714,7 +3726,7 @@ void PartPlateList::reinit()
//reset plate 0's position
Vec2d pos = compute_shape_position(0, m_plate_cols);
m_plate_list[0]->set_shape(m_shape, m_exclude_areas, pos, m_height_to_lid, m_height_to_rod);
m_plate_list[0]->set_shape(m_shape, m_exclude_areas, m_extruder_areas, pos, m_height_to_lid, m_height_to_rod);
//reset unprintable plate's position
Vec3d origin2 = compute_origin_for_unprintable();
unprintable_plate.set_pos_and_size(origin2, m_plate_width, m_plate_depth, m_plate_height, false);
@@ -3764,7 +3776,7 @@ int PartPlateList::create_plate(bool adjust_position)
plate->set_index(new_index);
Vec2d pos = compute_shape_position(new_index, cols);
plate->set_shape(m_shape, m_exclude_areas, pos, m_height_to_lid, m_height_to_rod);
plate->set_shape(m_shape, m_exclude_areas, m_extruder_areas, pos, m_height_to_lid, m_height_to_rod);
m_plate_list.emplace_back(plate);
update_plate_cols();
if (old_cols != cols)
@@ -3772,7 +3784,7 @@ int PartPlateList::create_plate(bool adjust_position)
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":old_cols %1% -> new_cols %2%") % old_cols % cols;
//update the origin of each plate
update_all_plates_pos_and_size(adjust_position, false);
set_shapes(m_shape, m_exclude_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
set_shapes(m_shape, m_exclude_areas, m_extruder_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
if (m_plater) {
Vec2d pos = compute_shape_position(m_current_plate, cols);
@@ -3943,7 +3955,7 @@ int PartPlateList::delete_plate(int index)
//update render shapes
Vec2d pos = compute_shape_position(i, m_plate_cols);
plate->set_shape(m_shape, m_exclude_areas, pos, m_height_to_lid, m_height_to_rod);
plate->set_shape(m_shape, m_exclude_areas, m_extruder_areas, pos, m_height_to_lid, m_height_to_rod);
}
//update current_plate if delete current
@@ -3966,7 +3978,7 @@ int PartPlateList::delete_plate(int index)
{
//update the origin of each plate
update_all_plates_pos_and_size();
set_shapes(m_shape, m_exclude_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
set_shapes(m_shape, m_exclude_areas, m_extruder_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
}
else
{
@@ -5063,11 +5075,12 @@ void PartPlateList::select_plate_view()
m_plater->get_camera().select_view("topfront");
}
bool PartPlateList::set_shapes(const Pointfs& shape, const Pointfs& exclude_areas, const std::string& texture_filename, float height_to_lid, float height_to_rod)
bool PartPlateList::set_shapes(const Pointfs& shape, const Pointfs& exclude_areas, const std::vector<Pointfs>& extruder_areas, const std::string& texture_filename, float height_to_lid, float height_to_rod)
{
const std::lock_guard<std::mutex> local_lock(m_plates_mutex);
m_shape = shape;
m_exclude_areas = exclude_areas;
m_extruder_areas = extruder_areas;
m_height_to_lid = height_to_lid;
m_height_to_rod = height_to_rod;
@@ -5081,7 +5094,7 @@ bool PartPlateList::set_shapes(const Pointfs& shape, const Pointfs& exclude_area
Vec2d pos;
pos = compute_shape_position(i, m_plate_cols);
plate->set_shape(shape, exclude_areas, pos, height_to_lid, height_to_rod);
plate->set_shape(shape, exclude_areas, extruder_areas, pos, height_to_lid, height_to_rod);
}
is_load_bedtype_textures = false; //reload textures
calc_bounding_boxes();
@@ -5260,7 +5273,7 @@ int PartPlateList::rebuild_plates_after_deserialize(std::vector<bool>& previous_
}
update_plate_cols();
update_all_plates_pos_and_size(false, false, false, false);
set_shapes(m_shape, m_exclude_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
set_shapes(m_shape, m_exclude_areas, m_extruder_areas, m_logo_texture_filename, m_height_to_lid, m_height_to_rod);
for (unsigned int i = 0; i < (unsigned int)m_plate_list.size(); ++i)
{
bool need_reset_print = false;
@@ -5592,7 +5605,7 @@ int PartPlateList::load_gcode_files()
//BoundingBoxf3 print_volume = m_plate_list[i]->get_bounding_box(false);
//print_volume.max(2) = this->m_plate_height;
//print_volume.min(2) = -1e10;
m_model->update_print_volume_state({m_plate_list[i]->get_shape(), (double)this->m_plate_height });
m_model->update_print_volume_state({m_plate_list[i]->get_shape(), (double)this->m_plate_height, m_plate_list[i]->get_extruder_areas() });
if (!m_plate_list[i]->load_gcode_from_file(m_plate_list[i]->m_gcode_path_from_3mf))
ret ++;
+5 -2
View File
@@ -120,6 +120,7 @@ private:
Pointfs m_shape;
Pointfs m_exclude_area;
std::vector<Pointfs> m_extruder_areas;
BoundingBoxf3 m_bounding_box;
BoundingBoxf3 m_extended_bounding_box;
mutable std::vector<BoundingBoxf3> m_exclude_bounding_box;
@@ -363,7 +364,8 @@ public:
/*rendering related functions*/
const Pointfs& get_shape() const { return m_shape; }
bool set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod);
bool set_shape(const Pointfs& shape, const Pointfs& exclude_areas, const std::vector<Pointfs>& extruder_areas, Vec2d position, float height_to_lid, float height_to_rod);
const std::vector<Pointfs>& get_extruder_areas() const { return m_extruder_areas; }
bool contains(const Vec3d& point) const;
bool contains(const GLVolume& v) const;
bool contains(const BoundingBoxf3& bb) const;
@@ -562,6 +564,7 @@ class PartPlateList : public ObjectBase
PartPlate unprintable_plate;
Pointfs m_shape;
Pointfs m_exclude_areas;
std::vector<Pointfs> m_extruder_areas;
BoundingBoxf3 m_bounding_box;
bool m_intialized;
std::string m_logo_texture_filename;
@@ -821,7 +824,7 @@ public:
int select_plate_by_obj(int obj_index, int instance_index);
void calc_bounding_boxes();
void select_plate_view();
bool set_shapes(const Pointfs& shape, const Pointfs& exclude_areas, const std::string& custom_texture, float height_to_lid, float height_to_rod);
bool set_shapes(const Pointfs& shape, const Pointfs& exclude_areas, const std::vector<Pointfs>& extruder_areas, const std::string& custom_texture, float height_to_lid, float height_to_rod);
void set_hover_id(int id);
void reset_hover_id();
bool intersects(const BoundingBoxf3 &bb);
+27 -15
View File
@@ -2880,7 +2880,7 @@ struct Plater::priv
// fills the m_bed.m_grid_lines and sets m_bed.m_origin.
// Sets m_bed.m_polygon to limit the object placement.
//BBS: add bed exclude area
void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, std::vector<Pointfs> extruder_areas, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false);
bool can_delete() const;
bool can_delete_all() const;
@@ -3034,8 +3034,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
, main_frame(main_frame)
//BBS: add bed_exclude_area
, config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({
"printable_area", "bed_exclude_area", "bed_custom_texture", "bed_custom_model", "print_sequence",
"extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
"printable_area", "bed_exclude_area", "extruder_printable_area", "bed_custom_texture", "bed_custom_model", "print_sequence",
"extruder_clearance_radius",
"extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
"brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_volume",
@@ -5450,7 +5451,7 @@ void Plater::priv::update_print_volume_state()
{
//BBS: use the plate's bounding box instead of the bed's
PartPlate* pp = partplate_list.get_curr_plate();
BuildVolume build_volume(pp->get_shape(), this->bed.build_volume().printable_height());
BuildVolume build_volume(pp->get_shape(), this->bed.build_volume().printable_height(), this->bed.build_volume().extruder_areas());
this->model.update_print_volume_state(build_volume);
}
@@ -8464,7 +8465,7 @@ bool Plater::priv::show_publish_dlg(bool show)
}
//BBS: add bed exclude area
void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_areas, const double printable_height, std::vector<Pointfs> extruder_areas, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom)
{
//Orca: reduce resolution for large bed printer
BoundingBoxf bed_size = get_extents(shape);
@@ -8475,7 +8476,7 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar
//BBS: add shape position
Vec2d shape_position = partplate_list.get_current_shape_position();
bool new_shape = bed.set_shape(shape, printable_height, custom_model, force_as_custom, shape_position);
bool new_shape = bed.set_shape(shape, printable_height, extruder_areas, custom_model, force_as_custom, shape_position);
float prev_height_lid, prev_height_rod;
partplate_list.get_height_limits(prev_height_lid, prev_height_rod);
@@ -8499,11 +8500,11 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar
//Pointfs& exclude_areas = config->option<ConfigOptionPoints>("bed_exclude_area")->values;
partplate_list.reset_size(max.x() - min.x() - Bed3D::Axes::DefaultTipRadius, max.y() - min.y() - Bed3D::Axes::DefaultTipRadius, z);
partplate_list.set_shapes(shape, exclude_areas, custom_texture, height_to_lid, height_to_rod);
partplate_list.set_shapes(shape, exclude_areas, extruder_areas, custom_texture, height_to_lid, height_to_rod);
Vec2d new_shape_position = partplate_list.get_current_shape_position();
if (shape_position != new_shape_position)
bed.set_shape(shape, printable_height, custom_model, force_as_custom, new_shape_position);
bed.set_shape(shape, printable_height, extruder_areas, custom_model, force_as_custom, new_shape_position);
}
}
@@ -13602,14 +13603,15 @@ void Plater::set_bed_shape() const
//BBS: add bed exclude areas
p->config->option<ConfigOptionPoints>("bed_exclude_area")->values,
p->config->option<ConfigOptionFloat>("printable_height")->value,
p->config->option<ConfigOptionPointsGroups>("extruder_printable_area")->values,
p->config->option<ConfigOptionString>("bed_custom_texture")->value.empty() ? texture_filename : p->config->option<ConfigOptionString>("bed_custom_texture")->value,
p->config->option<ConfigOptionString>("bed_custom_model")->value);
}
//BBS: add bed exclude area
void Plater::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const
void Plater::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, std::vector<Pointfs> extruder_areas, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const
{
p->set_bed_shape(make_counter_clockwise(shape), exclude_area, printable_height, custom_texture, custom_model, force_as_custom);
p->set_bed_shape(make_counter_clockwise(shape), exclude_area, printable_height, extruder_areas, custom_texture, custom_model, force_as_custom);
}
void Plater::force_filament_colors_update()
@@ -14328,13 +14330,16 @@ int Plater::select_sliced_plate(int plate_index)
return ret;
}
extern std::string object_limited_text;
extern std::string object_clashed_text;
void Plater::validate_current_plate(bool& model_fits, bool& validate_error)
{
model_fits = p->view3D->get_canvas3d()->check_volumes_outside_state() != ModelInstancePVS_Partly_Outside;
ModelInstanceEPrintVolumeState state = p->view3D->get_canvas3d()->check_volumes_outside_state();
model_fits = (state != ModelInstancePVS_Partly_Outside);
validate_error = false;
if (p->printer_technology == ptFFF) {
std::string plater_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
"Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");;
//std::string plater_text = _u8L("An object is laid over the boundary of plate or exceeds the height limit.\n"
// "Please solve the problem by moving it totally on or off the plate, and confirming that the height is within the build volume.");;
StringObjectException warning;
Polygons polygons;
std::vector<std::pair<Polygon, float>> height_polygons;
@@ -14369,10 +14374,17 @@ void Plater::validate_current_plate(bool& model_fits, bool& validate_error)
}
if (!model_fits) {
p->notification_manager->push_plater_error_notification(plater_text);
p->notification_manager->push_plater_error_notification(object_clashed_text);
}
else {
p->notification_manager->close_plater_error_notification(plater_text);
p->notification_manager->close_plater_error_notification(object_clashed_text);
}
if (state == ModelInstancePVS_Limited) {
p->notification_manager->push_plater_warning_notification(object_limited_text);
}
else {
p->notification_manager->close_plater_warning_notification(object_limited_text);
}
}
+1 -1
View File
@@ -664,7 +664,7 @@ public:
void update_flush_volume_matrix(size_t old_nozzle_size, size_t new_nozzle_size);
//BBS: add bed exclude area
void set_bed_shape() const;
void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
void set_bed_shape(const Pointfs& shape, const Pointfs& exclude_area, const double printable_height, std::vector<Pointfs> extruder_areas, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
const NotificationManager* get_notification_manager() const;
NotificationManager* get_notification_manager();