def sigmoid(x): return 1 / (1 + math.exp(-x)) def curvy_thickness(): gp_layer = init_grease_pencil() #VALUES line_spread = 35 #width of thickening. higher values take longer line_variation = 120 # contrast of the line deriv = .98 #derivative for the sigmoid function bias = .5 #bias for stroke weighting. normalize_strokes = True #normalize the stroke for stroke in np.array(gp_layer.active_frame.strokes.values()): #create curvature array curvature = np.array([.0]*len(stroke.points)) point_iter = -1 point_list = np.array(stroke.points.values()) for point in point_list: point_iter += 1 #itters over the points while getting the neighouring points position for angle calc for i in range(line_spread): if point_iter > 0 and point_iter < (len(point_list)-1):#skip first s = i+1 index_sel_pos = clamp(point_iter+s,len(point_list)-1,0) index_sel_neg = clamp(point_iter-s,len(point_list)-1,0) #makes neighbour points pos relative to main point p_1 = Vector(point_list[index_sel_pos].co) - point.co p_2 = Vector(point_list[index_sel_neg].co) - point.co dot = p_2.normalized().dot(p_1.normalized()) #adds affects linevariation angle = dot+deriv #.98 #divide by distance from neighouring position. angle = (angle*(line_variation/line_spread))/(Vector((p_1.lerp(p_2,bias))).length +1) # curvature[point_iter] += angle/line_spread # this method requires 3 points at least. copy curvature from 2nd last one to endpoints if len(point_list) > 3: pass curvature[0] = curvature[1] curvature[-1] = curvature[-2] else: curvature[0] = 0 curvature[-1] = 0 #put through sigmoid function and normalize strokes if needed curvature = np.array([sigmoid(float) for float in curvature]) if normalize_strokes: curvature *= .5/curvature.mean() curvature *= 2 point_iter = -1 for point in point_list: #apply curvature as line thickness point_iter += 1 point.pressure = curvature[point_iter]