pixel based brush size, Photoshop slider curve, improve abr import

This commit is contained in:
2019-02-23 20:46:20 +01:00
parent e1f82373c6
commit 3a1a48a0d0
15 changed files with 218 additions and 104 deletions

View File

@@ -63,8 +63,9 @@ bool NodePanelStroke::import_abr(const std::string& path)
std::string path_high = App::I.data_path + "/brushes/" + samp.first + ".png";
std::string path_thumb = App::I.data_path + "/brushes/thumbs/" + samp.first + ".png";
auto padded = samp.second->resize_squared(glm::u8vec4(255));
auto high = padded.resize_power2();
high.save(path_high);
//auto high = padded.resize_power2();
//high.save(path_high);
samp.second->save(path_high);
auto thumb = padded.resize(64, 64);
thumb.save(path_thumb);
@@ -136,9 +137,9 @@ bool NodePanelStroke::import_abr(const std::string& path)
void NodePanelStroke::update_controls()
{
const auto& b = Canvas::I->m_current_brush;
m_tip_size->m_value.x = glm::pow(b->m_tip_size, 1.f/3.f);
m_tip_spacing->m_value.x = glm::pow(b->m_tip_spacing, 1.f/2.f);
m_tip_flow->m_value.x = glm::pow(b->m_tip_flow, 1.f/2.f);
m_tip_size->m_value.x = m_curves[m_tip_size].to_slider(b->m_tip_size);
m_tip_spacing->m_value.x = m_curves[m_tip_spacing].to_slider(b->m_tip_spacing);
m_tip_flow->m_value.x = m_curves[m_tip_flow].to_slider(b->m_tip_flow);
m_tip_opacity->m_value.x = b->m_tip_opacity;
m_tip_angle->m_value.x = b->m_tip_angle;
m_tip_angle_delay->m_value.x = b->m_tip_angle_delay;
@@ -168,9 +169,9 @@ void NodePanelStroke::update_controls()
m_tip_randflipx->checked = b->m_tip_randflipx;
m_tip_randflipy->checked = b->m_tip_randflipy;
m_dual_size->m_value.x = glm::pow(b->m_dual_size, 1.f / 3.f);
m_dual_spacing->m_value.x = glm::pow(b->m_dual_spacing, 1.f / 2.f);
m_dual_flow->m_value.x = glm::pow(b->m_dual_flow, 1.f / 2.f);
m_dual_size->m_value.x = m_curves[m_dual_size].to_slider(b->m_dual_size);
m_dual_spacing->m_value.x = m_curves[m_dual_spacing].to_slider(b->m_dual_spacing);
m_dual_flow->m_value.x = m_curves[m_dual_flow].to_slider(b->m_dual_flow);
m_dual_scatter->m_value.x = b->m_dual_scatter;
m_tip_aspect->m_value.x = b->m_tip_aspect;
m_dual_opacity->m_value.x = b->m_dual_opacity;
@@ -181,7 +182,7 @@ void NodePanelStroke::update_controls()
m_pattern_flipx->checked = b->m_pattern_flipx;
m_pattern_flipy->checked = b->m_pattern_flipy;
m_pattern_rand_offset->checked = b->m_pattern_rand_offset;
m_pattern_scale->m_value.x = b->m_pattern_scale;
m_pattern_scale->m_value.x = m_curves[m_pattern_scale].to_slider(b->m_pattern_scale);
m_pattern_brightness->m_value.x = b->m_pattern_brightness;
m_pattern_contrast->m_value.x = b->m_pattern_contrast;
m_pattern_depth->m_value.x = b->m_pattern_depth;
@@ -247,8 +248,8 @@ void NodePanelStroke::init_controls()
b->load_tip(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
b->load_dual(m_brush_popup->get_texture_path(br_idx), m_brush_popup->get_thumb_path(br_idx));
b->load_pattern(m_pattern_popup->get_texture_path(0), m_pattern_popup->get_thumb_path(0));
b->m_tip_size = .1f;
b->m_tip_flow = .5f;
b->m_tip_size = 30;
b->m_tip_flow = .9f;
b->m_tip_spacing = .1f;
b->m_tip_opacity = 1.f;
Canvas::I->m_current_brush = b;
@@ -470,14 +471,62 @@ void NodePanelStroke::init_controls()
init_slider(m_pattern_contrast, "pattern-contrast", &Brush::m_pattern_contrast);
init_slider(m_pattern_depth, "pattern-depth", &Brush::m_pattern_depth);
auto curve_cubic = [](float v) { return glm::pow(v, 3.f); };
auto curve_quad = [](float v) { return glm::pow(v, 2.f); };
m_curves[m_tip_size] = curve_cubic;
m_curves[m_tip_spacing] = curve_quad;
SliderCurve curve_cubic {
[](float v) { return glm::pow(v, 3.f); },
[](float v) { return glm::pow(v, 1.f / 3.f); },
};
SliderCurve curve_quad {
[](float v) { return glm::pow(v, 2.f); },
[](float v) { return glm::pow(v, 1.f / 2.f); },
};
SliderCurve curve_size1k_perc {
[](float v) {
float ret = 0;
if (v > 0.00f) ret += glm::pow(glm::min(1.f, (v - 0.00f) / 0.50f), 2.f) * 1.f;
if (v > 0.50f) ret += glm::min(1.f, (v - 0.50f) / 0.25f) * 2.f;
if (v > 0.75f) ret += glm::min(1.f, (v - 0.75f) / 0.10f) * 4.f;
if (v > 0.85f) ret += glm::min(1.f, (v - 0.85f) / 0.05f) * 5.f;
if (v > 0.90f) ret += glm::min(1.f, (v - 0.90f) / 0.10f) * 10.f;
return glm::max(.01f, ret);
},
[](float v) {
float ret = 0;
if (v > 0.f) ret += glm::pow(glm::min(1.f, (v - 0.f) / 1.f), 1.f / 2.f) * 0.50f;
if (v > 1.f) ret += glm::min(1.f, (v - 1.f) / 2.f) * 0.25f;
if (v > 2.f) ret += glm::min(1.f, (v - 2.f) / 4.f) * 0.10f;
if (v > 4.f) ret += glm::min(1.f, (v - 4.f) / 5.f) * 0.05f;
if (v > 5.f) ret += glm::min(1.f, (v - 5.f) / 10.f) * 0.10f;
return ret;
},
};
SliderCurve curve_size5k_pix {
[](float v) {
float ret = 0;
if (v > 0.00f) ret += glm::pow(glm::min(1.f, (v - 0.00f) / 0.50f), 2.f) * 100.f;
if (v > 0.50f) ret += glm::min(1.f, (v - 0.50f) / 0.25f) * 200.f;
if (v > 0.75f) ret += glm::min(1.f, (v - 0.75f) / 0.10f) * 400.f;
if (v > 0.85f) ret += glm::min(1.f, (v - 0.85f) / 0.05f) * 1000.f;
if (v > 0.90f) ret += glm::min(1.f, (v - 0.90f) / 0.10f) * 5000.f;
return glm::max(1.f, ret);
},
[](float v) {
float ret = 0;
if (v > 0.f) ret += glm::pow(glm::min(1.f, (v - 0.f) / 100.f), 1.f / 2.f) * 0.50f;
if (v > 100.f) ret += glm::min(1.f, (v - 100.f) / 200.f) * 0.25f;
if (v > 200.f) ret += glm::min(1.f, (v - 200.f) / 400.f) * 0.10f;
if (v > 400.f) ret += glm::min(1.f, (v - 400.f) / 1000.f) * 0.05f;
if (v > 1000.f) ret += glm::min(1.f, (v - 1000.f) / 5000.f) * 0.10f;
return ret;
},
};
m_curves[m_tip_size] = curve_size5k_pix;
m_curves[m_tip_spacing] = curve_size1k_perc;
m_curves[m_tip_flow] = curve_quad;
m_curves[m_dual_size] = curve_cubic;
m_curves[m_dual_spacing] = curve_quad;
m_curves[m_dual_size] = curve_size5k_pix;
m_curves[m_dual_spacing] = curve_size1k_perc;
m_curves[m_dual_flow] = curve_quad;
m_curves[m_pattern_scale] = curve_size1k_perc;
m_tip_aspect_reset = find<NodeButtonCustom>("tip-aspect-reset");
m_tip_aspect_reset->on_click = [this](Node*) {
@@ -529,7 +578,7 @@ void NodePanelStroke::init_slider(NodeSliderH*& target, const char* id, float Br
void NodePanelStroke::handle_slide(float Brush::* prop, Node* target, float value)
{
auto curve = m_curves.find((NodeSliderH*)target);
Canvas::I->m_current_brush.get()->*prop = curve != m_curves.end() ? curve->second(value) : value;
Canvas::I->m_current_brush.get()->*prop = curve != m_curves.end() ? curve->second.to_value(value) : value;
m_preview->draw_stroke();
if (on_stroke_change)
on_stroke_change(this);