mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 03:29:00 +08:00
refactored support spot generator to store data in the shared PrintObjectRegions struct, automatic coloring moved to frontend.
There are still issues with multiple instances
This commit is contained in:
parent
b67fe277fc
commit
49b68b936c
@ -8,6 +8,7 @@
|
||||
#include "Flow.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "Slicing.hpp"
|
||||
#include "SupportSpotsGenerator.hpp"
|
||||
#include "TriangleMeshSlicer.hpp"
|
||||
#include "GCode/ToolOrdering.hpp"
|
||||
#include "GCode/WipeTower.hpp"
|
||||
@ -20,6 +21,7 @@
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <tcbspan/span.hpp>
|
||||
|
||||
@ -207,12 +209,15 @@ public:
|
||||
Transform3d trafo_bboxes;
|
||||
std::vector<ObjectID> cached_volume_ids;
|
||||
|
||||
SupportSpotsGenerator::SupportPoints generated_support_points;
|
||||
|
||||
void ref_cnt_inc() { ++ m_ref_cnt; }
|
||||
void ref_cnt_dec() { if (-- m_ref_cnt == 0) delete this; }
|
||||
void clear() {
|
||||
all_regions.clear();
|
||||
layer_ranges.clear();
|
||||
cached_volume_ids.clear();
|
||||
generated_support_points.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -516,7 +516,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloatOrPercent, min_feature_size))
|
||||
((ConfigOptionFloatOrPercent, min_bead_width))
|
||||
((ConfigOptionBool, support_material))
|
||||
// Automatic supports (generated based on support_material_threshold).
|
||||
// Automatic supports (generated based fdm support point generator).
|
||||
((ConfigOptionBool, support_material_auto))
|
||||
// Direction of the support pattern (in XY plane).`
|
||||
((ConfigOptionFloat, support_material_angle))
|
||||
|
@ -417,44 +417,13 @@ std::vector<size_t> problematic_layers = SupportSpotsGenerator::quick_search(thi
|
||||
void PrintObject::generate_support_spots()
|
||||
{
|
||||
if (this->set_started(posSupportSpotsSearch)) {
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "Searching support spots - start";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Searching support spots - start";
|
||||
m_print->set_status(75, L("Searching support spots"));
|
||||
if (m_config.support_material && !m_config.support_material_auto &&
|
||||
std::all_of(this->model_object()->volumes.begin(), this->model_object()->volumes.end(),
|
||||
[](const ModelVolume* mv){return mv->supported_facets.empty();})
|
||||
) {
|
||||
SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values};
|
||||
SupportSpotsGenerator::Issues issues = SupportSpotsGenerator::full_search(this, params);
|
||||
|
||||
auto obj_transform = this->trafo_centered();
|
||||
for (ModelVolume *model_volume : this->model_object()->volumes) {
|
||||
if (model_volume->is_model_part()) {
|
||||
Transform3d mesh_transformation = obj_transform * model_volume->get_matrix();
|
||||
Transform3d inv_transform = mesh_transformation.inverse();
|
||||
TriangleSelectorWrapper selector { model_volume->mesh(), mesh_transformation};
|
||||
|
||||
for (const SupportSpotsGenerator::SupportPoint &support_point : issues.support_points) {
|
||||
Vec3f point = Vec3f(inv_transform.cast<float>() * support_point.position);
|
||||
Vec3f origin = Vec3f(
|
||||
inv_transform.cast<float>() * Vec3f(support_point.position.x(), support_point.position.y(), 0.0f));
|
||||
selector.enforce_spot(point, origin, support_point.spot_radius);
|
||||
}
|
||||
|
||||
model_volume->supported_facets.set(selector.selector);
|
||||
#if 0 //DEBUG export
|
||||
indexed_triangle_set copy = model_volume->mesh().its;
|
||||
its_transform(copy, obj_transform * model_transformation);
|
||||
its_write_obj(copy,
|
||||
debug_out_path(("model"+std::to_string(model_volume->id().id)+".obj").c_str()).c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SupportSpotsGenerator::SupportPoints supp_points = SupportSpotsGenerator::full_search(this, params);
|
||||
this->m_shared_regions->generated_support_points = supp_points;
|
||||
m_print->throw_if_canceled();
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "Searching support spots - end";
|
||||
BOOST_LOG_TRIVIAL(debug) << "Searching support spots - end";
|
||||
this->set_done(posSupportSpotsSearch);
|
||||
}
|
||||
}
|
||||
|
@ -665,9 +665,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
Issues check_stability(const PrintObject *po, const Params ¶ms)
|
||||
SupportPoints check_stability(const PrintObject *po, const Params ¶ms)
|
||||
{
|
||||
Issues issues{};
|
||||
SupportPoints supp_points{};
|
||||
SupportGridFilter supports_presence_grid(po, params.min_distance_between_support_points);
|
||||
ActiveObjectParts active_object_parts{};
|
||||
LD prev_layer_ext_perim_lines({});
|
||||
@ -764,14 +764,14 @@ Issues check_stability(const PrintObject *po, const Params ¶ms)
|
||||
#endif
|
||||
// Function that is used when new support point is generated. It will update the ObjectPart stability, weakest conneciton info,
|
||||
// and the support presence grid and add the point to the issues.
|
||||
auto reckon_new_support_point = [&part, &weakest_conn, &issues, &supports_presence_grid, ¶ms,
|
||||
auto reckon_new_support_point = [&part, &weakest_conn, &supp_points, &supports_presence_grid, ¶ms,
|
||||
&layer_idx](const Vec3f &support_point, float force, const Vec2f &dir) {
|
||||
if (supports_presence_grid.position_taken(support_point) || layer_idx <= 1) { return; }
|
||||
float area = params.support_points_interface_radius * params.support_points_interface_radius * float(PI);
|
||||
part.add_support_point(support_point, area);
|
||||
|
||||
float radius = params.support_points_interface_radius;
|
||||
issues.support_points.emplace_back(support_point, force, radius, dir);
|
||||
supp_points.emplace_back(support_point, force, radius, dir);
|
||||
supports_presence_grid.take_position(support_point);
|
||||
|
||||
if (weakest_conn.area > EPSILON) { // Do not add it to the weakest connection if it is not valid - does not exist
|
||||
@ -836,7 +836,7 @@ Issues check_stability(const PrintObject *po, const Params ¶ms)
|
||||
} // slice iterations
|
||||
prev_layer_ext_perim_lines = LD(current_layer_ext_perims_lines);
|
||||
} // layer iterations
|
||||
return issues;
|
||||
return supp_points;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
@ -868,14 +868,14 @@ void debug_export(Issues issues, std::string file_name)
|
||||
// std::vector<size_t> quick_search(const PrintObject *po, const Params ¶ms) {
|
||||
// return {};
|
||||
// }
|
||||
Issues full_search(const PrintObject *po, const Params ¶ms)
|
||||
SupportPoints full_search(const PrintObject *po, const Params ¶ms)
|
||||
{
|
||||
Issues issues = check_stability(po, params);
|
||||
SupportPoints supp_points = check_stability(po, params);
|
||||
#ifdef DEBUG_FILES
|
||||
debug_export(issues, "issues");
|
||||
#endif
|
||||
|
||||
return issues;
|
||||
return supp_points;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#ifndef SRC_LIBSLIC3R_SUPPORTABLEISSUESSEARCH_HPP_
|
||||
#define SRC_LIBSLIC3R_SUPPORTABLEISSUESSEARCH_HPP_
|
||||
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "Layer.hpp"
|
||||
#include "Line.hpp"
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -67,19 +69,17 @@ struct SupportPoint {
|
||||
Vec2f direction;
|
||||
};
|
||||
|
||||
struct Issues {
|
||||
std::vector<SupportPoint> support_points;
|
||||
};
|
||||
using SupportPoints = std::vector<SupportPoint>;
|
||||
|
||||
struct Malformations {
|
||||
std::vector<Lines> layers; //for each layer
|
||||
};
|
||||
|
||||
// std::vector<size_t> quick_search(const PrintObject *po, const Params ¶ms);
|
||||
Issues full_search(const PrintObject *po, const Params ¶ms);
|
||||
SupportPoints full_search(const PrintObject *po, const Params ¶ms);
|
||||
|
||||
void estimate_supports_malformations(SupportLayerPtrs &layers, float supports_flow_width, const Params ¶ms);
|
||||
void estimate_malformations(LayerPtrs &layers, const Params ¶ms);
|
||||
void estimate_supports_malformations(std::vector<SupportLayer*> &layers, float supports_flow_width, const Params ¶ms);
|
||||
void estimate_malformations(std::vector<Layer*> &layers, const Params ¶ms);
|
||||
|
||||
} // namespace SupportSpotsGenerator
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ namespace Slic3r {
|
||||
TriangleSelectorWrapper::TriangleSelectorWrapper(const TriangleMesh &mesh, const Transform3d& mesh_transform) :
|
||||
mesh(mesh), mesh_transform(mesh_transform), selector(mesh), triangles_tree(
|
||||
AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(mesh.its.vertices, mesh.its.indices)) {
|
||||
|
||||
}
|
||||
|
||||
void TriangleSelectorWrapper::enforce_spot(const Vec3f &point, const Vec3f &origin, float radius) {
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
//#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "libslic3r/SupportSpotsGenerator.hpp"
|
||||
#include "libslic3r/TriangleSelectorWrapper.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/ImGuiWrapper.hpp"
|
||||
@ -392,13 +394,13 @@ void GLGizmoFdmSupports::data_changed()
|
||||
|
||||
ModelObject* mo = m_c->selection_info()->model_object();
|
||||
if (mo && this->waiting_for_autogenerated_supports) {
|
||||
get_data_from_backend();
|
||||
apply_data_from_backend();
|
||||
} else {
|
||||
this->waiting_for_autogenerated_supports = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoFdmSupports::get_data_from_backend()
|
||||
void GLGizmoFdmSupports::apply_data_from_backend()
|
||||
{
|
||||
if (!has_backend_supports())
|
||||
return;
|
||||
@ -407,28 +409,43 @@ void GLGizmoFdmSupports::get_data_from_backend()
|
||||
// find the respective PrintObject, we need a pointer to it
|
||||
for (const PrintObject *po : m_parent.fff_print()->objects()) {
|
||||
if (po->model_object()->id() == mo->id()) {
|
||||
std::unordered_map<size_t, const ModelVolume*> mvs;
|
||||
for (const ModelVolume* mv : po->model_object()->volumes) {
|
||||
if (mv->is_model_part()) {
|
||||
mvs.emplace(mv->id().id, mv);
|
||||
}
|
||||
}
|
||||
int mesh_id = -1.0f;
|
||||
for (ModelVolume* mv : mo->volumes){
|
||||
if (mv->is_model_part()){
|
||||
mesh_id++;
|
||||
mv->supported_facets.assign(mvs[mv->id().id]->supported_facets);
|
||||
m_triangle_selectors[mesh_id]->deserialize(mv->supported_facets.get_data(), true);
|
||||
m_triangle_selectors[mesh_id]->request_update_render_data();
|
||||
}
|
||||
}
|
||||
this->waiting_for_autogenerated_supports = false;
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
m_parent.set_as_dirty();
|
||||
std::unordered_map<size_t, TriangleSelectorWrapper> selectors;
|
||||
SupportSpotsGenerator::SupportPoints support_points = po->shared_regions()->generated_support_points;
|
||||
auto obj_transform = po->trafo_centered();
|
||||
for (ModelVolume *model_volume : po->model_object()->volumes) {
|
||||
if (model_volume->is_model_part()) {
|
||||
Transform3d mesh_transformation = obj_transform * model_volume->get_matrix();
|
||||
Transform3d inv_transform = mesh_transformation.inverse();
|
||||
selectors.emplace(model_volume->id().id, TriangleSelectorWrapper{model_volume->mesh(), mesh_transformation});
|
||||
|
||||
for (const SupportSpotsGenerator::SupportPoint &support_point : support_points) {
|
||||
Vec3f point = Vec3f(inv_transform.cast<float>() * support_point.position);
|
||||
Vec3f origin = Vec3f(inv_transform.cast<float>() *
|
||||
Vec3f(support_point.position.x(), support_point.position.y(), 0.0f));
|
||||
selectors.at(model_volume->id().id).enforce_spot(point, origin, support_point.spot_radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mesh_id = -1.0f;
|
||||
for (ModelVolume *mv : mo->volumes) {
|
||||
if (mv->is_model_part()) {
|
||||
mesh_id++;
|
||||
auto selector = selectors.find(mv->id().id);
|
||||
if (selector != selectors.end()) {
|
||||
mv->supported_facets.set(selector->second.selector);
|
||||
m_triangle_selectors[mesh_id]->deserialize(mv->supported_facets.get_data(), true);
|
||||
m_triangle_selectors[mesh_id]->request_update_render_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
m_parent.set_as_dirty();
|
||||
}
|
||||
this->waiting_for_autogenerated_supports = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoFdmSupports::update_model_object() const
|
||||
{
|
||||
@ -474,11 +491,13 @@ void GLGizmoFdmSupports::update_from_model_object()
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoFdmSupports::has_backend_supports() const
|
||||
bool GLGizmoFdmSupports::has_backend_supports()
|
||||
{
|
||||
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||
if (! mo)
|
||||
if (! mo) {
|
||||
waiting_for_autogenerated_supports = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find PrintObject with this ID
|
||||
for (const PrintObject* po : m_parent.fff_print()->objects()) {
|
||||
@ -520,8 +539,6 @@ void GLGizmoFdmSupports::auto_generate()
|
||||
}
|
||||
}
|
||||
|
||||
mo->config.set("support_material", true);
|
||||
mo->config.set("support_material_auto", false);
|
||||
this->waiting_for_autogenerated_supports = true;
|
||||
wxGetApp().CallAfter([this]() { reslice_FDM_supports(); });
|
||||
}
|
||||
|
@ -43,10 +43,10 @@ private:
|
||||
|
||||
|
||||
bool waiting_for_autogenerated_supports = false;
|
||||
bool has_backend_supports() const;
|
||||
bool has_backend_supports();
|
||||
void reslice_FDM_supports(bool postpone_error_messages = false) const;
|
||||
void auto_generate();
|
||||
void get_data_from_backend();
|
||||
void apply_data_from_backend();
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user