Suggestion: Expanding Fill Tool (Paintbucket) Functionality

Hi! I have an idea for the paint bucket tool that could greatly increase the workflow speed in Synfig; filling in an outline consisting of multiple layers:

Currently, according to wiki.synfig.org/wiki/Doc:How_Do_ … outline.3F, you need to “Create a region with the same number of ducks, and manually link each duck. If you want a region that depends on multiple outline layers, this is really your only choice for now.”

It would be great if clicking on an empty space could fill in the space enclosed by all the nearby Blines with a region.

Then, it would count how many vertices exist on all the surrounding Blines, and create a duplicate region to match (and automatically link the ducks).

The user simply needs to make sure that a vertex exists on every corner prior to using the paint bucket tool!

Coloring would be a breeze, just like using the paint bucket tool in MS Paint. This would work in synergy with the import function to bring in inked svg files. Ink in your favorite program, color in synfig. You don’t have to worry about creating so many closed paths for the nuances of animation; just make something that looks good and bring it into Synfig!

I would be willing to try developing the code for this functionality, but If I mainly have experience with Java and don’t know much about the program APIs, would I be in over my head?

It’s not the program’s API knowledge what stops you to code that. You can start by doing a flow diagram with the needed steps to perform a region fill with the corresponding vertices of the surrounding splines.

In my opinion the click and fill would be extremely difficult to achieve and the results from the computer might be different from what the user want in many cases. I think that the “select and fill” would be the best approaching, since you limit the number of vertices to consider by the previous selection. Even with that, you can have alternative solutions for the same vertices that should be offered to the user to finish the fill state.
-G

That does sound very feature-rich and easier to code.
As for the alternative solutions, I was really thinking that copying the vertices from the blines exactly to the region before linking them would present the proper results.
I could try adding it.

Thanks!
-G

I have the same idea before, but never to sit down and look into the code. The fill will really nice feature, since the “nature” procedure of drawing a cartoon: sketching shape, cleaning up and inking (Outline Layer), and then fill color(Region Layer). I have some ideas regarding this fill tool, hope I can manage my time to write them down and make some mockup.

And in fact, Synfig Studio has this kind of “fill” tool available already.

So Synfig has this already? I know Inkscape does, and that’s what inspired me to make this comment.

The fill that jcome refers to basically just changes the colour of an existing region. What you’re talking about is to define a new region based on intersections of lines in separate layers. It’s an excellent feature, and one I’ve wished for in the past too.

It’s going to be tricky to try to get Synfig to recognize those intersections, But Genete’s suggestion on “select and fill” sounds very doable. After playing around with linking up the regions manually, I learned about the tricky nature of linking vertices, especially end vertices with non-end vertices, and came up with an algorithm that could be implemented:

Have the user select the vertices that they want to define the region, then supply a right-click option to create a linked region from the vertex selection. A dialogue would pop up showing a picture of the vertices with a number over each one, and the user would specify the order in which the vertices are to be chained together. The region is created with identical vertices, linked up appropriately. In the end, the user might just need to add a couple of extra vertices at some junctions to obtain the desired effect.

I have been looking into the source code, but it seems I need to study it a bit more to understand what tools I can use to create dialogues, get and set the state of a given vertex, etc.

We have Fill Last Stroke option for Draw Tool, I tried to figure out if we can enhance it to make it a standalone fill tool, which can fill all (Advanced) Outline instead of Last Stroke, but I didn’t manage it happen.

/synfig-studio/src/gui/states/state_draw.cpp

Smach::event_result
StateDraw_Context::fill_last_stroke_and_unselect_other_layers()
{
	if(!last_stroke)
		return Smach::RESULT_OK;

	synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Fill Stroke"));

	Layer::Handle layer;

	get_canvas_interface()->auto_export(last_stroke);

	synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL);

	Canvas::Handle canvas(get_canvas_view()->get_canvas());
	int depth(0);

	layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
	if(layer)
	{
		depth=layer->get_depth();
		canvas=layer->get_canvas();
	}

	get_canvas_interface()->get_selection_manager()->clear_selected_layers();
	layer=get_canvas_interface()->add_layer_to("region", canvas, depth);
	if (!layer) return Smach::RESULT_ERROR;
	layer->set_description(last_stroke_id + _(" Region"));

	synfigapp::Action::Handle action(synfigapp::Action::create("LayerParamConnect"));

	assert(action);

	action->set_param("canvas",get_canvas());
	action->set_param("canvas_interface",get_canvas_interface());
	action->set_param("layer",layer);
	if(!action->set_param("param",String("bline")))
		synfig::error("LayerParamConnect didn't like \"param\"");
	if(!action->set_param("value_node",ValueNode::Handle(last_stroke)))
		synfig::error("LayerParamConnect didn't like \"value_node\"");

	if(!get_canvas_interface()->get_instance()->perform_action(action))
	{
		get_canvas_view()->get_ui_interface()->error(_("Unable to create Region layer"));
		group.cancel();
		return Smach::RESULT_OK;
	}
	get_canvas_view()->get_selection_manager()->set_selected_layer(layer);
	return Smach::RESULT_OK;
}

void
StateDraw_Context::fill_last_stroke()
{
	if(!last_stroke)
		return;

	synfigapp::SelectionManager::LayerList layer_list = get_canvas_view()->get_selection_manager()->get_selected_layers();
	fill_last_stroke_and_unselect_other_layers();
	get_canvas_view()->get_selection_manager()->set_selected_layers(layer_list);
}

Yu, the code you show is to fill the last stroke and possibly can be reused to create a “fill this spline” action. But the suggested feature is to fill an area shared by several splines and use some vertices from one spline and other vertices from other spline.
So what it’s needed to research is how to access to the selected value nodes (vertices) in the right order and then create a region based on that selection.

The formulation of the problem might be:

Say we have a set of vertices scattered in the plane. I want the computer to return me those unordered vertices but ordered in a way that they are connected one by one but the region that it forms doesn’t cross itself.

That’s a geometrical problem but is needed to make possible the feature “select and fill”.

Also there is the problems of the tangents, but just linking them in the right way will solve the problem.

This might help: wiki.synfig.org/wiki/Sewing_Blines
-G