1441{
1442 if (GUI::wxGetApp().plater() == NULL)
1443 {
1444 if (out_state != nullptr)
1446 return false;
1447 }
1448
1449 const Model& model = GUI::wxGetApp().plater()->model();
1450 auto volume_below = [](GLVolume& volume) -> bool
1451 { return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_below_printbed(); };
1452
1453 auto volume_sinking = [](GLVolume& volume) -> bool
1454 { return volume.object_idx() != -1 && volume.volume_idx() != -1 && volume.is_sinking(); };
1455
1456 auto volume_bbox = [volume_sinking](GLVolume& volume) -> BoundingBoxf3
1457 { return volume_sinking(volume) ? volume.transformed_non_sinking_bounding_box() : volume.transformed_convex_hull_bounding_box(); };
1458
1459 auto volume_convex_mesh = [volume_sinking, &model](GLVolume& volume) -> const TriangleMesh&
1460 { return volume_sinking(volume) ? model.objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh() : *volume.convex_hull(); };
1461
1463 bool contained_min_one = false;
1464
1465
1466
1467
1468 GUI::PartPlate* curr_plate = GUI::wxGetApp().plater()->get_partplate_list().get_selected_plate();
1469 const Pointfs& pp_bed_shape = curr_plate->get_shape();
1471 const std::vector<BoundingBoxf3>& exclude_areas = curr_plate->get_exclude_areas();
1472
1473 const DynamicPrintConfig *plater_config = GUI::wxGetApp().plater()->config();
1474 std::vector<std::vector<BedExcludeRegion>> exclusion_regions;
1475
1476
1479
1480
1481 for (std::vector<BedExcludeRegion> ®ions : exclusion_regions)
1482 regions.erase(std::remove_if(regions.begin(), regions.end(),
1483 [](const BedExcludeRegion ®ion) { return !region.is_collision_volume(); }), regions.end());
1484 }
1485 const Vec3d plate_origin = curr_plate->get_origin();
1486 const Point exclusion_offset(
scale_(plate_origin.x()),
scale_(plate_origin.y()));
1487 for (std::vector<BedExcludeRegion> ®ions : exclusion_regions)
1488 for (BedExcludeRegion ®ion : regions)
1489 region.polygon.translate(exclusion_offset);
1490
1491 std::map<ModelObject*, std::map<int, std::set<int>>> objects_unprintable_filaments;
1492 const DynamicPrintConfig &plate_project_config = GUI::wxGetApp().preset_bundle->project_config;
1494 const int extruder_count = std::max<int>(build_volume_extruder_count, int(exclusion_regions.size()));
1495 std::vector<std::set<int>> unprintable_filament_ids(extruder_count, std::set<int>());
1496 std::set<ModelObject*> partly_objects_set;
1497 std::map<std::pair<int, int>, std::vector<bool>> instance_inside_exclusion_regions;
1499 for (GLVolume* volume : this->
volumes)
1500 {
1501 std::vector<bool> inside_extruders;
1502 if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) {
1504 if (volume_below(*volume))
1506 else {
1507 switch (plate_build_volume.type()) {
1509
1510 const BoundingBoxf3& bb = volume_bbox(*volume);
1511 state = plate_build_volume.volume_state_bbox(bb);
1513 {
1514 state = plate_build_volume.check_volume_bbox_state_with_extruder_areas(bb, inside_extruders);
1515 }
1516 break;
1517 }
1520
1522 {
1523 const indexed_triangle_set& convex_mesh_it = volume_convex_mesh(*volume).its;
1524 const Transform3f trafo = volume->world_matrix().cast<
float>();
1525 state = plate_build_volume.object_state(convex_mesh_it, trafo, volume_sinking(*volume));
1527 {
1528 state = plate_build_volume.check_object_state_with_extruder_areas(convex_mesh_it, trafo, inside_extruders);
1529 }
1530 break;
1531 }
1532 default:
1533
1535 break;
1536 }
1538
1539
1540
1541
1542
1543 const std::vector<bool> printable_area_inside_extruders = inside_extruders;
1544
1545
1546
1547
1548
1550 volume->object_idx() >= 0 && volume->object_idx() < int(model_objects.size()) &&
1551 volume->instance_idx() >= 0 &&
1552 volume->instance_idx() < int(model_objects[volume->object_idx()]->instances.size())) {
1553 inside_extruders.resize(extruder_count, true);
1554
1555 const std::pair<int, int> instance_key{ volume->object_idx(), volume->instance_idx() };
1556 auto [cache_it, inserted] = instance_inside_exclusion_regions.emplace(
1557 instance_key, std::vector<bool>(extruder_count, true));
1558 if (inserted) {
1559 const ModelInstance *instance = model_objects[volume->object_idx()]->instances[volume->instance_idx()];
1560 for (size_t extruder_id = 0; extruder_id < exclusion_regions.size(); ++extruder_id) {
1561 if (instance->intersects_bed_exclude_regions(exclusion_regions[extruder_id]))
1562 cache_it->second[extruder_id] = false;
1563 }
1564 }
1565
1566 bool exclusion_limited = false;
1567 for (size_t extruder_id = 0; extruder_id < cache_it->second.size(); ++extruder_id) {
1568 if (!cache_it->second[extruder_id]) {
1569 inside_extruders[extruder_id] = false;
1570 exclusion_limited = true;
1571 }
1572 }
1573
1576
1577 }
1578
1580
1581 ModelObject *model_object = model_objects[volume->object_idx()];
1582 ModelVolume *model_volume = model_object->volumes[volume->volume_idx()];
1583 for (size_t i = 0; i < printable_area_inside_extruders.size(); ++i) {
1584 if (!printable_area_inside_extruders[i]) {
1585 std::vector<int> filaments = model_volume->get_extruders();
1586 unprintable_filament_ids[i].insert(filaments.begin(), filaments.end());
1587 if (object_results) {
1588 std::map<int, std::set<int>>& obj_extruder_filament_maps = objects_unprintable_filaments[model_object];
1589 std::set<int>& obj_extruder_filaments = obj_extruder_filament_maps[i+1];
1590 obj_extruder_filaments.insert(filaments.begin(), filaments.end());
1591 }
1592 }
1593 }
1594 }
1595 }
1596
1597
1600 if (volume->printable) {
1602 {
1604 partly_objects_set.emplace(model_objects[volume->object_idx()]);
1605 }
1610 }
1611 contained_min_one |= !volume->is_outside;
1612 }
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 }
1645 }
1646
1647 std::vector<std::vector<int>> unprintable_filament_vec;
1648 for (const std::set<int>& filamnt_ids : unprintable_filament_ids) {
1649 unprintable_filament_vec.emplace_back(std::vector<int>(filamnt_ids.begin(), filamnt_ids.end()));
1650 }
1651
1652 if (object_results && !partly_objects_set.empty()) {
1653 object_results->partly_outside_objects = std::vector<ModelObject*>(partly_objects_set.begin(), partly_objects_set.end());
1654 }
1655
1656
1657 if (object_results && (extruder_count > 1))
1658 {
1659 object_results->mode = curr_plate->get_real_filament_map_mode(plate_project_config);
1661 {
1662 std::vector<int> conflict_filament_vector;
1663 for (int index = 0; index < extruder_count; index++ )
1664 {
1665 if (!unprintable_filament_vec[index].
empty())
1666 {
1667 std::sort (unprintable_filament_vec[index].
begin(), unprintable_filament_vec[index].
end());
1668 if (index == 0)
1669 conflict_filament_vector = unprintable_filament_vec[index];
1670 else
1671 {
1672 std::vector<int> result_filaments;
1673
1674 std::set_intersection (conflict_filament_vector.begin(), conflict_filament_vector.end(), unprintable_filament_vec[index].begin(), unprintable_filament_vec[index].end(), std::insert_iterator<std::vector<int>>(result_filaments, result_filaments.begin()));
1675 conflict_filament_vector = result_filaments;
1676 }
1677 }
1678 else
1679 {
1680 conflict_filament_vector.clear();
1681 break;
1682 }
1683 }
1684
1685 if (!conflict_filament_vector.empty())
1686 {
1687 std::set<int> conflict_filaments_set(conflict_filament_vector.begin(), conflict_filament_vector.end());
1688 object_results->filaments = conflict_filament_vector;
1689
1690 for (auto& object_map: objects_unprintable_filaments)
1691 {
1692 ModelObject *model_object = object_map.first;
1693 std::map<int, std::set<int>>& obj_extruder_filament_maps = object_map.second;
1694 std::set<int> obj_filaments_set;
1695 ObjectFilamentInfo object_filament_info;
1696 object_filament_info.object = model_object;
1697
1698 for (std::map<int, std::set<int>>::iterator extruder_map_iter = obj_extruder_filament_maps.begin(); extruder_map_iter != obj_extruder_filament_maps.end(); extruder_map_iter++ )
1699 {
1700 int extruder_id = extruder_map_iter->first;
1701 std::set<int>& filaments_set = extruder_map_iter->second;
1702
1703 for (int filament: filaments_set)
1704 {
1705 if (conflict_filaments_set.find(filament) != conflict_filaments_set.end())
1706 {
1707 obj_filaments_set.emplace(filament);
1708 }
1709 }
1710 }
1711 if (!obj_filaments_set.empty()) {
1712 object_filament_info.auto_filaments = std::vector<int>(obj_filaments_set.begin(), obj_filaments_set.end());
1713 object_results->object_filaments.push_back(std::move(object_filament_info));
1714 }
1715 }
1716 }
1717 }
1718 else
1719 {
1720 std::set<int> conflict_filaments_set;
1721 std::vector<int> filament_maps = curr_plate->get_real_filament_maps(plate_project_config);
1722 for (auto& object_map: objects_unprintable_filaments)
1723 {
1724 ModelObject *model_object = object_map.first;
1725 std::map<int, std::set<int>>& obj_extruder_filament_maps = object_map.second;
1726 ObjectFilamentInfo object_filament_info;
1727 object_filament_info.object = model_object;
1728
1729 for (std::map<int, std::set<int>>::iterator extruder_map_iter = obj_extruder_filament_maps.begin(); extruder_map_iter != obj_extruder_filament_maps.end(); extruder_map_iter++ )
1730 {
1731 int extruder_id = extruder_map_iter->first;
1732 std::set<int>& filaments_set = extruder_map_iter->second;
1733
1734 for (int filament: filaments_set)
1735 {
1736 if (filament > 0 && size_t(filament) <= filament_maps.size() &&
1737 filament_maps[filament - 1] == extruder_id)
1738 {
1739 object_filament_info.manual_filaments.emplace(filament, extruder_id);
1740 object_results->filament_maps[filament] = extruder_id;
1741 conflict_filaments_set.emplace(filament);
1742 }
1743 }
1744 }
1745 if (!object_filament_info.manual_filaments.empty())
1746 {
1747 object_results->object_filaments.push_back(std::move(object_filament_info));
1748 }
1749 }
1750 if (!conflict_filaments_set.empty()) {
1751 object_results->filaments = std::vector<int>(conflict_filaments_set.begin(), conflict_filaments_set.end());
1752 }
1753 }
1754
1755 }
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773 if (out_state != nullptr)
1774 *out_state = overall_state;
1775
1776 return contained_min_one;
1777}
const std::vector< double > & extruder_heights() const
Definition BuildVolume.hpp:68
const std::vector< std::vector< Vec2d > > & extruder_areas() const
Definition BuildVolume.hpp:67
int get_extruder_area_count() const
Definition BuildVolume.hpp:126
ObjectState
Definition BuildVolume.hpp:94
@ Limited
Definition BuildVolume.hpp:105
@ Inside
Definition BuildVolume.hpp:96
@ Colliding
Definition BuildVolume.hpp:98
@ Below
Definition BuildVolume.hpp:103
double printable_height() const
Definition BuildVolume.hpp:66
GLVolumePtrs volumes
Definition 3DScene.hpp:468
bool empty() const
Definition 3DScene.hpp:531
#define scale_(val)
Definition libslic3r.h:106
T * begin(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:838
T * end(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:841
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
bool has_bed_exclude_volumes(const DynamicPrintConfig &cfg)
Definition PrintConfig.cpp:14346
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
std::vector< Vec2d > Pointfs
Definition Point.hpp:77
Eigen::Transform< float, 3, Eigen::Affine, Eigen::DontAlign > Transform3f
Definition Point.hpp:95
@ Circle
Definition BuildVolume.hpp:25
@ Convex
Definition BuildVolume.hpp:27
@ Custom
Definition BuildVolume.hpp:29
@ Rectangle
Definition BuildVolume.hpp:23
std::vector< std::vector< BedExcludeRegion > > get_bed_excluded_regions_by_extruder(const DynamicPrintConfig &cfg)
Definition PrintConfig.cpp:14211
@ fmmManual
Definition PrintConfig.hpp:635
ModelInstanceEPrintVolumeState
Definition Model.hpp:1410
@ ModelInstancePVS_Limited
Definition Model.hpp:1412
@ ModelInstancePVS_Inside
Definition Model.hpp:1411
@ ModelInstancePVS_Partly_Outside
Definition Model.hpp:1413
@ ModelInstancePVS_Fully_Outside
Definition Model.hpp:1414
std::vector< ModelObject * > ModelObjectPtrs
Definition CutUtils.hpp:13