add undo action for bucket fill
This commit is contained in:
@@ -1342,7 +1342,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
||||
*/
|
||||
}
|
||||
|
||||
void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, std::map<int, std::unique_ptr<bool[]>>& plane_mask,
|
||||
void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, FloodData& plane_data,
|
||||
float threshold, glm::vec4 dest_color, std::unique_ptr<glm::vec4>& source_color)
|
||||
{
|
||||
struct adj_t
|
||||
@@ -1365,12 +1365,19 @@ void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, std::
|
||||
LOG("flood_fill plane %d", plane);
|
||||
|
||||
auto& rtt = m_layers[layer]->m_rtt[plane];
|
||||
auto sz = glm::ivec2(rtt.getWidth(), rtt.getHeight());
|
||||
auto rgb = reinterpret_cast<glm::u8vec4*>(m_layers[layer]->m_rtt[plane].readTextureData());
|
||||
auto sz = rtt.getSize();
|
||||
|
||||
if (plane_mask.find(plane) == plane_mask.end())
|
||||
plane_mask.insert({ plane, std::make_unique<bool[]>((size_t)sz.x * sz.y) });
|
||||
auto& mask = plane_mask[plane];
|
||||
if (!plane_data.mask[plane])
|
||||
{
|
||||
plane_data.mask[plane] = std::make_unique<bool[]>((size_t)sz.x * sz.y);
|
||||
plane_data.rgb[plane] = std::unique_ptr<glm::u8vec4[]>(
|
||||
reinterpret_cast<glm::u8vec4*>(m_layers[layer]->m_rtt[plane].readTextureData()));
|
||||
plane_data.bb[plane] = { sz.x, sz.y, 0, 0 };
|
||||
plane_data.dirty[plane] = false;
|
||||
plane_data.layer = m_layers[layer];
|
||||
}
|
||||
auto& mask = plane_data.mask[plane];
|
||||
auto& rgb = plane_data.rgb[plane];
|
||||
|
||||
if (!source_color)
|
||||
source_color = std::make_unique<glm::vec4>(rgb[pos.back().y * sz.x + pos.back().x]);
|
||||
@@ -1378,35 +1385,35 @@ void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, std::
|
||||
|
||||
std::array<std::vector<glm::ivec2>, 4> edges;
|
||||
static const std::array<adj_t, 4> adj[6] = {
|
||||
// front - ok
|
||||
// front
|
||||
{
|
||||
adj_t(3, 1, 0, 0),
|
||||
adj_t(4, 1, 1, 0),
|
||||
adj_t(1, 0, 0, 0),
|
||||
adj_t(5, 1, 0, 0),
|
||||
},
|
||||
// right - ok
|
||||
// right
|
||||
{
|
||||
adj_t(0, 1, 0, 0),
|
||||
adj_t(4, 1, 0, 1),
|
||||
adj_t(2, 0, 0, 0),
|
||||
adj_t(5, 0, 0, 1),
|
||||
},
|
||||
// back - ok
|
||||
// back
|
||||
{
|
||||
adj_t(1, 1, 0, 0),
|
||||
adj_t(4, 0, 0, 0),
|
||||
adj_t(3, 0, 0, 0),
|
||||
adj_t(5, 0, 1, 0),
|
||||
},
|
||||
// left - ok
|
||||
// left
|
||||
{
|
||||
adj_t(2, 1, 0, 0),
|
||||
adj_t(4, 0, 1, 1),
|
||||
adj_t(0, 0, 0, 0),
|
||||
adj_t(5, 1, 1, 1),
|
||||
},
|
||||
// top - ok
|
||||
// top
|
||||
{
|
||||
adj_t(1, 1, 1, 1),
|
||||
adj_t(0, 1, 1, 0),
|
||||
@@ -1454,6 +1461,10 @@ void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, std::
|
||||
{
|
||||
mask[i] = true;
|
||||
rgb[i] = dest_color * 255.f;
|
||||
plane_data.dirty[plane] = true;
|
||||
glm::vec2 bb_min = glm::min((glm::vec2)p, xy(plane_data.bb[plane]));
|
||||
glm::vec2 bb_max = glm::max((glm::vec2)p, zw(plane_data.bb[plane]));
|
||||
plane_data.bb[plane] = { bb_min, bb_max };
|
||||
}
|
||||
pos.push_back(p);
|
||||
}
|
||||
@@ -1478,20 +1489,30 @@ void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, std::
|
||||
// test(p + glm::ivec2(x, y), false);
|
||||
}
|
||||
|
||||
rtt.bindTexture();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sz.x, sz.y, GL_RGBA, GL_UNSIGNED_BYTE, rgb);
|
||||
rtt.unbindTexture();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (!edges[i].empty())
|
||||
{
|
||||
flood_fill(layer, adj[plane][i].plane, edges[i], plane_mask, threshold, dest_color, source_color);
|
||||
flood_fill(layer, adj[plane][i].plane, edges[i], plane_data, threshold, dest_color, source_color);
|
||||
//LOG("continue to plane %d -> %d", plane, adj[plane][i].plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::FloodData::apply()
|
||||
{
|
||||
for (int plane = 0; plane < 6; plane++)
|
||||
{
|
||||
if (!dirty[plane])
|
||||
continue;
|
||||
auto& rtt = layer->m_rtt[plane];
|
||||
rtt.bindTexture();
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rtt.getWidth(), rtt.getHeight(),
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, rgb[plane].get());
|
||||
rtt.unbindTexture();
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::resize(int width, int height)
|
||||
{
|
||||
m_width = width;
|
||||
|
||||
Reference in New Issue
Block a user