mirror of
				https://github.com/tonytins/CozyPixelStudio.git
				synced 2025-11-04 08:34:42 -05:00 
			
		
		
		
	More experiments I may or may not need
Trying to generate a polygon from the individual selected pixels
This commit is contained in:
		
							parent
							
								
									1e469ddf89
								
							
						
					
					
						commit
						d8c78331f0
					
				
					 4 changed files with 247 additions and 29 deletions
				
			
		| 
						 | 
					@ -84,11 +84,6 @@ _global_script_classes=[ {
 | 
				
			||||||
"language": "GDScript",
 | 
					"language": "GDScript",
 | 
				
			||||||
"path": "res://src/Classes/Project.gd"
 | 
					"path": "res://src/Classes/Project.gd"
 | 
				
			||||||
}, {
 | 
					}, {
 | 
				
			||||||
"base": "Reference",
 | 
					 | 
				
			||||||
"class": "Selection",
 | 
					 | 
				
			||||||
"language": "GDScript",
 | 
					 | 
				
			||||||
"path": "res://src/Classes/Selection.gd"
 | 
					 | 
				
			||||||
}, {
 | 
					 | 
				
			||||||
"base": "Polygon2D",
 | 
					"base": "Polygon2D",
 | 
				
			||||||
"class": "SelectionShape",
 | 
					"class": "SelectionShape",
 | 
				
			||||||
"language": "GDScript",
 | 
					"language": "GDScript",
 | 
				
			||||||
| 
						 | 
					@ -115,7 +110,6 @@ _global_script_class_icons={
 | 
				
			||||||
"PaletteColor": "",
 | 
					"PaletteColor": "",
 | 
				
			||||||
"Patterns": "",
 | 
					"Patterns": "",
 | 
				
			||||||
"Project": "",
 | 
					"Project": "",
 | 
				
			||||||
"Selection": "",
 | 
					 | 
				
			||||||
"SelectionShape": "",
 | 
					"SelectionShape": "",
 | 
				
			||||||
"SymmetryGuide": ""
 | 
					"SymmetryGuide": ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +0,0 @@
 | 
				
			||||||
class_name Selection extends Reference
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var selected_area := [] # Selected pixels for each selection
 | 
					 | 
				
			||||||
var borders : PoolVector2Array
 | 
					 | 
				
			||||||
var node : SelectionShape
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func _init(_node : SelectionShape) -> void:
 | 
					 | 
				
			||||||
	node = _node
 | 
					 | 
				
			||||||
	Global.canvas.add_child(node)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,6 @@ func _ready() -> void:
 | 
				
			||||||
	tween.start()
 | 
						tween.start()
 | 
				
			||||||
	_clear_image.create(1, 1, false, Image.FORMAT_RGBA8)
 | 
						_clear_image.create(1, 1, false, Image.FORMAT_RGBA8)
 | 
				
			||||||
	_clear_image.fill(Color(0, 0, 0, 0))
 | 
						_clear_image.fill(Color(0, 0, 0, 0))
 | 
				
			||||||
#	set_rect(Rect2(16, 20, 4, 4))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _offset_tween_completed(_object, _key) -> void:
 | 
					func _offset_tween_completed(_object, _key) -> void:
 | 
				
			||||||
| 
						 | 
					@ -57,17 +56,18 @@ func _draw() -> void:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !local_selected_pixels:
 | 
						if !local_selected_pixels:
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	var rect_pos := _selected_rect.position
 | 
					#	draw_polygon(Global.current_project.get_selection_polygon(), [Color(1, 1, 1, 0.5)])
 | 
				
			||||||
	var rect_end := _selected_rect.end
 | 
					#	var rect_pos := _selected_rect.position
 | 
				
			||||||
	draw_circle(rect_pos, 1, Color.gray)
 | 
					#	var rect_end := _selected_rect.end
 | 
				
			||||||
	draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_pos.y), 1, Color.gray)
 | 
					#	draw_circle(rect_pos, 1, Color.gray)
 | 
				
			||||||
	draw_circle(Vector2(rect_end.x, rect_pos.y), 1, Color.gray)
 | 
					#	draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_pos.y), 1, Color.gray)
 | 
				
			||||||
	draw_circle(Vector2(rect_end.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
 | 
					#	draw_circle(Vector2(rect_end.x, rect_pos.y), 1, Color.gray)
 | 
				
			||||||
	draw_circle(rect_end, 1, Color.gray)
 | 
					#	draw_circle(Vector2(rect_end.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
 | 
				
			||||||
	draw_circle(Vector2(rect_end.x, rect_end.y), 1, Color.gray)
 | 
					#	draw_circle(rect_end, 1, Color.gray)
 | 
				
			||||||
	draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_end.y), 1, Color.gray)
 | 
					#	draw_circle(Vector2(rect_end.x, rect_end.y), 1, Color.gray)
 | 
				
			||||||
	draw_circle(Vector2(rect_pos.x, rect_end.y), 1, Color.gray)
 | 
					#	draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_end.y), 1, Color.gray)
 | 
				
			||||||
	draw_circle(Vector2(rect_pos.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
 | 
					#	draw_circle(Vector2(rect_pos.x, rect_end.y), 1, Color.gray)
 | 
				
			||||||
 | 
					#	draw_circle(Vector2(rect_pos.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _move_pixel:
 | 
						if _move_pixel:
 | 
				
			||||||
		draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5))
 | 
							draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5))
 | 
				
			||||||
| 
						 | 
					@ -143,6 +143,9 @@ func _local_selected_pixels_changed(value : Array) -> void:
 | 
				
			||||||
		else:
 | 
							else:
 | 
				
			||||||
			Global.current_project.selected_pixels.append(pixel)
 | 
								Global.current_project.selected_pixels.append(pixel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#	if value:
 | 
				
			||||||
 | 
					#		Global.canvas.get_node("Selection").generate_polygons()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func has_point(position : Vector2) -> bool:
 | 
					func has_point(position : Vector2) -> bool:
 | 
				
			||||||
	return Geometry.is_point_in_polygon(position, polygon)
 | 
						return Geometry.is_point_in_polygon(position, polygon)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										232
									
								
								src/UI/Canvas/Selection.gd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								src/UI/Canvas/Selection.gd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,232 @@
 | 
				
			||||||
 | 
					extends Node2D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SelectionPolygon:
 | 
				
			||||||
 | 
					#	var project : Project
 | 
				
			||||||
 | 
						var border := PoolVector2Array()
 | 
				
			||||||
 | 
						var rect_outline : Rect2
 | 
				
			||||||
 | 
						var rects := [] # Array of Rect2s
 | 
				
			||||||
 | 
						var selected_pixels := [] # Array of Vector2s - the selected pixels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var line_offset := Vector2.ZERO setget _offset_changed
 | 
				
			||||||
 | 
					var tween : Tween
 | 
				
			||||||
 | 
					var selection_polygons := [] # Array of SelectionPolygons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _ready() -> void:
 | 
				
			||||||
 | 
						tween = Tween.new()
 | 
				
			||||||
 | 
						tween.connect("tween_completed", self, "_offset_tween_completed")
 | 
				
			||||||
 | 
						add_child(tween)
 | 
				
			||||||
 | 
						tween.interpolate_property(self, "line_offset", Vector2.ZERO, Vector2(2, 2), 1)
 | 
				
			||||||
 | 
						tween.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func generate_polygons():
 | 
				
			||||||
 | 
					#	selection_polygons.clear()
 | 
				
			||||||
 | 
					#	selection_polygons.append(SelectionPolygon.new())
 | 
				
			||||||
 | 
					#	for pixel in Global.current_project.selected_pixels:
 | 
				
			||||||
 | 
					#		var current_polygon : SelectionPolygon = selection_polygons[0]
 | 
				
			||||||
 | 
					#		var rect = Rect2(pixel, Vector2.ONE)
 | 
				
			||||||
 | 
					#		var pixel_border = get_rect_border(rect)
 | 
				
			||||||
 | 
					#		var arr = Geometry.merge_polygons_2d(pixel_border, current_polygon.border)
 | 
				
			||||||
 | 
					##		print("Arr ", arr)
 | 
				
			||||||
 | 
					#		if arr.size() == 1: # if the selections intersect
 | 
				
			||||||
 | 
					##			current_polygon.rects.append(rect)
 | 
				
			||||||
 | 
					#			current_polygon.rect_outline.merge(rect)
 | 
				
			||||||
 | 
					#			current_polygon.border = arr[0]
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#	return
 | 
				
			||||||
 | 
						var selected_pixels_copy := Global.current_project.selected_pixels.duplicate()
 | 
				
			||||||
 | 
						var rects := []
 | 
				
			||||||
 | 
						while selected_pixels_copy.size() > 0:
 | 
				
			||||||
 | 
							var rect : Rect2 = generate_rect(selected_pixels_copy)
 | 
				
			||||||
 | 
							print("!!!")
 | 
				
			||||||
 | 
							if !rect:
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							for pixel in Global.current_project.selected_pixels:
 | 
				
			||||||
 | 
								if rect.has_point(pixel):
 | 
				
			||||||
 | 
					#				print("POINT")
 | 
				
			||||||
 | 
									selected_pixels_copy.erase(pixel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rects.append(rect)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						print(rects)
 | 
				
			||||||
 | 
					#	print("e ", selected_pixels_copy)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !rects:
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
					#	var polygons := [SelectionPolygon.new()]
 | 
				
			||||||
 | 
						selection_polygons.clear()
 | 
				
			||||||
 | 
						var polygons := [SelectionPolygon.new()]
 | 
				
			||||||
 | 
						var curr_polyg := 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if rects.size() == 1:
 | 
				
			||||||
 | 
							polygons[0].rects.append(rects[0])
 | 
				
			||||||
 | 
							polygons[0].rect_outline = rects[0]
 | 
				
			||||||
 | 
							polygons[0].selected_pixels = Global.current_project.selected_pixels.duplicate()
 | 
				
			||||||
 | 
							var border : PoolVector2Array = get_rect_border(rects[0])
 | 
				
			||||||
 | 
							polygons[0].border = border
 | 
				
			||||||
 | 
							selection_polygons = polygons
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i in rects.size():
 | 
				
			||||||
 | 
							var current_polygon : SelectionPolygon = polygons[curr_polyg]
 | 
				
			||||||
 | 
							var rect : Rect2 = rects[i]
 | 
				
			||||||
 | 
							var outlines : PoolVector2Array = get_rect_border(rect)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#		var rect_prev : Rect2 = rects[i - 1]
 | 
				
			||||||
 | 
					#		var outlines_prev : PoolVector2Array = get_rect_border(rect_prev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var arr = Geometry.merge_polygons_2d(outlines, current_polygon.border)
 | 
				
			||||||
 | 
							print("Arr ", arr)
 | 
				
			||||||
 | 
							if arr.size() == 1: # if the selections intersect
 | 
				
			||||||
 | 
								current_polygon.rects.append(rect)
 | 
				
			||||||
 | 
					#			if not rect_prev in current_polygon.rects:
 | 
				
			||||||
 | 
					#				current_polygon.rects.append(rect_prev)
 | 
				
			||||||
 | 
								current_polygon.rect_outline.merge(rect)
 | 
				
			||||||
 | 
								current_polygon.border = arr[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						selection_polygons = polygons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func generate_rect(pixels : Array) -> Rect2:
 | 
				
			||||||
 | 
						if !pixels:
 | 
				
			||||||
 | 
							return Rect2()
 | 
				
			||||||
 | 
						var rect := Rect2()
 | 
				
			||||||
 | 
						rect.position = pixels[0]
 | 
				
			||||||
 | 
						var reached_bottom := false
 | 
				
			||||||
 | 
						var bottom_right_corner
 | 
				
			||||||
 | 
						var p = pixels[0]
 | 
				
			||||||
 | 
						while p + Vector2.DOWN in pixels:
 | 
				
			||||||
 | 
							p += Vector2.DOWN
 | 
				
			||||||
 | 
					#	while p + Vector2.RIGHT in pixels:
 | 
				
			||||||
 | 
					#		p += Vector2.RIGHT
 | 
				
			||||||
 | 
						bottom_right_corner = p
 | 
				
			||||||
 | 
					#	for p in pixels:
 | 
				
			||||||
 | 
					#		if p + Vector2.DOWN in pixels:
 | 
				
			||||||
 | 
					#			continue
 | 
				
			||||||
 | 
					#		reached_bottom = true
 | 
				
			||||||
 | 
					#		if p + Vector2.RIGHT in pixels:
 | 
				
			||||||
 | 
					#			continue
 | 
				
			||||||
 | 
					#		if reached_bottom and !bottom_right_corner:
 | 
				
			||||||
 | 
					#			bottom_right_corner = p
 | 
				
			||||||
 | 
						rect.end = bottom_right_corner + Vector2.ONE
 | 
				
			||||||
 | 
						return rect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func get_rect_border(rect : Rect2) -> PoolVector2Array:
 | 
				
			||||||
 | 
						var border := PoolVector2Array()
 | 
				
			||||||
 | 
						border.append(rect.position)
 | 
				
			||||||
 | 
						border.append(Vector2(rect.end.x, rect.position.y))
 | 
				
			||||||
 | 
						border.append(rect.end)
 | 
				
			||||||
 | 
						border.append(Vector2(rect.position.x, rect.end.y))
 | 
				
			||||||
 | 
						return border
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _offset_tween_completed(_object, _key) -> void:
 | 
				
			||||||
 | 
						self.line_offset = Vector2.ZERO
 | 
				
			||||||
 | 
						tween.interpolate_property(self, "line_offset", Vector2.ZERO, Vector2(2, 2), 1)
 | 
				
			||||||
 | 
						tween.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _offset_changed(value : Vector2) -> void:
 | 
				
			||||||
 | 
						line_offset = value
 | 
				
			||||||
 | 
						update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _draw() -> void:
 | 
				
			||||||
 | 
						for polygon in selection_polygons:
 | 
				
			||||||
 | 
							var points : PoolVector2Array = polygon.border
 | 
				
			||||||
 | 
					#		print(points)
 | 
				
			||||||
 | 
							for i in range(1, points.size() + 1):
 | 
				
			||||||
 | 
								var point0 = points[i - 1]
 | 
				
			||||||
 | 
								var point1
 | 
				
			||||||
 | 
								if i >= points.size():
 | 
				
			||||||
 | 
									point1 = points[0]
 | 
				
			||||||
 | 
								else:
 | 
				
			||||||
 | 
									point1 = points[i]
 | 
				
			||||||
 | 
								var start_x = min(point0.x, point1.x)
 | 
				
			||||||
 | 
								var start_y = min(point0.y, point1.y)
 | 
				
			||||||
 | 
								var end_x = max(point0.x, point1.x)
 | 
				
			||||||
 | 
								var end_y = max(point0.y, point1.y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var start := Vector2(start_x, start_y)
 | 
				
			||||||
 | 
								var end := Vector2(end_x, end_y)
 | 
				
			||||||
 | 
								draw_dashed_line(start, end, Color.white, Color.black, 1.0, 1.0, false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !polygon.selected_pixels:
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
					#		draw_polygon(Global.current_project.get_selection_polygon(), [Color(1, 1, 1, 0.5)])
 | 
				
			||||||
 | 
						#	var rect_pos := _selected_rect.position
 | 
				
			||||||
 | 
						#	var rect_end := _selected_rect.end
 | 
				
			||||||
 | 
						#	draw_circle(rect_pos, 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_pos.y), 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2(rect_end.x, rect_pos.y), 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2(rect_end.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(rect_end, 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2(rect_end.x, rect_end.y), 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_end.y), 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2(rect_pos.x, rect_end.y), 1, Color.gray)
 | 
				
			||||||
 | 
						#	draw_circle(Vector2(rect_pos.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#		if _move_pixel:
 | 
				
			||||||
 | 
					#			draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Taken and modified from https://github.com/juddrgledhill/godot-dashed-line
 | 
				
			||||||
 | 
					func draw_dashed_line(from : Vector2, to : Vector2, color : Color, color2 : Color, width := 1.0, dash_length := 1.0, cap_end := false, antialiased := false) -> void:
 | 
				
			||||||
 | 
						var length = (to - from).length()
 | 
				
			||||||
 | 
						var normal = (to - from).normalized()
 | 
				
			||||||
 | 
						var dash_step = normal * dash_length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var horizontal : bool = from.y == to.y
 | 
				
			||||||
 | 
						var _offset : Vector2
 | 
				
			||||||
 | 
						if horizontal:
 | 
				
			||||||
 | 
							_offset = Vector2(line_offset.x, 0)
 | 
				
			||||||
 | 
						else:
 | 
				
			||||||
 | 
							_offset = Vector2(0, line_offset.y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if length < dash_length: # not long enough to dash
 | 
				
			||||||
 | 
							draw_line(from, to, color, width, antialiased)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						else:
 | 
				
			||||||
 | 
							var draw_flag = true
 | 
				
			||||||
 | 
							var segment_start = from
 | 
				
			||||||
 | 
							var steps = length/dash_length
 | 
				
			||||||
 | 
							for _start_length in range(0, steps + 1):
 | 
				
			||||||
 | 
								var segment_end = segment_start + dash_step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var start = segment_start + _offset
 | 
				
			||||||
 | 
								start.x = min(start.x, to.x)
 | 
				
			||||||
 | 
								start.y = min(start.y, to.y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var end = segment_end + _offset
 | 
				
			||||||
 | 
								end.x = min(end.x, to.x)
 | 
				
			||||||
 | 
								end.y = min(end.y, to.y)
 | 
				
			||||||
 | 
								if draw_flag:
 | 
				
			||||||
 | 
									draw_line(start, end, color, width, antialiased)
 | 
				
			||||||
 | 
								else:
 | 
				
			||||||
 | 
									draw_line(start, end, color2, width, antialiased)
 | 
				
			||||||
 | 
									if _offset.length() < 1:
 | 
				
			||||||
 | 
										draw_line(from, from + _offset, color2, width, antialiased)
 | 
				
			||||||
 | 
									else:
 | 
				
			||||||
 | 
										var from_offseted : Vector2 = from + _offset
 | 
				
			||||||
 | 
										var halfway_point : Vector2 = from_offseted
 | 
				
			||||||
 | 
										if horizontal:
 | 
				
			||||||
 | 
											halfway_point += Vector2.LEFT
 | 
				
			||||||
 | 
										else:
 | 
				
			||||||
 | 
											halfway_point += Vector2.UP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										from_offseted.x = min(from_offseted.x, to.x)
 | 
				
			||||||
 | 
										from_offseted.y = min(from_offseted.y, to.y)
 | 
				
			||||||
 | 
										draw_line(halfway_point, from_offseted, color2, width, antialiased)
 | 
				
			||||||
 | 
										draw_line(from, halfway_point, color, width, antialiased)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								segment_start = segment_end
 | 
				
			||||||
 | 
								draw_flag = !draw_flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if cap_end:
 | 
				
			||||||
 | 
								draw_line(segment_start, to, color, width, antialiased)
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue