ENH: set filler_angle of roof layers to interlace with bottom bridge

jira: STUDIO-10239
Change-Id: I8dfebb289b30293a39f9737073e992e97b4b46d4
This commit is contained in:
jiaxi.chen 2025-02-13 10:28:22 +08:00 committed by lane.wei
parent 547cfe75d0
commit aeba1ebfa2
3 changed files with 50 additions and 11 deletions

View File

@ -3922,8 +3922,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Interface pattern"); def->label = L("Interface pattern");
def->category = L("Support"); def->category = L("Support");
def->tooltip = L("Line pattern of support interface. " def->tooltip = L("Line pattern of support interface. "
"Default pattern for non-soluble support interface is Rectilinear, " "Default pattern for support interface is Rectilinear Interlaced");
"while default pattern for soluble support interface is Concentric");
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values(); def->enum_keys_map = &ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values();
def->enum_values.push_back("auto"); def->enum_values.push_back("auto");
def->enum_values.push_back("rectilinear"); def->enum_values.push_back("rectilinear");
@ -3975,7 +3974,7 @@ void PrintConfigDef::init_fff_params()
"a lot of material, strong style will make larger and stronger support structure and use more materials, " "a lot of material, strong style will make larger and stronger support structure and use more materials, "
"while hybrid style is the combination of slim tree and normal support with normal nodes " "while hybrid style is the combination of slim tree and normal support with normal nodes "
"under large flat overhangs. Organic style will produce more organic shaped tree structure and less interfaces which makes it easer to be removed. " "under large flat overhangs. Organic style will produce more organic shaped tree structure and less interfaces which makes it easer to be removed. "
"The default style is organic tree for most cases, and hybrid tree if adaptive layer height is enabled."); "The default style is organic tree for most cases, and hybrid tree if adaptive layer height or soluble interface is enabled.");
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialStyle>::get_enum_values(); def->enum_keys_map = &ConfigOptionEnum<SupportMaterialStyle>::get_enum_values();
def->enum_values.push_back("default"); def->enum_values.push_back("default");
def->enum_values.push_back("grid"); def->enum_values.push_back("grid");

View File

@ -116,12 +116,10 @@ struct SupportParameters {
this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase; this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase;
if (object_config.support_interface_pattern == smipGrid) if (object_config.support_interface_pattern == smipGrid)
this->contact_fill_pattern = ipGrid; this->contact_fill_pattern = ipGrid;
else if (object_config.support_interface_pattern == smipRectilinearInterlaced) else if (object_config.support_interface_pattern == smipRectilinearInterlaced || object_config.support_interface_pattern == smipAuto)
this->contact_fill_pattern = ipRectilinear; this->contact_fill_pattern = ipRectilinear;
else else
this->contact_fill_pattern = this->contact_fill_pattern = object_config.support_interface_pattern == smipConcentric ?
(object_config.support_interface_pattern == smipAuto && slicing_params.soluble_interface) ||
object_config.support_interface_pattern == smipConcentric ?
ipConcentric : ipConcentric :
(this->interface_density > 0.95 ? ipRectilinear : ipSupportBase); (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);

View File

@ -1549,8 +1549,6 @@ void TreeSupport::generate_toolpaths()
return; return;
BoundingBox bbox_object(Point(-scale_(1.), -scale_(1.0)), Point(scale_(1.), scale_(1.))); BoundingBox bbox_object(Point(-scale_(1.), -scale_(1.0)), Point(scale_(1.), scale_(1.)));
if (m_support_params.support_style == smsTreeHybrid && object_config.support_interface_pattern == smipAuto) m_support_params.contact_fill_pattern = ipRectilinear;
std::shared_ptr<Fill> filler_interface = std::shared_ptr<Fill>(Fill::new_from_type(m_support_params.contact_fill_pattern)); std::shared_ptr<Fill> filler_interface = std::shared_ptr<Fill>(Fill::new_from_type(m_support_params.contact_fill_pattern));
std::shared_ptr<Fill> filler_Roof1stLayer = std::shared_ptr<Fill>(Fill::new_from_type(ipRectilinear)); std::shared_ptr<Fill> filler_Roof1stLayer = std::shared_ptr<Fill>(Fill::new_from_type(ipRectilinear));
filler_interface->set_bounding_box(bbox_object); filler_interface->set_bounding_box(bbox_object);
@ -1602,6 +1600,26 @@ void TreeSupport::generate_toolpaths()
// Note: spacing means the separation between two lines as if they are tightly extruded // Note: spacing means the separation between two lines as if they are tightly extruded
filler_Roof1stLayer->spacing = roof_1st_layer_flow.spacing(); filler_Roof1stLayer->spacing = roof_1st_layer_flow.spacing();
auto interface_layer_above = m_object->get_support_layer(layer_id + m_support_params.num_top_interface_layers);
if (interface_layer_above) {
Layer *bridge_layer = m_object->get_layer_at_bottomz(interface_layer_above->print_z + object_config.support_top_z_distance.value, layer_height / 10.);
if (bridge_layer) {
for (size_t region_id = 0; region_id < bridge_layer->regions().size(); ++region_id) {
LayerRegion *layerm = bridge_layer->regions()[region_id];
bool find_bridge = false;
for (const auto surface : layerm->fill_surfaces.surfaces) {
if (surface.surface_type == stBottomBridge && overlaps(polys, surface.expolygon)) {
filler_Roof1stLayer->angle = surface.bridge_angle + (m_support_params.num_top_interface_layers - 1) * M_PI_2;
find_bridge - true;
break;
}
}
if (find_bridge) break;
}
}
}
// generate a perimeter first to support interface better // generate a perimeter first to support interface better
ExtrusionEntityCollection* temp_support_fills = new ExtrusionEntityCollection(); ExtrusionEntityCollection* temp_support_fills = new ExtrusionEntityCollection();
make_perimeter_and_infill(temp_support_fills->entities, poly, 1, roof_1st_layer_flow, erSupportTransition, make_perimeter_and_infill(temp_support_fills->entities, poly, 1, roof_1st_layer_flow, erSupportTransition,
@ -1625,8 +1643,32 @@ void TreeSupport::generate_toolpaths()
filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value); filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value);
fill_params.dont_sort = true; fill_params.dont_sort = true;
} }
if (m_object_config->support_interface_pattern == smipRectilinearInterlaced || m_object_config->support_interface_pattern == smipAuto) { if (m_support_params.contact_fill_pattern = ipRectilinear) {
filler_interface->layer_id = area_group.interface_id; bool find_bridge = false;
for (size_t i = 0; i < m_support_params.num_top_interface_layers; i++) {
auto cur_ts_layer = m_object->get_support_layer(layer_id + i);
if (cur_ts_layer == nullptr) break;
Layer *obj_layer = m_object->get_layer_at_bottomz(cur_ts_layer->print_z + object_config.support_top_z_distance.value, layer_height / 10.);
if (obj_layer) {
for (size_t region_id = 0; region_id < obj_layer->regions().size(); ++region_id) {
LayerRegion *layerm = obj_layer->regions()[region_id];
for (const auto surface : layerm->fill_surfaces.surfaces) {
if (surface.surface_type == stBottomBridge && overlaps(polys, surface.expolygon)) {
filler_interface->angle = surface.bridge_angle + (i + 1) * M_PI_2;
find_bridge = true;
break;
}
}
if (find_bridge) break;
}
}
if (find_bridge) break;
}
if (!find_bridge)
filler_interface->layer_id = area_group.interface_id;
else
filler_interface->layer_id = 0;
} }
fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, erSupportMaterialInterface, fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, erSupportMaterialInterface,