implement frames save and open from ppi
This commit is contained in:
@@ -54,7 +54,7 @@ void App::create()
|
||||
|
||||
void App::open_document(std::string path)
|
||||
{
|
||||
std::regex r(R"((.*)[\\/]?([^\\/]+)\.(\w+)$)");
|
||||
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
||||
std::smatch m;
|
||||
if (!std::regex_search(path, m, r))
|
||||
return;
|
||||
|
||||
167
src/canvas.cpp
167
src/canvas.cpp
@@ -5,6 +5,8 @@
|
||||
#include "texture.h"
|
||||
#include "node_progress_bar.h"
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Foundation/Foundation.h>
|
||||
@@ -2117,8 +2119,13 @@ bool Canvas::project_save_thread(std::string file_path, bool show_progress)
|
||||
int n_layers = (int)m_layers.size();
|
||||
fwrite(&n_layers, sizeof(int), 1, fp);
|
||||
|
||||
int n_frames = std::accumulate(m_layers.begin(), m_layers.end(), 0,
|
||||
[](int tot, auto& l) { return tot + l->m_frames.size(); });
|
||||
if (ppi_header.doc_version.minor >= 3)
|
||||
fwrite(&n_frames, sizeof(int), 1, fp);
|
||||
|
||||
int progress = 0;
|
||||
int total = (int)m_layers.size() * 6;
|
||||
int total = n_frames * 6;
|
||||
|
||||
for (int i = 0; i < (int)m_layers.size(); i++)
|
||||
{
|
||||
@@ -2132,44 +2139,57 @@ bool Canvas::project_save_thread(std::string file_path, bool show_progress)
|
||||
fwrite(&name_len, sizeof(int), 1, fp);
|
||||
fwrite(m_layers[i]->m_name.data(), name_len, 1, fp);
|
||||
|
||||
if (ppi_header.doc_version.minor > 1)
|
||||
if (ppi_header.doc_version.minor >= 2)
|
||||
{
|
||||
fwrite(&m_layers[i]->m_blend_mode, sizeof(int), 1, fp);
|
||||
fwrite(&m_layers[i]->m_alpha_locked, sizeof(bool), 1, fp);
|
||||
fwrite(&m_layers[i]->m_visible, sizeof(bool), 1, fp);
|
||||
}
|
||||
|
||||
m_layers[i]->optimize();
|
||||
auto snap = m_layers[i]->snapshot();
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
int frames = 1;
|
||||
if (ppi_header.doc_version.minor >= 3)
|
||||
{
|
||||
int has_data = snap.m_dirty_face[plane_index] ? 1 : 0;
|
||||
fwrite(&has_data, sizeof(int), 1, fp);
|
||||
if (has_data)
|
||||
frames = (int)m_layers[i]->m_frames.size();
|
||||
fwrite(&frames, sizeof(int), 1, fp);
|
||||
}
|
||||
|
||||
for (int fi = 0; fi < frames; fi++)
|
||||
{
|
||||
if (ppi_header.doc_version.minor >= 3)
|
||||
fwrite(&m_layers[i]->m_frames[fi].m_duration, sizeof(int), 1, fp);
|
||||
|
||||
m_layers[i]->optimize(fi);
|
||||
auto snap = m_layers[i]->snapshot(fi);
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
glm::ivec4 b = snap.m_dirty_box[plane_index];
|
||||
glm::vec2 sz = zw(b) - xy(b);
|
||||
int box[4] = { b.x, b.y, b.z, b.w };
|
||||
fwrite(&box, sizeof(box), 1, fp);
|
||||
|
||||
std::vector<uint8_t> compressed;
|
||||
auto callback = [](void *context, void *data, int size)
|
||||
int has_data = snap.m_dirty_face[plane_index] ? 1 : 0;
|
||||
fwrite(&has_data, sizeof(int), 1, fp);
|
||||
if (has_data)
|
||||
{
|
||||
std::vector<uint8_t>* buffer = static_cast<std::vector<uint8_t>*>(context);
|
||||
buffer->insert(buffer->end(), (uint8_t*)data, (uint8_t*)data + size);
|
||||
};
|
||||
int ret = stbi_write_png_to_func(callback, &compressed, sz.x, sz.y, 4, snap.image[plane_index].get(), sz.x * 4);
|
||||
glm::ivec4 b = snap.m_dirty_box[plane_index];
|
||||
glm::vec2 sz = zw(b) - xy(b);
|
||||
int box[4] = { b.x, b.y, b.z, b.w };
|
||||
fwrite(&box, sizeof(box), 1, fp);
|
||||
|
||||
int data_size = (int)compressed.size();
|
||||
fwrite(&data_size, sizeof(int), 1, fp);
|
||||
std::vector<uint8_t> compressed;
|
||||
auto callback = [](void* context, void* data, int size)
|
||||
{
|
||||
std::vector<uint8_t>* buffer = static_cast<std::vector<uint8_t>*>(context);
|
||||
buffer->insert(buffer->end(), (uint8_t*)data, (uint8_t*)data + size);
|
||||
};
|
||||
int ret = stbi_write_png_to_func(callback, &compressed, sz.x, sz.y, 4, snap.image[plane_index].get(), sz.x * 4);
|
||||
|
||||
fwrite(compressed.data(), 1, compressed.size(), fp);
|
||||
int data_size = (int)compressed.size();
|
||||
fwrite(&data_size, sizeof(int), 1, fp);
|
||||
|
||||
fwrite(compressed.data(), 1, compressed.size(), fp);
|
||||
}
|
||||
progress++;
|
||||
float p = (float)progress / total * 100.f;
|
||||
if (show_progress)
|
||||
pb->m_progress->SetWidthP(p);
|
||||
LOG("progress: %f", p);
|
||||
}
|
||||
progress++;
|
||||
float p = (float)progress / total * 100.f;
|
||||
if (show_progress)
|
||||
pb->m_progress->SetWidthP(p);
|
||||
LOG("progress: %f", p);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
@@ -2273,13 +2293,16 @@ bool Canvas::project_open_thread(std::string file_path)
|
||||
|
||||
int n_layers = 0;
|
||||
fread(&n_layers, sizeof(int), 1, fp);
|
||||
int n_frames = 1;
|
||||
if (ppi_header.doc_version.minor >= 3)
|
||||
fread(&n_frames, sizeof(int), 1, fp);
|
||||
|
||||
const int bytes = m_width * m_height * 4;
|
||||
Layer::Snapshot snap;
|
||||
snap.create(m_width, m_height); // allocate single data, no box should be bigger
|
||||
|
||||
int progress = 0;
|
||||
int total = n_layers * 6;
|
||||
int total = n_frames * 6;
|
||||
|
||||
for (auto& l : m_layers)
|
||||
l->destroy();
|
||||
@@ -2307,52 +2330,63 @@ bool Canvas::project_open_thread(std::string file_path)
|
||||
std::string name(name_len, '\0');
|
||||
fread((char*)name.data(), name_len, 1, fp);
|
||||
|
||||
if (ppi_header.doc_version.minor > 1)
|
||||
if (ppi_header.doc_version.minor >= 2)
|
||||
{
|
||||
fread(&layer->m_blend_mode, sizeof(int), 1, fp);
|
||||
fread(&layer->m_alpha_locked, sizeof(bool), 1, fp);
|
||||
fread(&layer->m_visible, sizeof(bool), 1, fp);
|
||||
}
|
||||
|
||||
snap.clear();
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
int has_data;
|
||||
fread(&has_data, sizeof(int), 1, fp);
|
||||
snap.m_dirty_face[plane_index] = has_data;
|
||||
if (has_data)
|
||||
{
|
||||
int b[4];
|
||||
fread(&b, sizeof(b), 1, fp);
|
||||
snap.m_dirty_box[plane_index] = glm::vec4(b[0], b[1], b[2], b[3]);
|
||||
glm::vec2 sz = zw(snap.m_dirty_box[plane_index]) - xy(snap.m_dirty_box[plane_index]);
|
||||
|
||||
int data_size;
|
||||
fread(&data_size, sizeof(int), 1, fp);
|
||||
std::vector<uint8_t> compressed(data_size);
|
||||
|
||||
fread(compressed.data(), 1, data_size, fp);
|
||||
int imgw, imgh, imgc;
|
||||
uint8_t* rgba = stbi_load_from_memory(compressed.data(), data_size, &imgw, &imgh, &imgc, 4);
|
||||
if (rgba)
|
||||
{
|
||||
std::copy(rgba, rgba + (imgw*imgh * 4), snap.image[plane_index].get());
|
||||
delete rgba;
|
||||
}
|
||||
}
|
||||
|
||||
progress++;
|
||||
float p = (float)progress / total * 100.f;
|
||||
LOG("progress: %f", p);
|
||||
|
||||
if (App::I->layout.m_loaded)
|
||||
{
|
||||
pb->m_progress->SetWidthP(p);
|
||||
}
|
||||
}
|
||||
int frames = 1;
|
||||
if (ppi_header.doc_version.minor >= 3)
|
||||
fread(&frames, sizeof(int), 1, fp);
|
||||
|
||||
layer->create(m_width, m_height, name.c_str());
|
||||
layer->restore(snap);
|
||||
|
||||
for (int fi = 0; fi < frames; fi++)
|
||||
{
|
||||
if (fi > 0)
|
||||
layer->add_frame();
|
||||
if (ppi_header.doc_version.minor >= 3)
|
||||
fread(&layer->m_frames[fi].m_duration, sizeof(int), 1, fp);
|
||||
snap.clear();
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
int has_data;
|
||||
fread(&has_data, sizeof(int), 1, fp);
|
||||
snap.m_dirty_face[plane_index] = has_data;
|
||||
if (has_data)
|
||||
{
|
||||
int b[4];
|
||||
fread(&b, sizeof(b), 1, fp);
|
||||
snap.m_dirty_box[plane_index] = glm::vec4(b[0], b[1], b[2], b[3]);
|
||||
glm::vec2 sz = zw(snap.m_dirty_box[plane_index]) - xy(snap.m_dirty_box[plane_index]);
|
||||
|
||||
int data_size;
|
||||
fread(&data_size, sizeof(int), 1, fp);
|
||||
std::vector<uint8_t> compressed(data_size);
|
||||
|
||||
fread(compressed.data(), 1, data_size, fp);
|
||||
int imgw, imgh, imgc;
|
||||
uint8_t* rgba = stbi_load_from_memory(compressed.data(), data_size, &imgw, &imgh, &imgc, 4);
|
||||
if (rgba)
|
||||
{
|
||||
std::copy(rgba, rgba + (imgw * imgh * 4), snap.image[plane_index].get());
|
||||
delete rgba;
|
||||
}
|
||||
}
|
||||
|
||||
progress++;
|
||||
float p = (float)progress / total * 100.f;
|
||||
LOG("progress: %f", p);
|
||||
|
||||
if (App::I->layout.m_loaded)
|
||||
{
|
||||
pb->m_progress->SetWidthP(p);
|
||||
}
|
||||
}
|
||||
layer->restore(snap, fi);
|
||||
}
|
||||
}
|
||||
|
||||
std::swap(tmp_layers, m_layers);
|
||||
@@ -2377,6 +2411,7 @@ bool Canvas::project_open_thread(std::string file_path)
|
||||
{
|
||||
pb->destroy();
|
||||
App::I->title_update();
|
||||
App::I->animation->load_layers();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,11 @@ struct PPIThumb
|
||||
struct PPIDocVersion
|
||||
{
|
||||
int major = 0;
|
||||
int minor = 2;
|
||||
|
||||
// version 1: initial
|
||||
// version 2: added blend mode, alpha and visibility
|
||||
// version 3: added animation frames
|
||||
int minor = 3;
|
||||
};
|
||||
|
||||
struct PPISoftVersion
|
||||
|
||||
@@ -101,15 +101,17 @@ void Layer::destroy()
|
||||
rtt(i).destroy();
|
||||
}
|
||||
|
||||
void Layer::optimize()
|
||||
void Layer::optimize(int frame /*= -1*/)
|
||||
{
|
||||
if (frame == -1)
|
||||
frame = m_frame_index;
|
||||
int saved_bytes = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!face(i))
|
||||
if (!face(i, frame))
|
||||
continue;
|
||||
|
||||
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(rtt(i).readTextureData()));
|
||||
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(rtt(i, frame).readTextureData()));
|
||||
glm::ivec2 bbmin(w, h);
|
||||
glm::ivec2 bbmax(0);
|
||||
for (int y = 0; y < h; y++)
|
||||
@@ -124,17 +126,17 @@ void Layer::optimize()
|
||||
}
|
||||
}
|
||||
glm::vec2 bbsz = bbmax - bbmin;
|
||||
glm::vec2 old_size = zw(box(i)) - xy(box(i));
|
||||
glm::vec2 old_size = zw(box(i, frame)) - xy(box(i, frame));
|
||||
glm::vec2 diff;
|
||||
if (bbsz.x <= 0 || bbmax.y <= 0)
|
||||
{
|
||||
face(i) = false;
|
||||
box(i) = glm::vec4(0);
|
||||
face(i, frame) = false;
|
||||
box(i, frame) = glm::vec4(0);
|
||||
diff = old_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
box(i) = { bbmin, bbmax };
|
||||
box(i, frame) = { bbmin, bbmax };
|
||||
|
||||
diff = old_size - bbsz;
|
||||
}
|
||||
@@ -143,73 +145,79 @@ void Layer::optimize()
|
||||
LOG("optimized %d bytes", saved_bytes);
|
||||
}
|
||||
|
||||
void Layer::restore(const Snapshot& snap)
|
||||
void Layer::restore(const Snapshot& snap, int frame /*= -1*/)
|
||||
{
|
||||
clear({ 0, 0, 0, 0 });
|
||||
if (frame == -1)
|
||||
frame = m_frame_index;
|
||||
clear({ 0, 0, 0, 0 }, frame);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (snap.image[i] == nullptr || snap.m_dirty_face[i] == false || box_area(snap.m_dirty_box[i]) <= 0)
|
||||
{
|
||||
box(i) = glm::vec4(snap.width, snap.height, 0, 0);
|
||||
face(i) = false;
|
||||
box(i, frame) = glm::vec4(snap.width, snap.height, 0, 0);
|
||||
face(i, frame) = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
box(i) = snap.m_dirty_box[i];
|
||||
face(i) = snap.m_dirty_face[i];
|
||||
box(i, frame) = snap.m_dirty_box[i];
|
||||
face(i, frame) = snap.m_dirty_face[i];
|
||||
|
||||
// TODO: this should not be recreated here!
|
||||
// Sorry I messed up with this,
|
||||
// it's just a quick fix DON'T SHIP!!
|
||||
//m_rtt[i].recreate();
|
||||
|
||||
App::I->render_task_async([this, i, &snap]
|
||||
App::I->render_task_async([this, i, &snap, frame]
|
||||
{
|
||||
rtt(i).bindTexture();
|
||||
glm::vec2 box_sz = zw(box(i)) - xy(box(i));
|
||||
rtt(i, frame).bindTexture();
|
||||
glm::vec2 box_sz = zw(box(i, frame)) - xy(box(i, frame));
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
box(i).x, box(i).y,
|
||||
box(i, frame).x, box(i, frame).y,
|
||||
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
snap.image[i].get());
|
||||
rtt(i).unbindTexture();
|
||||
LOG("restore face %d - %d bytes (%dx%d)", i,
|
||||
rtt(i, frame).unbindTexture();
|
||||
LOG("restore frame %d face %d - %d bytes (%dx%d)", frame, i,
|
||||
(int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
|
||||
});
|
||||
}
|
||||
App::I->render_sync();
|
||||
}
|
||||
|
||||
Layer::Snapshot Layer::snapshot(std::array<glm::vec4, 6>* dirty_box /*= nullptr*/, std::array<bool, 6>* dirty_face /*= nullptr*/)
|
||||
Layer::Snapshot Layer::snapshot(int frame /*= -1*/, std::array<glm::vec4, 6>* dirty_box /*= nullptr*/, std::array<bool, 6>* dirty_face /*= nullptr*/)
|
||||
{
|
||||
if (frame == -1)
|
||||
frame = m_frame_index;
|
||||
Snapshot snap;
|
||||
snap.width = w;
|
||||
snap.height = h;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : box(i);
|
||||
snap.m_dirty_face[i] = dirty_face ? dirty_face->at(i) : face(i);
|
||||
snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : box(i, frame);
|
||||
snap.m_dirty_face[i] = dirty_face ? dirty_face->at(i) : face(i, frame);
|
||||
|
||||
if (!snap.m_dirty_face[i])
|
||||
continue;
|
||||
|
||||
snap.image[i] = std::make_unique<uint8_t[]>(rtt(i).bytes());
|
||||
snap.image[i] = std::make_unique<uint8_t[]>(rtt(i, frame).bytes());
|
||||
|
||||
App::I->render_task_async([this, i, &snap]
|
||||
App::I->render_task_async([this, i, &snap, frame]
|
||||
{
|
||||
rtt(i).bindFramebuffer();
|
||||
rtt(i, frame).bindFramebuffer();
|
||||
glm::vec2 box_sz = zw(snap.m_dirty_box[i]) - xy(snap.m_dirty_box[i]);
|
||||
glReadPixels(snap.m_dirty_box[i].x, snap.m_dirty_box[i].y,
|
||||
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get());
|
||||
rtt(i).unbindFramebuffer();
|
||||
rtt(i, frame).unbindFramebuffer();
|
||||
});
|
||||
}
|
||||
App::I->render_sync();
|
||||
return snap;
|
||||
}
|
||||
|
||||
void Layer::clear(const glm::vec4& c)
|
||||
void Layer::clear(const glm::vec4& c, int frame /*= -1*/)
|
||||
{
|
||||
frame().clear(c);
|
||||
if (frame == -1)
|
||||
frame = m_frame_index;
|
||||
m_frames[frame].clear(c);
|
||||
}
|
||||
|
||||
bool Layer::create(int width, int height, std::string name)
|
||||
@@ -218,9 +226,9 @@ bool Layer::create(int width, int height, std::string name)
|
||||
w = width;
|
||||
h = height;
|
||||
m_frame_index = 0;
|
||||
if (m_frames.empty())
|
||||
m_frames.emplace_back();
|
||||
frame().create(width, height);
|
||||
m_frames.clear();
|
||||
m_frames.emplace_back();
|
||||
m_frames.back().create(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ public:
|
||||
bool add_frame();
|
||||
int total_duration() const noexcept;
|
||||
void goto_frame(int frame) noexcept;
|
||||
void clear(const glm::vec4& c);
|
||||
Snapshot snapshot(std::array<glm::vec4, 6>* dirty_box = nullptr, std::array<bool, 6>* dirty_face = nullptr);
|
||||
void clear(const glm::vec4& c, int frame = -1);
|
||||
Snapshot snapshot(int frame = -1, std::array<glm::vec4, 6>* dirty_box = nullptr, std::array<bool, 6>* dirty_face = nullptr);
|
||||
TextureCube gen_cube();
|
||||
Texture2D gen_equirect();
|
||||
void restore(const Snapshot& snap);
|
||||
void restore(const Snapshot& snap, int frame = -1);
|
||||
void destroy();
|
||||
void optimize();
|
||||
void optimize(int frame = -1);
|
||||
};
|
||||
|
||||
@@ -37,21 +37,16 @@ void NodePanelAnimation::init_controls()
|
||||
Canvas::I->layer().add_frame();
|
||||
load_layers();
|
||||
};
|
||||
btn_up->on_click = [this](Node*) {
|
||||
auto& layers = Canvas::I->m_layers;
|
||||
auto layer = std::find_if(layers.begin(), layers.end(),
|
||||
[id = m_selected_frame_layer_id](const auto& l) { return l->id == id; });
|
||||
if (layer != layers.end())
|
||||
(*layer)->m_frames[m_selected_frame_index].m_duration++;
|
||||
};
|
||||
btn_up->on_click = [this](Node*) {
|
||||
if (auto layer = Canvas::I->layer_with_id(m_selected_frame_layer_id))
|
||||
layer->m_frames[m_selected_frame_index].m_duration++;
|
||||
layer->m_frames[m_selected_frame_index].m_duration =
|
||||
glm::max(layer->m_frames[m_selected_frame_index].m_duration + 1, 1);
|
||||
load_layers();
|
||||
};
|
||||
btn_down->on_click = [this](Node*) {
|
||||
if (auto layer = Canvas::I->layer_with_id(m_selected_frame_layer_id))
|
||||
layer->m_frames[m_selected_frame_index].m_duration--;
|
||||
layer->m_frames[m_selected_frame_index].m_duration =
|
||||
glm::max(layer->m_frames[m_selected_frame_index].m_duration - 1, 1);
|
||||
load_layers();
|
||||
};
|
||||
|
||||
@@ -85,9 +80,9 @@ void NodePanelAnimation::load_layers()
|
||||
}
|
||||
b->on_click = [this, fi, lid=layers[i]->id] (Node* target) {
|
||||
auto frame = static_cast<NodeAnimationFrame*>(target);
|
||||
frame->set_active(true);
|
||||
if (m_selected_frame)
|
||||
m_selected_frame->set_active(false);
|
||||
frame->set_active(true);
|
||||
m_selected_frame = frame;
|
||||
m_selected_frame_layer_id = lid;
|
||||
m_selected_frame_index = fi;
|
||||
|
||||
@@ -83,7 +83,7 @@ void NodePanelBrush::init()
|
||||
m_btn_add->on_click = [this](Node*) {
|
||||
App::I->pick_file({ "JPG", "PNG" }, [this](std::string path) {
|
||||
std::string name, base, ext;
|
||||
std::regex r(R"((.*)[\\/]?([^\\/]+)\.(\w+)$)");
|
||||
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
||||
std::smatch m;
|
||||
if (!std::regex_search(path, m, r))
|
||||
return;
|
||||
@@ -708,7 +708,7 @@ bool NodePanelBrushPreset::export_ppbr(const std::string& path_in, const PPBRInf
|
||||
path += ".ppbr";
|
||||
LOG("export ppbr to: %s", path.c_str());
|
||||
|
||||
std::regex r(R"((.*)[\\/]?([^\\/]+)\.(\w+)?$)");
|
||||
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)?$)");
|
||||
std::smatch m;
|
||||
if (!std::regex_search(path, m, r))
|
||||
return false;
|
||||
@@ -972,7 +972,7 @@ bool NodePanelBrushPreset::import_abr(const std::string& path)
|
||||
LOG("ABR detected");
|
||||
|
||||
std::string name, base, ext;
|
||||
std::regex r(R"((.*)[\\/]?([^\\/]+)\.(\w+)$)");
|
||||
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
||||
std::smatch m;
|
||||
if (!std::regex_search(path, m, r))
|
||||
return false;
|
||||
@@ -1042,7 +1042,7 @@ bool NodePanelBrushPreset::import_abr(const std::string& path)
|
||||
|
||||
bool NodePanelBrushPreset::import_brush(const std::string& path)
|
||||
{
|
||||
std::regex r(R"((.*)[\\/]?([^\\/]+)\.(\w+)$)");
|
||||
std::regex r(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
||||
std::smatch m;
|
||||
if (!std::regex_search(path, m, r))
|
||||
return false;
|
||||
|
||||
@@ -409,7 +409,7 @@ void NodePanelLayer::merge(int src_index, int dst_index, bool create_history)
|
||||
a->m_dirty_face[i] = Canvas::I->m_layers[dst_index]->face(i);
|
||||
}
|
||||
a->m_snap = std::make_shared<Layer::Snapshot>();
|
||||
*a->m_snap = Canvas::I->m_layers[dst_index]->snapshot(
|
||||
*a->m_snap = Canvas::I->m_layers[dst_index]->snapshot(-1,
|
||||
&Canvas::I->m_layers[src_index]->frame().m_dirty_box, &Canvas::I->m_layers[src_index]->frame().m_dirty_face);
|
||||
a->m_layer = Canvas::I->m_layers[src_index];
|
||||
a->m_layer_node = std::static_pointer_cast<NodeLayer>(m_layers_container->m_children[src_index]);
|
||||
|
||||
@@ -93,12 +93,7 @@ bool RTT::resize(int width, int height)
|
||||
|
||||
oldRFboID = 0;
|
||||
oldDFboID = 0;
|
||||
fboID = new_rtt.fboID;
|
||||
rboID = new_rtt.rboID;
|
||||
texID = new_rtt.texID;
|
||||
int_fmt = new_rtt.int_fmt;
|
||||
w = new_rtt.w;
|
||||
h = new_rtt.h;
|
||||
*this = std::move(new_rtt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user