2024-12-20 06:44:50 +00:00
# include "../ClipperUtils.hpp"
# include "../ExPolygon.hpp"
# include "../ShortestPath.hpp"
# include "../Surface.hpp"
# include "FillLine.hpp"
namespace Slic3r {
void FillLine : : _fill_surface_single (
const FillParams & params ,
unsigned int thickness_layers ,
const std : : pair < float , Point > & direction ,
ExPolygon expolygon ,
Polylines & polylines_out )
{
// rotate polygons so that we can work with vertical lines here
2025-06-03 01:08:41 +00:00
//旋转多边形,这样我们就可以在这里处理垂直线
2024-12-20 06:44:50 +00:00
expolygon . rotate ( - direction . first ) ;
this - > _min_spacing = scale_ ( this - > spacing ) ;
assert ( params . density > 0.0001f & & params . density < = 1.f ) ;
this - > _line_spacing = coord_t ( coordf_t ( this - > _min_spacing ) / params . density ) ;
this - > _diagonal_distance = this - > _line_spacing * 2 ;
this - > _line_oscillation = this - > _line_spacing - this - > _min_spacing ; // only for Line infill
BoundingBox bounding_box = expolygon . contour . bounding_box ( ) ;
// define flow spacing according to requested density
2025-06-03 01:08:41 +00:00
//根据要求的密度定义流间距
2024-12-20 06:44:50 +00:00
if ( params . density > 0.9999f & & ! params . dont_adjust ) {
this - > _line_spacing = this - > _adjust_solid_spacing ( bounding_box . size ( ) ( 0 ) , this - > _line_spacing ) ;
this - > spacing = unscale < double > ( this - > _line_spacing ) ;
} else {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
2025-06-03 01:08:41 +00:00
//扩展边界框,使我们的图案与其他层对齐
//将参考点变换到旋转坐标系。
2024-12-20 06:44:50 +00:00
bounding_box . merge ( align_to_grid (
bounding_box . min ,
Point ( this - > _line_spacing , this - > _line_spacing ) ,
direction . second . rotated ( - direction . first ) ) ) ;
}
// generate the basic pattern
2025-06-03 01:08:41 +00:00
//生成基本模式
2024-12-20 06:44:50 +00:00
coord_t x_max = bounding_box . max ( 0 ) + SCALED_EPSILON ;
Lines lines ;
for ( coord_t x = bounding_box . min ( 0 ) ; x < = x_max ; x + = this - > _line_spacing )
lines . push_back ( this - > _line ( lines . size ( ) , x , bounding_box . min ( 1 ) , bounding_box . max ( 1 ) ) ) ;
// clip paths against a slightly larger expolygon, so that the first and last paths
// are kept even if the expolygon has vertical sides
// the minimum offset for preventing edge lines from being clipped is SCALED_EPSILON;
// however we use a larger offset to support expolygons with slightly skewed sides and
// not perfectly straight
//FIXME Vojtech: Update the intersecton function to work directly with lines.
2025-06-03 01:08:41 +00:00
//将路径剪切到稍大的expolygon上, 这样即使expolygon有垂直边, 也能保持第一条和最后一条路径, 防止边缘线被剪切的最小偏移量为SCALED_EPSILON;
//然而, 我们使用更大的偏移量来支持边略微倾斜且不完全笔直的expolygon
//FIXME Vojtech: 更新交集函数以直接处理线条。
2024-12-20 06:44:50 +00:00
Polylines polylines_src ;
polylines_src . reserve ( lines . size ( ) ) ;
for ( Lines : : const_iterator it = lines . begin ( ) ; it ! = lines . end ( ) ; + + it ) {
polylines_src . push_back ( Polyline ( ) ) ;
Points & pts = polylines_src . back ( ) . points ;
pts . reserve ( 2 ) ;
pts . push_back ( it - > a ) ;
pts . push_back ( it - > b ) ;
}
Polylines polylines = intersection_pl ( polylines_src , offset ( expolygon , scale_ ( 0.02 ) ) ) ;
// FIXME Vojtech: This is only performed for horizontal lines, not for the vertical lines!
2025-06-03 01:08:41 +00:00
//FIXME Vojtech: 这只适用于水平线, 不适用于垂直线!
2024-12-20 06:44:50 +00:00
const float INFILL_OVERLAP_OVER_SPACING = 0.3f ;
// How much to extend an infill path from expolygon outside?
2025-06-03 01:08:41 +00:00
//将填充路径从expolygon向外延伸多少?
2024-12-20 06:44:50 +00:00
coord_t extra = coord_t ( floor ( this - > _min_spacing * INFILL_OVERLAP_OVER_SPACING + 0.5f ) ) ;
for ( Polylines : : iterator it_polyline = polylines . begin ( ) ; it_polyline ! = polylines . end ( ) ; + + it_polyline ) {
Point * first_point = & it_polyline - > points . front ( ) ;
Point * last_point = & it_polyline - > points . back ( ) ;
if ( first_point - > y ( ) > last_point - > y ( ) )
std : : swap ( first_point , last_point ) ;
first_point - > y ( ) - = extra ;
last_point - > y ( ) + = extra ;
}
size_t n_polylines_out_old = polylines_out . size ( ) ;
// connect lines
2025-06-03 01:08:41 +00:00
if ( ! params . dont_connect ( ) & & ! polylines . empty ( ) ) { // prevent calling leftmost_point() on empty collections//防止对空集合调用left most_point( )
2024-12-20 06:44:50 +00:00
// offset the expolygon by max(min_spacing/2, extra)
ExPolygon expolygon_off ;
{
ExPolygons expolygons_off = offset_ex ( expolygon , this - > _min_spacing / 2 ) ;
if ( ! expolygons_off . empty ( ) ) {
// When expanding a polygon, the number of islands could only shrink. Therefore the offset_ex shall generate exactly one expanded island for one input island.
2025-06-03 01:08:41 +00:00
//展开多边形时, 岛的数量只能缩小。因此, offset_ex应为一个输入岛生成一个扩展岛。
2024-12-20 06:44:50 +00:00
assert ( expolygons_off . size ( ) = = 1 ) ;
std : : swap ( expolygon_off , expolygons_off . front ( ) ) ;
}
}
bool first = true ;
for ( Polyline & polyline : chain_polylines ( std : : move ( polylines ) ) ) {
if ( ! first ) {
// Try to connect the lines.
Points & pts_end = polylines_out . back ( ) . points ;
const Point & first_point = polyline . points . front ( ) ;
const Point & last_point = pts_end . back ( ) ;
// Distance in X, Y.
const Vector distance = last_point - first_point ;
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
2025-06-03 01:08:41 +00:00
//TODO: 我们还应该检查这两个点是否都在fill_boundary上, 以避免
//内部区域边界上的连接路径
2024-12-20 06:44:50 +00:00
if ( this - > _can_connect ( std : : abs ( distance ( 0 ) ) , std : : abs ( distance ( 1 ) ) ) & &
expolygon_off . contains ( Line ( last_point , first_point ) ) ) {
// Append the polyline.
pts_end . insert ( pts_end . end ( ) , polyline . points . begin ( ) , polyline . points . end ( ) ) ;
continue ;
}
}
// The lines cannot be connected.
2025-06-03 01:08:41 +00:00
//线路无法连接。
2024-12-20 06:44:50 +00:00
polylines_out . emplace_back ( std : : move ( polyline ) ) ;
first = false ;
}
}
// paths must be rotated back
2025-06-03 01:08:41 +00:00
//路径必须向后旋转
2024-12-20 06:44:50 +00:00
for ( Polylines : : iterator it = polylines_out . begin ( ) + n_polylines_out_old ; it ! = polylines_out . end ( ) ; + + it ) {
// No need to translate, the absolute position is irrelevant.
2025-06-03 01:08:41 +00:00
//无需翻译,绝对位置无关紧要。
2024-12-20 06:44:50 +00:00
// it->translate(- direction.second(0), - direction.second(1));
it - > rotate ( direction . first ) ;
}
}
} // namespace Slic3r