Skip to content

Commit 5cb8a6c

Browse files
Added area fill mode where regions from the merging of all layers is filled (#1258)
* Allow Area sampling choice between cel and frame * Use checkbox * typo * formatting * Make _sample_masks a private variable to fix linter error --------- Co-authored-by: Emmanouil Papadeas <[email protected]>
1 parent a23f1fa commit 5cb8a6c

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

src/Tools/DesignTools/Bucket.gd

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ var _pattern: Patterns.Pattern
1313
var _tolerance := 0.003
1414
var _fill_area: int = FillArea.AREA
1515
var _fill_with: int = FillWith.COLOR
16+
var _fill_merged_area := false ## Fill regions from the merging of all layers
1617
var _offset_x := 0
1718
var _offset_y := 0
1819
## Working array used as buffer for segments while flooding
1920
var _allegro_flood_segments: Array[Segment]
2021
## Results array per image while flooding
2122
var _allegro_image_segments: Array[Segment]
23+
## Used for _fill_merged_area = true
24+
var _sample_masks: Dictionary[Frame, Image] = {}
2225

2326

2427
class Segment:
@@ -59,8 +62,15 @@ func _on_FillAreaOptions_item_selected(index: int) -> void:
5962
save_config()
6063

6164

65+
func _on_merge_area_options_toggled(toggled_on: bool) -> void:
66+
_fill_merged_area = toggled_on
67+
update_config()
68+
save_config()
69+
70+
6271
func _select_fill_area_optionbutton() -> void:
6372
$FillAreaOptions.selected = _fill_area
73+
$MergeAreaOptions.visible = _fill_area == FillArea.AREA
6474
$ToleranceSlider.visible = (_fill_area != FillArea.SELECTION)
6575

6676

@@ -103,10 +113,16 @@ func _on_PatternOffsetY_value_changed(value: float) -> void:
103113

104114
func get_config() -> Dictionary:
105115
if !_pattern:
106-
return {"fill_area": _fill_area, "fill_with": _fill_with, "tolerance": _tolerance}
116+
return {
117+
"fill_area": _fill_area,
118+
"fill_merged_area": _fill_merged_area,
119+
"fill_with": _fill_with,
120+
"tolerance": _tolerance
121+
}
107122
return {
108123
"pattern_index": _pattern.index,
109124
"fill_area": _fill_area,
125+
"fill_merged_area": _fill_merged_area,
110126
"fill_with": _fill_with,
111127
"tolerance": _tolerance,
112128
"offset_x": _offset_x,
@@ -119,6 +135,7 @@ func set_config(config: Dictionary) -> void:
119135
var index = config.get("pattern_index", _pattern.index)
120136
_pattern = Global.patterns_popup.get_pattern(index)
121137
_fill_area = config.get("fill_area", _fill_area)
138+
_fill_merged_area = config.get("fill_merged_area", _fill_merged_area)
122139
_fill_with = config.get("fill_with", _fill_with)
123140
_tolerance = config.get("tolerance", _tolerance)
124141
_offset_x = config.get("offset_x", _offset_x)
@@ -133,6 +150,7 @@ func update_config() -> void:
133150
$FillPattern.visible = _fill_with == FillWith.PATTERN
134151
$FillPattern/OffsetX.value = _offset_x
135152
$FillPattern/OffsetY.value = _offset_y
153+
$MergeAreaOptions.button_pressed = _fill_merged_area
136154

137155

138156
func update_pattern() -> void:
@@ -163,6 +181,18 @@ func draw_start(pos: Vector2i) -> void:
163181
return
164182
if not Global.current_project.can_pixel_get_drawn(pos):
165183
return
184+
if _fill_merged_area and _fill_area == FillArea.AREA:
185+
var project := Global.current_project
186+
for frame_layer: Array in project.selected_cels:
187+
if project.frames[frame_layer[0]].cels[frame_layer[1]] is PixelCel:
188+
var frame := project.frames[frame_layer[0]]
189+
if not _sample_masks.has(frame):
190+
var mask := Image.create(
191+
project.size.x, project.size.y, false, Image.FORMAT_RGBA8
192+
)
193+
mask.fill(Color(0, 0, 0, 0))
194+
DrawingAlgos.blend_layers(mask, frame)
195+
_sample_masks[frame] = mask
166196
fill(pos)
167197

168198

@@ -183,6 +213,7 @@ func draw_end(pos: Vector2i) -> void:
183213
super.draw_end(pos)
184214
if _picking_color:
185215
return
216+
_sample_masks.clear()
186217
commit_undo()
187218

188219

@@ -343,11 +374,14 @@ func _flood_fill(pos: Vector2i) -> void:
343374
)
344375
return
345376

346-
var images := _get_selected_draw_images()
347-
for image in images:
377+
var cels = _get_selected_draw_cels()
378+
for cel: PixelCel in cels:
379+
var image: ImageExtended = cel.image
348380
if Tools.check_alpha_lock(image, pos):
349381
continue
350382
var color: Color = image.get_pixelv(pos)
383+
if _fill_merged_area:
384+
color = _sample_masks.get(cel.get_frame(project), cel.image).get_pixelv(pos)
351385
if _fill_with == FillWith.COLOR or _pattern == null:
352386
# end early if we are filling with the same color
353387
if tool_slot.color.is_equal_approx(color):
@@ -360,7 +394,12 @@ func _flood_fill(pos: Vector2i) -> void:
360394
# init flood data structures
361395
_allegro_flood_segments = []
362396
_allegro_image_segments = []
363-
_compute_segments_for_image(pos, project, image, color)
397+
_compute_segments_for_image(
398+
pos,
399+
project,
400+
image if !_fill_merged_area else _sample_masks.get(cel.get_frame(project), cel.image),
401+
color
402+
)
364403
# now actually color the image: since we have already checked a few things for the points
365404
# we'll process here, we're going to skip a bunch of safety checks to speed things up.
366405
_color_segments(image)

src/Tools/DesignTools/Bucket.tscn

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ mouse_default_cursor_shape = 2
4141
selected = 0
4242
item_count = 3
4343
popup/item_0/text = "Similar area"
44+
popup/item_0/id = 0
4445
popup/item_1/text = "Similar colors"
4546
popup/item_1/id = 1
4647
popup/item_2/text = "Whole selection"
4748
popup/item_2/id = 2
4849

49-
[node name="ToleranceSlider" type="TextureProgressBar" parent="." index="4"]
50+
[node name="MergeAreaOptions" type="CheckBox" parent="." index="4"]
51+
layout_mode = 2
52+
text = "Fill regions from the merging of all layers"
53+
autowrap_mode = 3
54+
55+
[node name="ToleranceSlider" type="TextureProgressBar" parent="." index="5"]
5056
custom_minimum_size = Vector2(32, 24)
5157
layout_mode = 2
5258
focus_mode = 2
@@ -61,22 +67,23 @@ stretch_margin_bottom = 3
6167
script = ExtResource("4_1pngp")
6268
prefix = "Tolerance:"
6369

64-
[node name="FillWith" type="Label" parent="." index="5"]
70+
[node name="FillWith" type="Label" parent="." index="6"]
6571
layout_mode = 2
6672
size_flags_horizontal = 3
6773
text = "Fill with:"
6874

69-
[node name="FillWithOptions" type="OptionButton" parent="." index="6"]
75+
[node name="FillWithOptions" type="OptionButton" parent="." index="7"]
7076
layout_mode = 2
7177
size_flags_horizontal = 3
7278
mouse_default_cursor_shape = 2
7379
selected = 0
7480
item_count = 2
7581
popup/item_0/text = "Selected color"
82+
popup/item_0/id = 0
7683
popup/item_1/text = "Pattern"
7784
popup/item_1/id = 1
7885

79-
[node name="FillPattern" type="VBoxContainer" parent="." index="7"]
86+
[node name="FillPattern" type="VBoxContainer" parent="." index="8"]
8087
visible = false
8188
layout_mode = 2
8289
size_flags_horizontal = 3
@@ -109,6 +116,7 @@ layout_mode = 2
109116
prefix = "Offset Y:"
110117

111118
[connection signal="item_selected" from="FillAreaOptions" to="." method="_on_FillAreaOptions_item_selected"]
119+
[connection signal="toggled" from="MergeAreaOptions" to="." method="_on_merge_area_options_toggled"]
112120
[connection signal="value_changed" from="ToleranceSlider" to="." method="_on_tolerance_slider_value_changed"]
113121
[connection signal="item_selected" from="FillWithOptions" to="." method="_on_FillWithOptions_item_selected"]
114122
[connection signal="pressed" from="FillPattern/Type" to="." method="_on_PatternType_pressed"]

0 commit comments

Comments
 (0)