1035{
1037 if (canvas.get_model() == nullptr)
1038 return markers;
1039
1041 {
1043 std::vector<const GLVolume*> volumes;
1044 };
1045 std::map<int, std::map<int, Instance>> objects;
1047 for (const GLVolume* volume : canvas.get_volumes().volumes) {
1048 const int obj_idx = volume->object_idx();
1049 const int vol_idx = volume->volume_idx();
1050 if (!volume->is_active || volume->is_wipe_tower || obj_idx < 0 || obj_idx >= int(model_objects.size()) || vol_idx < 0 ||
1051 vol_idx >= int(model_objects[obj_idx]->volumes.size()))
1052 continue;
1053 Instance& instance = objects[obj_idx][volume->instance_idx()];
1054 instance.trafo = volume->get_instance_transformation().get_matrix();
1055 instance.volumes.emplace_back(volume);
1056 }
1057
1058
1059 const PresetBundle& preset_bundle = *wxGetApp().preset_bundle;
1060 std::vector<double> filament_densities;
1061 for (const std::string& name : preset_bundle.filament_presets)
1062 filament_densities.emplace_back(preset_bundle.filaments.find_preset(name, true)->config.opt_float("filament_density", 0));
1063 const auto density = [&filament_densities](const ModelVolume& volume) {
1064 const size_t filament = size_t(std::max(1, volume.extruder_id()));
1065 const double density = filament <= filament_densities.size() ? filament_densities[filament - 1] : 0.;
1067 };
1068
1069
1070 PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
1071 std::map<int, Marker> plates;
1072 std::map<size_t, MassProperties> meshes;
1073 std::map<size_t, Bodies> bodies;
1074 for (const auto& [obj_idx, instances] : objects) {
1075 const ModelObject& object = *model_objects[obj_idx];
1076
1077
1078 std::vector<const GLVolume*> volumes = instances.begin()->second.volumes;
1079 std::sort(volumes.begin(), volumes.end(), [](const GLVolume* l, const GLVolume* r) { return l->volume_idx() < r->volume_idx(); });
1080 std::vector<MeshInPlace> solids;
1081 std::vector<double> densities;
1082 std::vector<MeshInPlace> negatives;
1083 std::vector<Bodies::Volume> sliced;
1084 for (const GLVolume* volume : volumes) {
1085 const ModelVolume& model_volume = *object.volumes[volume->volume_idx()];
1086 if (!model_volume.is_model_part() && !model_volume.is_negative_volume())
1087 continue;
1088 const Transform3d trafo = volume->get_volume_transformation().get_matrix();
1089 if (model_volume.is_model_part()) {
1090 solids.emplace_back(&model_volume.mesh().its, trafo);
1091 densities.emplace_back(density(model_volume));
1092 } else
1093 negatives.emplace_back(&model_volume.mesh().its, trafo);
1094 sliced.push_back({ model_volume.id().id, model_volume.is_negative_volume(), model_volume.is_model_part() ? densities.back() : 0., trafo });
1095 }
1096 const std::vector<SolidBody>* assembly = nullptr;
1097 if (solids.size() > 1 || (!solids.empty() && !negatives.empty())) {
1098
1099 const size_t slabs = canvas.is_dragging() ? 100 : 500;
1100 const auto cached =
m_bodies.find(
object.
id().
id);
1101 const bool valid = cached !=
m_bodies.end() && cached->second.slabs >= slabs && cached->second.volumes == sliced;
1102 Bodies& entry = bodies[
object.id().id];
1103 entry = valid ? std::move(cached->second) :
Bodies{ std::move(sliced), slabs,
solid_bodies(solids, densities, negatives, slabs) };
1104 assembly = &entry.bodies;
1105 }
1106
1107 for (const auto& [inst_idx, instance] : instances) {
1108
1110 object_marker.
assembly = assembly !=
nullptr;
1111 for (const GLVolume* volume : instance.volumes)
1112 if (object.volumes[volume->volume_idx()]->is_model_part())
1113 object_marker.box.merge(volume->transformed_convex_hull_bounding_box());
1114 if (assembly != nullptr) {
1115 std::vector<Marker> parts;
1116 for (const SolidBody& body : *assembly)
1117 if (body.mass > 0.) {
1118 parts.push_back({
mass_sum(body.transformed(instance.trafo)), body.bounding_box(instance.trafo) });
1119 object_marker.sum.add(parts.back().sum);
1120 }
1121 if (parts.size() > 1)
1123 } else
1124 for (const GLVolume* volume : instance.volumes) {
1125
1126 const ModelVolume& model_volume = *object.volumes[volume->volume_idx()];
1127 if (!model_volume.is_model_part())
1128 continue;
1129 const auto [it, inserted] = meshes.try_emplace(model_volume.id().id);
1130 if (inserted) {
1131 const auto cached =
m_meshes.find(it->first);
1133 }
1134 MassProperties part = it->second.transformed(volume->world_matrix());
1135 part.mass *= density(model_volume);
1136 object_marker.sum.add(
mass_sum(part));
1137 }
1138 if (object_marker.sum.mass > 0.) {
1139 if (const int plate = plate_list.find_instance(obj_idx, inst_idx); plate >= 0) {
1140 plates[plate].sum.add(object_marker.sum);
1141 plates[plate].box.merge(object_marker.box);
1142 }
1143 markers[
mkObject].emplace_back(std::move(object_marker));
1144 }
1145 }
1146 }
1149 for (auto& [plate, marker] : plates)
1150 markers[
mkPlate].emplace_back(std::move(marker));
1151 return markers;
1152}
std::map< size_t, MassProperties > m_meshes
Definition GLCanvas3D.hpp:504
std::array< std::vector< Marker >, mkCount > Markers
Definition GLCanvas3D.hpp:499
std::map< size_t, Bodies > m_bodies
Definition GLCanvas3D.hpp:524
Definition GLCanvas3D.hpp:507
@ Instance
Definition GUI_Geometry.hpp:10
static GCodeProcessorResult::ObjectMass::Sum mass_sum(const MassProperties &solid)
Definition GLCanvas3D.cpp:1014
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
std::vector< SolidBody > solid_bodies(const std::vector< MeshInPlace > &solids, const std::vector< double > &densities, const std::vector< MeshInPlace > &negatives, size_t slabs)
Definition ConnectedBodies.cpp:184
constexpr float DEFAULT_FILAMENT_DENSITY
Definition GCodeProcessor.hpp:42
MassProperties its_mass_properties(const indexed_triangle_set &its)
Definition TriangleMesh.cpp:1508
std::vector< ModelObject * > ModelObjectPtrs
Definition CutUtils.hpp:13
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:157
Definition GLCanvas3D.hpp:490
bool assembly
Definition GLCanvas3D.hpp:494