ENH: add bridge for beamlocking
jira: NONE Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: I5126d8e8d327ece7615fdfe536500018dec54b48
This commit is contained in:
parent
84786cc6a8
commit
6231148ef3
|
@ -549,6 +549,7 @@ private:
|
||||||
void detect_surfaces_type();
|
void detect_surfaces_type();
|
||||||
void process_external_surfaces();
|
void process_external_surfaces();
|
||||||
void discover_vertical_shells();
|
void discover_vertical_shells();
|
||||||
|
void discover_shell_for_perimeters();
|
||||||
void bridge_over_infill();
|
void bridge_over_infill();
|
||||||
void clip_fill_surfaces();
|
void clip_fill_surfaces();
|
||||||
void discover_horizontal_shells();
|
void discover_horizontal_shells();
|
||||||
|
|
|
@ -516,6 +516,7 @@ void PrintObject::prepare_infill()
|
||||||
this->discover_vertical_shells();
|
this->discover_vertical_shells();
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
|
|
||||||
|
|
||||||
// this will detect bridges and reverse bridges
|
// this will detect bridges and reverse bridges
|
||||||
// and rearrange top/bottom/internal surfaces
|
// and rearrange top/bottom/internal surfaces
|
||||||
// It produces enlarged overlapping bridging areas.
|
// It produces enlarged overlapping bridging areas.
|
||||||
|
@ -559,6 +560,8 @@ void PrintObject::prepare_infill()
|
||||||
} // for each region
|
} // for each region
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
|
if (m_config.interlocking_beam.value)
|
||||||
|
discover_shell_for_perimeters();
|
||||||
|
|
||||||
// Only active if config->infill_only_where_needed. This step trims the sparse infill,
|
// Only active if config->infill_only_where_needed. This step trims the sparse infill,
|
||||||
// so it acts as an internal support. It maintains all other infill types intact.
|
// so it acts as an internal support. It maintains all other infill types intact.
|
||||||
|
@ -1890,6 +1893,58 @@ void PrintObject::discover_vertical_shells()
|
||||||
// PROFILE_OUTPUT(debug_out_path("discover_vertical_shells-profile.txt").c_str());
|
// PROFILE_OUTPUT(debug_out_path("discover_vertical_shells-profile.txt").c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void PrintObject::discover_shell_for_perimeters()
|
||||||
|
{
|
||||||
|
const size_t num_regions = this->num_printing_regions();
|
||||||
|
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||||
|
[this,num_regions](const tbb::blocked_range<size_t> &range){
|
||||||
|
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
|
||||||
|
Layer* layer = m_layers[idx_layer];
|
||||||
|
if (!layer->lower_layer)
|
||||||
|
continue;
|
||||||
|
Layer* lower_layer = layer->lower_layer;
|
||||||
|
|
||||||
|
ExPolygons perimeter_areas;
|
||||||
|
ExPolygons infill_areas;
|
||||||
|
float max_line_width = 0;
|
||||||
|
for (size_t region_id = 0; region_id < num_regions; ++region_id) {
|
||||||
|
LayerRegion* layerm = layer->m_regions[region_id];
|
||||||
|
Flow extflow = layerm->flow(frExternalPerimeter);
|
||||||
|
infill_areas.insert(infill_areas.end(), layerm->fill_expolygons.begin(), layerm->fill_expolygons.end());
|
||||||
|
max_line_width = std::max(max_line_width, 0.5f * float(extflow.scaled_width() + extflow.scaled_spacing()));
|
||||||
|
}
|
||||||
|
infill_areas = union_ex(infill_areas);
|
||||||
|
perimeter_areas = offset_ex(diff_ex(layer->lslices, infill_areas), max_line_width);
|
||||||
|
|
||||||
|
for (size_t region_id = 0; region_id < num_regions; ++region_id) {
|
||||||
|
LayerRegion* lower_layerm = lower_layer->m_regions[region_id];
|
||||||
|
|
||||||
|
ExPolygons new_perimeter_solid = intersection_ex(perimeter_areas, lower_layerm->fill_expolygons);
|
||||||
|
new_perimeter_solid.erase(std::remove_if(new_perimeter_solid.begin(), new_perimeter_solid.end(), [max_line_width](auto& expoly) {
|
||||||
|
return is_narrow_expolygon(expoly, 3 * max_line_width);
|
||||||
|
}), new_perimeter_solid.end());
|
||||||
|
if (new_perimeter_solid.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ExPolygons old_internal = to_expolygons(lower_layerm->fill_surfaces.filter_by_type(stInternal));
|
||||||
|
ExPolygons old_internal_void = to_expolygons(lower_layerm->fill_surfaces.filter_by_type(stInternalVoid));
|
||||||
|
ExPolygons old_internal_solid = to_expolygons(lower_layerm->fill_surfaces.filter_by_type(stInternalSolid));
|
||||||
|
|
||||||
|
lower_layerm->fill_surfaces.remove_types({ stInternal,stInternalVoid,stInternalSolid });
|
||||||
|
|
||||||
|
ExPolygons new_internal_solid = union_ex(old_internal_solid, new_perimeter_solid);
|
||||||
|
ExPolygons new_internal = diff_ex(old_internal, new_perimeter_solid);
|
||||||
|
ExPolygons new_internal_void = diff_ex(old_internal_void, new_perimeter_solid);
|
||||||
|
lower_layerm->fill_surfaces.append(new_internal, stInternal);
|
||||||
|
lower_layerm->fill_surfaces.append(new_internal_void, stInternalVoid);
|
||||||
|
lower_layerm->fill_surfaces.append(new_internal_solid, stInternalSolid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
// This method applies bridge flow to the first internal solid layer above sparse infill.
|
// This method applies bridge flow to the first internal solid layer above sparse infill.
|
||||||
// This method applies bridge flow to the first internal solid layer above sparse infill.
|
// This method applies bridge flow to the first internal solid layer above sparse infill.
|
||||||
void PrintObject::bridge_over_infill()
|
void PrintObject::bridge_over_infill()
|
||||||
|
@ -1910,11 +1965,11 @@ void PrintObject::bridge_over_infill()
|
||||||
, region(region)
|
, region(region)
|
||||||
, bridge_angle(bridge_angle)
|
, bridge_angle(bridge_angle)
|
||||||
{}
|
{}
|
||||||
const Surface *original_surface;
|
const Surface *original_surface; // 下方需要生成桥接的surface
|
||||||
int layer_index;
|
int layer_index; // 下方生成桥接的层号
|
||||||
Polygons new_polys;
|
Polygons new_polys; // 下方需要生成桥接的实心区域
|
||||||
const LayerRegion *region;
|
const LayerRegion *region; // 下方需要生成桥接的region,主要提供参数
|
||||||
double bridge_angle;
|
double bridge_angle; // 桥接方向
|
||||||
};
|
};
|
||||||
|
|
||||||
// 按层存放surface,存放着待桥接的信息
|
// 按层存放surface,存放着待桥接的信息
|
||||||
|
@ -1923,10 +1978,15 @@ void PrintObject::bridge_over_infill()
|
||||||
// SECTION to gather and filter surfaces for expanding, and then cluster them by layer
|
// SECTION to gather and filter surfaces for expanding, and then cluster them by layer
|
||||||
{
|
{
|
||||||
tbb::concurrent_vector<CandidateSurface> candidate_surfaces;
|
tbb::concurrent_vector<CandidateSurface> candidate_surfaces;
|
||||||
|
#if USE_TBB_IN_INFILL
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = static_cast<const PrintObject *>(this),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = static_cast<const PrintObject *>(this),
|
||||||
&candidate_surfaces](tbb::blocked_range<size_t> r) {
|
&candidate_surfaces](tbb::blocked_range<size_t> r) {
|
||||||
// 按层并行
|
// 按层并行
|
||||||
for (size_t lidx = r.begin(); lidx < r.end(); lidx++) {
|
for (size_t lidx = r.begin(); lidx < r.end(); lidx++) {
|
||||||
|
#else
|
||||||
|
auto po = static_cast<const PrintObject*>(this);
|
||||||
|
for(size_t lidx =0;lidx<this->layers().size();++lidx){
|
||||||
|
#endif
|
||||||
const Layer *layer = po->get_layer(lidx);
|
const Layer *layer = po->get_layer(lidx);
|
||||||
if (layer->lower_layer == nullptr) {
|
if (layer->lower_layer == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1973,6 +2033,7 @@ void PrintObject::bridge_over_infill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
worth_bridging = intersection(closing(worth_bridging, float(SCALED_EPSILON)), s->expolygon);
|
worth_bridging = intersection(closing(worth_bridging, float(SCALED_EPSILON)), s->expolygon);
|
||||||
|
// 对应哪个region下的那个surface需要生成桥接
|
||||||
candidate_surfaces.push_back(CandidateSurface(s, lidx, worth_bridging, region, 0));
|
candidate_surfaces.push_back(CandidateSurface(s, lidx, worth_bridging, region, 0));
|
||||||
|
|
||||||
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
#ifdef DEBUG_BRIDGE_OVER_INFILL
|
||||||
|
@ -1990,8 +2051,11 @@ void PrintObject::bridge_over_infill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if USE_TBB_IN_INFILL
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 按层重新存储
|
||||||
for (const CandidateSurface &c : candidate_surfaces) {
|
for (const CandidateSurface &c : candidate_surfaces) {
|
||||||
surfaces_by_layer[c.layer_index].push_back(c);
|
surfaces_by_layer[c.layer_index].push_back(c);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue