[docs]defgenerate_raft(slicer,raft_offset=10,distance_between_paths=10,direction="xy_diagonal",raft_layers=1,raft_layer_height=None):"""Creates a raft. Parameters ---------- slicer: :class:`compas_slicer.slicers.BaseSlicer` An instance of one of the compas_slicer.slicers.BaseSlicer classes. raft_offset: float Distance (in mm) that the raft should be offsetted from the first layer. Defaults to 10mm distance_between_paths: float Distance (in mm) between the printed lines of the raft. Defaults to 10mm direction: str x_axis: Create a raft aligned with the x_axis y_axis: Create a raft aligned with the y_axis xy_diagonal: Create a raft int the diagonal direction in the xy_plane raft_layers: int Number of raft layers to add. Defaults to 1 raft_layer_height: float Layer height of the raft layers. Defaults to same value as used in the slicer. """# check if a raft_layer_height is specified, if not, use the slicer.layer_height valueifnotraft_layer_height:raft_layer_height=slicer.layer_heightlogger.info("Generating raft")# find if slicer has vertical or horizontal layers, and select which paths are to be offset.ifisinstance(slicer.layers[0],compas_slicer.geometry.VerticalLayer):# Vertical layers# then find all paths that lie on the print platform and make them brim.paths_to_offset,_=slicer.find_vertical_layers_with_first_path_on_base()else:# Horizontal layers# then replace the first layer with a raft layer.paths_to_offset=slicer.layers[0].paths# get flat lists of points in bottom layerall_pts=[]forpathinpaths_to_offset:forptinpath.points:all_pts.append(pt)# get xy bounding box of bottom layer and create offsetbb_xy=bounding_box_xy(all_pts)bb_xy_offset=offset_polygon(bb_xy,-raft_offset)# bring points in the xy_offset to the correct heightforptinbb_xy_offset:pt[2]=slicer.layers[0].paths[0].points[0][2]# calculate x range, y range, and number of stepsx_range=abs(bb_xy_offset[0][0]-bb_xy_offset[1][0])y_range=abs(bb_xy_offset[0][1]-bb_xy_offset[3][1])# get maximum values of the bounding boxbb_max_x_right=bb_xy_offset[1][0]bb_max_y_top=bb_xy_offset[3][1]# get point in bottom left corner as raft start pointraft_start_pt=Point(bb_xy_offset[0][0],bb_xy_offset[0][1],bb_xy_offset[0][2])# create starting line for diagonal directionifdirection=="xy_diagonal":c=math.sqrt(2*(distance_between_paths**2))pt1=Point(raft_start_pt[0]+c,raft_start_pt[1],raft_start_pt[2])pt2=Point(pt1[0]-y_range,pt1[1]+y_range,pt1[2])line=Line(pt1,pt2)# move all points in the slicer up so that raft layers can be insertedfori,layerinenumerate(slicer.layers):forj,pathinenumerate(layer.paths):fork,ptinenumerate(path.points):slicer.layers[i].paths[j].points[k]=Point(pt[0],pt[1],pt[2]+(raft_layers)*raft_layer_height)foriinrange(raft_layers):iter=0raft_points=[]# create raft points depending on the chosen directionwhileiter<9999:# to avoid infinite while loop in case something is not correct# ===============# VERTICAL RAFT# ===============ifdirection=="y_axis":raft_pt1=Point(raft_start_pt[0]+iter*distance_between_paths,raft_start_pt[1],raft_start_pt[2]+i*raft_layer_height)raft_pt2=Point(raft_start_pt[0]+iter*distance_between_paths,raft_start_pt[1]+y_range,raft_start_pt[2]+i*raft_layer_height)ifraft_pt2[0]>bb_max_x_rightorraft_pt1[0]>bb_max_x_right:break# ===============# HORIZONTAL RAFT# ===============elifdirection=="x_axis":raft_pt1=Point(raft_start_pt[0],raft_start_pt[1]+iter*distance_between_paths,raft_start_pt[2]+i*raft_layer_height)raft_pt2=Point(raft_start_pt[0]+x_range,raft_start_pt[1]+iter*distance_between_paths,raft_start_pt[2]+i*raft_layer_height)ifraft_pt2[1]>bb_max_y_toporraft_pt1[1]>bb_max_y_top:break# ===============# DIAGONAL RAFT# ===============elifdirection=="xy_diagonal":# create offset of the initial diagonal lineoffset_l=offset_line(line,iter*distance_between_paths,Vector(0,0,-1))# get intersections for the initial diagonal line with the left and bottom of the bbint_left=intersection_line_line(offset_l,[bb_xy_offset[0],bb_xy_offset[3]])int_bottom=intersection_line_line(offset_l,[bb_xy_offset[0],bb_xy_offset[1]])# get the points at the intersectionsraft_pt1=Point(int_left[0][0],int_left[0][1],int_left[0][2]+i*raft_layer_height)raft_pt2=Point(int_bottom[0][0],int_bottom[0][1],int_bottom[0][2]+i*raft_layer_height)# if the intersection goes beyond the height of the left side of the bounding box:ifint_left[0][1]>bb_max_y_top:# create intersection with the top sideint_top=intersection_line_line(offset_l,[bb_xy_offset[3],bb_xy_offset[2]])raft_pt1=Point(int_top[0][0],int_top[0][1],int_top[0][2]+i*raft_layer_height)# if intersection goes beyond the length of the top side, breakifraft_pt1[0]>bb_max_x_right:break# if the intersection goes beyond the length of the bottom side of the bounding box:ifint_bottom[0][0]>bb_max_x_right:# create intersection with the right sideint_right=intersection_line_line(offset_l,[bb_xy_offset[1],bb_xy_offset[2]])raft_pt2=Point(int_right[0][0],int_right[0][1],int_right[0][2]+i*raft_layer_height)# if intersection goes beyond the height of the right side, breakifraft_pt2[1]>bb_xy_offset[2][1]:break# append to list alternatingifiter%2==0:raft_points.extend((raft_pt1,raft_pt2))else:raft_points.extend((raft_pt2,raft_pt1))iter+=1# create raft layerraft_layer=Layer([Path(raft_points,is_closed=False)])raft_layer.is_raft=True# insert raft layer in the correct position into the slicerslicer.layers.insert(i,raft_layer)