Add possible manipulation of small support diameter.
This commit is contained in:
parent
7c655b5d7e
commit
8cb115a035
@ -2715,7 +2715,7 @@ void PrintConfigDef::init_sla_params()
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
def = this->add("support_head_front_diameter", coFloat);
|
||||
def->label = L("Support head front diameter");
|
||||
def->label = L("Pinhead front diameter");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("Diameter of the pointing side of the head");
|
||||
def->sidetext = L("mm");
|
||||
@ -2724,7 +2724,7 @@ void PrintConfigDef::init_sla_params()
|
||||
def->set_default_value(new ConfigOptionFloat(0.4));
|
||||
|
||||
def = this->add("support_head_penetration", coFloat);
|
||||
def->label = L("Support head penetration");
|
||||
def->label = L("Head penetration");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("How much the pinhead has to penetrate the model surface");
|
||||
def->sidetext = L("mm");
|
||||
@ -2733,7 +2733,7 @@ void PrintConfigDef::init_sla_params()
|
||||
def->set_default_value(new ConfigOptionFloat(0.2));
|
||||
|
||||
def = this->add("support_head_width", coFloat);
|
||||
def->label = L("Support head width");
|
||||
def->label = L("Pinhead width");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("Width from the back sphere center to the front sphere center");
|
||||
def->sidetext = L("mm");
|
||||
@ -2743,7 +2743,7 @@ void PrintConfigDef::init_sla_params()
|
||||
def->set_default_value(new ConfigOptionFloat(1.0));
|
||||
|
||||
def = this->add("support_pillar_diameter", coFloat);
|
||||
def->label = L("Support pillar diameter");
|
||||
def->label = L("Pillar diameter");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("Diameter in mm of the support pillars");
|
||||
def->sidetext = L("mm");
|
||||
@ -2752,6 +2752,17 @@ void PrintConfigDef::init_sla_params()
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionFloat(1.0));
|
||||
|
||||
def = this->add("support_small_pillar_diameter_percent", coPercent);
|
||||
def->label = L("Small pillar diameter percent");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("The percentage of smaller pillars compared to the normal pillar diameter "
|
||||
"which are used in problematic areas where a normal pilla cannot fit.");
|
||||
def->sidetext = L("%");
|
||||
def->min = 1;
|
||||
def->max = 100;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionPercent(50));
|
||||
|
||||
def = this->add("support_max_bridges_on_pillar", coInt);
|
||||
def->label = L("Max bridges on a pillar");
|
||||
def->tooltip = L(
|
||||
@ -2763,7 +2774,7 @@ void PrintConfigDef::init_sla_params()
|
||||
def->set_default_value(new ConfigOptionInt(3));
|
||||
|
||||
def = this->add("support_pillar_connection_mode", coEnum);
|
||||
def->label = L("Support pillar connection mode");
|
||||
def->label = L("Pillar connection mode");
|
||||
def->tooltip = L("Controls the bridge type between two neighboring pillars."
|
||||
" Can be zig-zag, cross (double zig-zag) or dynamic which"
|
||||
" will automatically switch between the first two depending"
|
||||
|
@ -1019,6 +1019,10 @@ public:
|
||||
// Radius in mm of the support pillars.
|
||||
ConfigOptionFloat support_pillar_diameter /*= 0.8*/;
|
||||
|
||||
// The percentage of smaller pillars compared to the normal pillar diameter
|
||||
// which are used in problematic areas where a normal pilla cannot fit.
|
||||
ConfigOptionPercent support_small_pillar_diameter_percent;
|
||||
|
||||
// How much bridge (supporting another pinhead) can be placed on a pillar.
|
||||
ConfigOptionInt support_max_bridges_on_pillar;
|
||||
|
||||
@ -1142,6 +1146,7 @@ protected:
|
||||
OPT_PTR(support_head_penetration);
|
||||
OPT_PTR(support_head_width);
|
||||
OPT_PTR(support_pillar_diameter);
|
||||
OPT_PTR(support_small_pillar_diameter_percent);
|
||||
OPT_PTR(support_max_bridges_on_pillar);
|
||||
OPT_PTR(support_pillar_connection_mode);
|
||||
OPT_PTR(support_buildplate_only);
|
||||
|
@ -44,6 +44,8 @@ struct SupportTreeConfig
|
||||
// Radius of the back side of the 3d arrow.
|
||||
double head_back_radius_mm = 0.5;
|
||||
|
||||
double head_fallback_radius_mm = 0.25;
|
||||
|
||||
// Width in mm from the back sphere center to the front sphere center.
|
||||
double head_width_mm = 1.0;
|
||||
|
||||
|
@ -25,119 +25,6 @@ static Hit min_hit(const C &hits)
|
||||
return *mit;
|
||||
}
|
||||
|
||||
//IndexedMesh::hit_result query_hit(const SupportableMesh &msh, const Head &h)
|
||||
//{
|
||||
// static const size_t SAMPLES = 8;
|
||||
|
||||
// // Move away slightly from the touching point to avoid raycasting on the
|
||||
// // inner surface of the mesh.
|
||||
|
||||
// const double& sd = msh.cfg.safety_distance_mm;
|
||||
|
||||
// auto& m = msh.emesh;
|
||||
// using HitResult = IndexedMesh::hit_result;
|
||||
|
||||
// // Hit results
|
||||
// std::array<HitResult, SAMPLES> hits;
|
||||
|
||||
// Vec3d s1 = h.pos, s2 = h.junction_point();
|
||||
|
||||
// struct Rings {
|
||||
// double rpin;
|
||||
// double rback;
|
||||
// Vec3d spin;
|
||||
// Vec3d sback;
|
||||
// PointRing<SAMPLES> ring;
|
||||
|
||||
// Vec3d backring(size_t idx) { return ring.get(idx, sback, rback); }
|
||||
// Vec3d pinring(size_t idx) { return ring.get(idx, spin, rpin); }
|
||||
// } rings {h.r_pin_mm + sd, h.r_back_mm + sd, s1, s2, h.dir};
|
||||
|
||||
// // We will shoot multiple rays from the head pinpoint in the direction
|
||||
// // of the pinhead robe (side) surface. The result will be the smallest
|
||||
// // hit distance.
|
||||
|
||||
// auto hitfn = [&m, &rings, sd](HitResult &hit, size_t i) {
|
||||
// // Point on the circle on the pin sphere
|
||||
// Vec3d ps = rings.pinring(i);
|
||||
// // This is the point on the circle on the back sphere
|
||||
// Vec3d p = rings.backring(i);
|
||||
|
||||
// // Point ps is not on mesh but can be inside or
|
||||
// // outside as well. This would cause many problems
|
||||
// // with ray-casting. To detect the position we will
|
||||
// // use the ray-casting result (which has an is_inside
|
||||
// // predicate).
|
||||
|
||||
// Vec3d n = (p - ps).normalized();
|
||||
// auto q = m.query_ray_hit(ps + sd * n, n);
|
||||
|
||||
// if (q.is_inside()) { // the hit is inside the model
|
||||
// if (q.distance() > rings.rpin) {
|
||||
// // If we are inside the model and the hit
|
||||
// // distance is bigger than our pin circle
|
||||
// // diameter, it probably indicates that the
|
||||
// // support point was already inside the
|
||||
// // model, or there is really no space
|
||||
// // around the point. We will assign a zero
|
||||
// // hit distance to these cases which will
|
||||
// // enforce the function return value to be
|
||||
// // an invalid ray with zero hit distance.
|
||||
// // (see min_element at the end)
|
||||
// hit = HitResult(0.0);
|
||||
// } else {
|
||||
// // re-cast the ray from the outside of the
|
||||
// // object. The starting point has an offset
|
||||
// // of 2*safety_distance because the
|
||||
// // original ray has also had an offset
|
||||
// auto q2 = m.query_ray_hit(ps + (q.distance() + 2 * sd) * n, n);
|
||||
// hit = q2;
|
||||
// }
|
||||
// } else
|
||||
// hit = q;
|
||||
// };
|
||||
|
||||
// ccr::enumerate(hits.begin(), hits.end(), hitfn);
|
||||
|
||||
// return min_hit(hits);
|
||||
//}
|
||||
|
||||
//IndexedMesh::hit_result query_hit(const SupportableMesh &msh, const Bridge &br, double safety_d)
|
||||
//{
|
||||
|
||||
// static const size_t SAMPLES = 8;
|
||||
|
||||
// Vec3d dir = (br.endp - br.startp).normalized();
|
||||
// PointRing<SAMPLES> ring{dir};
|
||||
|
||||
// using Hit = IndexedMesh::hit_result;
|
||||
|
||||
// // Hit results
|
||||
// std::array<Hit, SAMPLES> hits;
|
||||
|
||||
// double sd = std::isnan(safety_d) ? msh.cfg.safety_distance_mm : safety_d;
|
||||
|
||||
// auto hitfn = [&msh, &br, &ring, dir, sd] (Hit &hit, size_t i) {
|
||||
|
||||
// // Point on the circle on the pin sphere
|
||||
// Vec3d p = ring.get(i, br.startp, br.r + sd);
|
||||
|
||||
// auto hr = msh.emesh.query_ray_hit(p + br.r * dir, dir);
|
||||
|
||||
// if(hr.is_inside()) {
|
||||
// if(hr.distance() > 2 * br.r + sd) hit = Hit(0.0);
|
||||
// else {
|
||||
// // re-cast the ray from the outside of the object
|
||||
// hit = msh.emesh.query_ray_hit(p + (hr.distance() + 2 * sd) * dir, dir);
|
||||
// }
|
||||
// } else hit = hr;
|
||||
// };
|
||||
|
||||
// ccr::enumerate(hits.begin(), hits.end(), hitfn);
|
||||
|
||||
// return min_hit(hits);
|
||||
//}
|
||||
|
||||
SupportTreeBuildsteps::SupportTreeBuildsteps(SupportTreeBuilder & builder,
|
||||
const SupportableMesh &sm)
|
||||
: m_cfg(sm.cfg)
|
||||
@ -282,15 +169,18 @@ bool SupportTreeBuildsteps::execute(SupportTreeBuilder & builder,
|
||||
}
|
||||
|
||||
IndexedMesh::hit_result SupportTreeBuildsteps::pinhead_mesh_intersect(
|
||||
const Vec3d &s, const Vec3d &dir, double r_pin, double r_back, double width)
|
||||
const Vec3d &s,
|
||||
const Vec3d &dir,
|
||||
double r_pin,
|
||||
double r_back,
|
||||
double width,
|
||||
double sd)
|
||||
{
|
||||
static const size_t SAMPLES = 8;
|
||||
|
||||
// Move away slightly from the touching point to avoid raycasting on the
|
||||
// inner surface of the mesh.
|
||||
|
||||
const double& sd = m_cfg.safety_distance_mm;
|
||||
|
||||
auto& m = m_mesh;
|
||||
using HitResult = IndexedMesh::hit_result;
|
||||
|
||||
@ -836,12 +726,17 @@ void SupportTreeBuildsteps::add_pinheads()
|
||||
// First we need to determine the available space for a mini pinhead.
|
||||
// The goal is the move away from the model a little bit to make the
|
||||
// contact point small as possible and avoid pearcing the model body.
|
||||
double pin_space = std::min(2 * R, bridge_mesh_distance(sph, n, R, 0.));
|
||||
double back_r = m_cfg.head_fallback_radius_mm;
|
||||
double max_w = 2 * R;
|
||||
double pin_space = std::min(max_w,
|
||||
pinhead_mesh_intersect(sph, n, R, back_r,
|
||||
max_w, 0.)
|
||||
.distance());
|
||||
|
||||
if (pin_space <= 0) continue;
|
||||
|
||||
m_iheads.emplace_back(i);
|
||||
m_builder.add_head(i, R, R, pin_space,
|
||||
m_builder.add_head(i, back_r, R, pin_space,
|
||||
m_cfg.head_penetration_mm, n, sph);
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +238,19 @@ class SupportTreeBuildsteps {
|
||||
const Vec3d& dir,
|
||||
double r_pin,
|
||||
double r_back,
|
||||
double width);
|
||||
double width,
|
||||
double safety_d);
|
||||
|
||||
IndexedMesh::hit_result pinhead_mesh_intersect(
|
||||
const Vec3d& s,
|
||||
const Vec3d& dir,
|
||||
double r_pin,
|
||||
double r_back,
|
||||
double width)
|
||||
{
|
||||
return pinhead_mesh_intersect(s, dir, r_pin, r_back, width,
|
||||
m_cfg.safety_distance_mm);
|
||||
}
|
||||
|
||||
// Checking bridge (pillar and stick as well) intersection with the model.
|
||||
// If the function is used for headless sticks, the ins_check parameter
|
||||
|
@ -41,7 +41,10 @@ sla::SupportTreeConfig make_support_cfg(const SLAPrintObjectConfig& c)
|
||||
|
||||
scfg.enabled = c.supports_enable.getBool();
|
||||
scfg.head_front_radius_mm = 0.5*c.support_head_front_diameter.getFloat();
|
||||
scfg.head_back_radius_mm = 0.5*c.support_pillar_diameter.getFloat();
|
||||
double pillar_r = 0.5 * c.support_pillar_diameter.getFloat();
|
||||
scfg.head_back_radius_mm = pillar_r;
|
||||
scfg.head_fallback_radius_mm =
|
||||
0.01 * c.support_small_pillar_diameter_percent.getFloat() * pillar_r;
|
||||
scfg.head_penetration_mm = c.support_head_penetration.getFloat();
|
||||
scfg.head_width_mm = c.support_head_width.getFloat();
|
||||
scfg.object_elevation_mm = is_zero_elevation(c) ?
|
||||
@ -925,6 +928,7 @@ bool SLAPrintObject::invalidate_state_by_config_options(const std::vector<t_conf
|
||||
|| opt_key == "support_head_penetration"
|
||||
|| opt_key == "support_head_width"
|
||||
|| opt_key == "support_pillar_diameter"
|
||||
|| opt_key == "support_small_pillar_diameter_percent"
|
||||
|| opt_key == "support_max_bridges_on_pillar"
|
||||
|| opt_key == "support_pillar_connection_mode"
|
||||
|| opt_key == "support_buildplate_only"
|
||||
|
@ -353,6 +353,7 @@ void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config)
|
||||
toggle_field("support_head_penetration", supports_en);
|
||||
toggle_field("support_head_width", supports_en);
|
||||
toggle_field("support_pillar_diameter", supports_en);
|
||||
toggle_field("support_small_pillar_diameter_percent", supports_en);
|
||||
toggle_field("support_max_bridges_on_pillar", supports_en);
|
||||
toggle_field("support_pillar_connection_mode", supports_en);
|
||||
toggle_field("support_buildplate_only", supports_en);
|
||||
|
@ -496,6 +496,7 @@ const std::vector<std::string>& Preset::sla_print_options()
|
||||
"support_head_penetration",
|
||||
"support_head_width",
|
||||
"support_pillar_diameter",
|
||||
"support_small_pillar_diameter_percent",
|
||||
"support_max_bridges_on_pillar",
|
||||
"support_pillar_connection_mode",
|
||||
"support_buildplate_only",
|
||||
|
@ -3919,6 +3919,7 @@ void TabSLAPrint::build()
|
||||
|
||||
optgroup = page->new_optgroup(L("Support pillar"));
|
||||
optgroup->append_single_option_line("support_pillar_diameter");
|
||||
optgroup->append_single_option_line("support_small_pillar_diameter_percent");
|
||||
optgroup->append_single_option_line("support_max_bridges_on_pillar");
|
||||
|
||||
optgroup->append_single_option_line("support_pillar_connection_mode");
|
||||
|
Loading…
Reference in New Issue
Block a user