From ed498c296dddad137c2f33151a5fcfae4b8c4b03 Mon Sep 17 00:00:00 2001 From: danya Date: Fri, 26 Mar 2021 15:57:37 +0300 Subject: [PATCH] Test UI and Bug fixes Made new ui to test Fixed bug with linear gradient Optimised Coons patch --- .../include/test_grads/custom_gradients.h | 131 ++- DesktopEditor/graphics/shading_info.h | 224 ++++- .../gradient/Gradient/mainwindow.cpp | 349 ++++---- .../gradient/Gradient/mainwindow.h | 65 +- .../gradient/Gradient/mainwindow.ui | 808 ++++++------------ 5 files changed, 788 insertions(+), 789 deletions(-) diff --git a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h index 4702096b09..48806b4555 100644 --- a/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h +++ b/DesktopEditor/agg-2.4/include/test_grads/custom_gradients.h @@ -72,31 +72,58 @@ namespace agg class calcRadial : public calcBase { public: - calcRadial(const NSStructures::GradientInfo &_gi, float _cx, float _cy, float _factor) : ginfo(_gi), cx(_cx), cy(_cy), factor(_factor), inverseFactor(1.0f / _factor), - invXsize(1.0f / _gi.xsize), invYsize(1.0f / _gi.ysize) + calcRadial(const NSStructures::GradientInfo &_gi) { - cx += ginfo.centerX * inverseFactor; - cy += ginfo.centerY * inverseFactor; - set_rotation(ginfo.angle); + r0 = _gi.r0; + r1 = _gi.r1; + p0 = _gi.p0; + p1 = _gi.p1; + ginfo = _gi; } virtual float eval(float x, float y) override { - x -= cx; - y -= cy; - rotate(x, y); - x *= invXsize; - y *= invYsize; - float t = sqrt(x * x + y * y) * factor; - return t; + if (r0 * r0 > (x - p0.x)*(x - p0.x) + (y - p0.y)*(y - p0.y)) + { + return ginfo.shading.function.get_x_min() - 1; + } + if (r1 * r1 < (x - p1.x)*(x - p1.x) + (y - p1.y)*(y - p1.y)) + { + return ginfo.shading.function.get_x_max() + 1; + } + + float a = (r1 - r0) * (r1 - r0) - (p1.x - p0.x) * (p1.x - p0.x) - (p1.y - p0.y) * (p1.y - p0.y); + + float b = 2 * r0 * (r1 - r0) + 2 * (p1.x - p0.x) * (x - p0.x) + 2 * (p1.y - p0.y) * (y - p0.y); + + float c = r0 * r0 - (x - p0.x) * (x - p0.x) - (y - p0.y) * (y - p0.y); + + float D = b * b - 4 * a * c; + if (D < 0) + { + return NAN_FLOAT; + } + float x1 = (-b + sqrtf(D)) / 2 / a; + float x2 = (-b - sqrtf(D)) / 2 / a; + + if (0 <= x1 && x1 <= 1) + { + return ginfo.shading.function.get_x_min() + + (ginfo.shading.function.get_x_max() - ginfo.shading.function.get_x_min()) * x1; + } + if (0 <= x2 && x2 <= 1) + { + return ginfo.shading.function.get_x_min() + + (ginfo.shading.function.get_x_max() - ginfo.shading.function.get_x_min()) * x2; + } + return NAN_FLOAT; } virtual ~calcRadial() {} private: + float r0, r1; + NSStructures::Point p0,p1; NSStructures::GradientInfo ginfo; - float cx, cy, factor; - float inverseFactor; - float invXsize, invYsize; }; /** @@ -170,30 +197,22 @@ namespace agg class calcNewLinear : public calcBase { public: - calcNewLinear(const NSStructures::GradientInfo &_gi, - float _xmin, float _ymin, - float _xmax, float _ymax) : ginfo(_gi), - xmin(_xmin), ymin(_ymin), xmax(_xmax), ymax(_ymax) + calcNewLinear(const NSStructures::GradientInfo &_gi) : ginfo(_gi) { - cx = (xmin + xmax) * 0.5; - cy = (ymin + ymax) * 0.5; - xlen = xmax - xmin; - invXlen = 1.0f / xlen; - invStretch = 1.0f / ginfo.linstretch; - set_rotation(ginfo.angle); + p0 = _gi.shading.point1; + p1 = _gi.shading.point2; } virtual float eval(float x, float y) override { - x -= cx; - y -= cy; - rotate(x, y); - float t = (x + 0.5 * xlen) * invXlen * invStretch - ginfo.linoffset; + float t = (x - p0.x) * (p1.x - p0.x) + (y - p0.y) * (p1.y - p0.y); + t /= (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y); return t; } private: - float xmin, ymin, xmax, ymax; - float cx, cy, xlen; + + NSStructures::Point p0, p1; + float cx, cy, len; float invXlen, invStretch; NSStructures::GradientInfo ginfo; }; @@ -274,15 +293,29 @@ namespace agg RES = (int)std::max(ymax - ymin, xmax - xmin); precalc = std::vector>(RES, std::vector(RES, NAN_FLOAT)); delta = 1.0f / RES; - std::pair prev_i; - for (u = 0; u <=1; u+=delta) + std::vector> next_indexes(RES + 1); + u = 0; + for (int i = 0; i < RES; ++i) { - for (v = 0; v <= 1; v+=delta) + v = 0; + std::vector> cur_next_indexes(RES + 1); + for (int j = 0; j < RES; ++j) { - NSStructures::Point p = get_p(u, v); - std::pair index1 = get_index(p.x, p.y); + NSStructures::Point p; + std::pair index1; + if (i == 0 || j == 0) + { + p = get_p(u, v); + index1 = get_index(p.x, p.y); + } + else + { + index1 = next_indexes[j]; + } + p = get_p(u + delta, v + delta); std::pair index2 = get_index(p.x, p.y); + cur_next_indexes[j + 1] = index2; float t = ginfo.shading.patch_parameters[0][0] * (1 - v) * (1 - u) + @@ -291,7 +324,10 @@ namespace agg ginfo.shading.patch_parameters[1][1] * v * u; fill_square(index1, index2, t); + v += delta; } + next_indexes = cur_next_indexes; + u += delta; } } @@ -333,9 +369,6 @@ namespace agg return 3 * t * t * (1 - t); case 3: return t * t * t; - - default: - printf("!!!!!!"); } } @@ -444,9 +477,9 @@ namespace agg if(isnanf(t)) return t; - if (t < 0 && !m_oGradientInfo.continue_shading) + if (t < m_oGradientInfo.shading.function.get_x_min() && !m_oGradientInfo.continue_shading_b) return NAN_FLOAT; - if (t > 1 && !m_oGradientInfo.continue_shading) + if (t > m_oGradientInfo.shading.function.get_x_max() && !m_oGradientInfo.continue_shading_f) return NAN_FLOAT; if (t > m_oGradientInfo.largeRadius) @@ -490,7 +523,7 @@ namespace agg switch (bType) { case Aggplus::BrushTypeRadialGradient: - calculate = new calcRadial(m_oGradientInfo, m_center.x, m_center.y, m_factor); + calculate = new calcRadial(m_oGradientInfo); break; case Aggplus::BrushTypeConicalGradient: @@ -502,7 +535,7 @@ namespace agg break; case Aggplus::BrushTypeNewLinearGradient: - calculate = new calcNewLinear(m_oGradientInfo, xmin, ymin, xmax, ymax); + calculate = new calcNewLinear(m_oGradientInfo); break; case Aggplus::BrushTypeTriagnleMeshGradient: @@ -557,8 +590,12 @@ namespace agg { float _x = x; float _y = y; - _x = (_x - xmin) / (xmax - xmin); - _y = (_y - ymin) / (ymax - xmin); + _x += m_oGradientInfo.shading.inv_map[4]; + _y += m_oGradientInfo.shading.inv_map[5]; + + _x = _x * m_oGradientInfo.shading.inv_map[0] + _y * m_oGradientInfo.shading.inv_map[1]; + _y = _x * m_oGradientInfo.shading.inv_map[2] + _y * m_oGradientInfo.shading.inv_map[3]; + *span++ = m_oGradientInfo.shading.function.get_color(_x, _y); //m_color_table[index]; } else if (m_oGradientInfo.shading.shading_type == NSStructures::ShadingInfo::TriangleInterpolation) @@ -667,6 +704,8 @@ namespace agg // Нужно для безопасного сложения цветов. int limit8bit(int a) { + if (a < 0) + return 0; if (a >= 0x100) return 0xFF; return a; @@ -727,7 +766,7 @@ namespace agg xmax_curve = xmin_curve = start_p.x; ymax_curve = ymin_curve = start_p.y; precalc = std::vector>(RES, std::vector(RES, {0, 0, 0, 0})); - for (; u <= 1; u += delta) + for (; u <= 1; u += delta ) { for (v = 0; v <= 1; v += delta) { diff --git a/DesktopEditor/graphics/shading_info.h b/DesktopEditor/graphics/shading_info.h index b45ad0b1c5..a8f14dca1e 100644 --- a/DesktopEditor/graphics/shading_info.h +++ b/DesktopEditor/graphics/shading_info.h @@ -67,12 +67,28 @@ namespace NSStructures { for (int j = 0; j < RESOLUTION; j++) { - uint value = 255 - (255 * ((float)(i + j) / RESOLUTION / 2)); - values[j][i] = ColorT(value, value, value); + uint value = 255 * sin(i * j * M_PI / RESOLUTION); + values[j][i] = ColorT(value, value, 0); } } } + float get_x_min() + { + return x_domain_min; + } + float get_x_max() + { + return x_domain_max; + } + float get_y_min() + { + return y_domain_min; + } + float get_y_max() + { + return y_domain_max; + } ColorT get_color(float x) { int index = get_x_index(x); @@ -270,7 +286,7 @@ namespace NSStructures struct ShadingInfo { public: - ShadingInfo() : shading_type(Parametric), f_type(UseNew){} + ShadingInfo() : shading_type(Parametric), f_type(UseNew), inv_map(6){} enum ShadingType { FunctionOnly, @@ -279,15 +295,21 @@ namespace NSStructures CurveInterpolation, TensorCurveInterpolation } shading_type; + + // if UseOld old function is called, look for IGraphicsRender.put_BrushGradientColors; enum ColorFunctionType { UseOld, UseNew - }f_type; // if UseOld old function is called, look for IGraphicsRender.put_BrushGradientColors; + } f_type; ColorFunction function; - - - bool default_mapping; // boundaries to domain of color function + // Обратное преобразование из картинки в цветовую функцию + std::vector inv_map; + + // Линейный градиент задается в pdf 2 точками + bool set_two_points; + Point point1, point2; + // triangle shading std::vector triangle; @@ -318,7 +340,8 @@ namespace NSStructures periods(0.5f), periodic(false), xsize(1.0f), ysize(1.0f), linstretch(1.0f), linoffset(0.0f), - continue_shading(true) + continue_shading_f(false), + continue_shading_b(false) { } @@ -335,7 +358,10 @@ namespace NSStructures discrete_step = 1.0f / n; } - float littleRadius, largeRadius; // used in radial gradient - [0, 1] + Point p0, p1; + float r0, r1; + + float littleRadius, largeRadius; float centerX, centerY; // used in radial, diamond and conical gradient - offset relative to figure center float angle; // used in linear and conical gradient (rad) float discrete_step; // used to make discrete gradient. <= 0 to make continuous @@ -345,7 +371,7 @@ namespace NSStructures float periods; // number of periods (best with to colours, works as saw function in color space) float linstretch; // stretch linear gradient, can be negative (eq angle = 180) can not be zero float linoffset; // offset relative to image size - float continue_shading; + float continue_shading_b, continue_shading_f; ShadingInfo shading; }; @@ -356,37 +382,169 @@ namespace NSStructures * Цветовую функцию надо заполнять вручную */ class GInfoConstructor { - static GradientInfo get_functional() - { - - } - static GradientInfo get_linear() - { - - } - static GradientInfo get_radial() - { - - } - static GradientInfo get_triangle() - { - - } - static GradientInfo get_curve(const std::vector &curve_points, - const std::vector &curve_parametrs, - const std::vector &curve_colors) + public: + static GradientInfo get_functional(float xmin, float xmax, float ymin, float ymax, + std::vector mapping) { GradientInfo ginfo; + ginfo.shading.function = ColorFunction(512, xmin, xmax, ymin, ymax); + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.shading_type = ShadingInfo::FunctionOnly; + + ginfo.shading.inv_map[4] = -mapping[4]; + ginfo.shading.inv_map[5] = -mapping[5]; + + float D = mapping[0] * mapping[3] - mapping[1] * mapping[2]; + ginfo.shading.inv_map[0] = mapping[3] / D; + ginfo.shading.inv_map[1] = mapping[1] / D; + ginfo.shading.inv_map[2] = mapping[2] / D; + ginfo.shading.inv_map[3] = mapping[0] / D; + + return ginfo; + } + static GradientInfo get_linear(const Point &p1, const Point &p2, float t0 = 0.0f, float t1 = 1.0f, + bool continue_shading_b = false, bool continue_shading_f = false) + { + GradientInfo ginfo; + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.shading_type = ShadingInfo::Parametric; + ginfo.continue_shading_f = continue_shading_f; + ginfo.continue_shading_b = continue_shading_b; + + ginfo.shading.function = ColorFunction(515, t0, t1); + + ginfo.shading.set_two_points = true; + ginfo.shading.point1 = p1; + ginfo.shading.point2 = p2; + + + return ginfo; + } + static GradientInfo get_radial(const Point &c0, const Point &c1, float r0, float r1, + float t0 = 0.0f, float t1 = 1.0f, + bool continue_shading_b = false, bool continue_shading_f = false) + { + GradientInfo ginfo; + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.shading_type = ShadingInfo::Parametric; + ginfo.continue_shading_f = continue_shading_f; + ginfo.continue_shading_b = continue_shading_b; + ginfo.shading.function = ColorFunction(512, t0, t1); + ginfo.p0 = c0; + ginfo.p1 = c1; + ginfo.r0 = r0; + ginfo.r1 = r1; + return ginfo; + + + } + static GradientInfo get_triangle(const std::vector &points, + const std::vector &colors, + const std::vector ¶ms, + bool parametric, + float t0 = 0.0f, float t1 = 1.0f) + { + GradientInfo ginfo; + ginfo.shading.triangle = points; + if (parametric) + { + ginfo.shading.triangle_parameters = params; + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.function = ColorFunction(512, t0, t1); + ginfo.shading.shading_type = ShadingInfo::Parametric; + ginfo.continue_shading_f = false; + ginfo.continue_shading_b = false; + } + else + { + ginfo.shading.triangle_colors = colors; + ginfo.shading.shading_type = ShadingInfo::TriangleInterpolation; + } + return ginfo; + } + + /** + * Набор из 12 точек для построения границ в порядке указанном в стандарте, + * Порядок цветов или параметров как в стандарте. + */ + static GradientInfo get_curve(const std::vector &curve_points, + const std::vector &curve_parametrs, + const std::vector &curve_colors, + bool parametric, + float t0 = 0.0f, float t1 = 1.0f) + { + GradientInfo ginfo; + ginfo.shading.patch.resize(4, std::vector(4)); + ginfo.shading.patch[0][0] = curve_points[0]; + ginfo.shading.patch[0][1] = curve_points[1]; + ginfo.shading.patch[0][2] = curve_points[2]; + + ginfo.shading.patch[0][3] = curve_points[3]; + ginfo.shading.patch[1][3] = curve_points[4]; + ginfo.shading.patch[2][3] = curve_points[5]; + + ginfo.shading.patch[3][3] = curve_points[6]; + ginfo.shading.patch[3][2] = curve_points[7]; + ginfo.shading.patch[3][1] = curve_points[8]; + + ginfo.shading.patch[3][0] = curve_points[9]; + ginfo.shading.patch[2][0] = curve_points[10]; + ginfo.shading.patch[1][0] = curve_points[11]; + + + + if (parametric) + { + ginfo.shading.patch_parameters.resize(2, std::vector(2)); + ginfo.shading.patch_parameters[0][0] = curve_parametrs[0]; + ginfo.shading.patch_parameters[0][1] = curve_parametrs[1]; + ginfo.shading.patch_parameters[1][0] = curve_parametrs[3]; + ginfo.shading.patch_parameters[1][1] = curve_parametrs[2]; + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.function = ColorFunction(512, t0, t1); + ginfo.shading.shading_type = ShadingInfo::Parametric; + ginfo.continue_shading_f = false; + ginfo.continue_shading_b = false; + } + else + { + ginfo.shading.patch_colors.resize(2, std::vector(2)); + ginfo.shading.patch_colors[0][0] = curve_colors[0]; + ginfo.shading.patch_colors[0][1] = curve_colors[1]; + ginfo.shading.patch_colors[1][0] = curve_colors[3]; + ginfo.shading.patch_colors[1][1] = curve_colors[2]; + ginfo.shading.shading_type = ShadingInfo::CurveInterpolation; + } return ginfo; } static GradientInfo get_tensor_curve(const std::vector> &curve_poits, - const std::vector &curve_parametrs, - const std::vector &curve_colors) + const std::vector> &curve_parametrs, + const std::vector> &curve_colors, + bool parametric, + float t0 = 0.0f, float t1 = 1.0f) { + GradientInfo ginfo; - } + ginfo.shading.patch = curve_poits; + + if (parametric) + { + ginfo.shading.patch_parameters = curve_parametrs; + ginfo.shading.f_type = ShadingInfo::UseNew; + ginfo.shading.function = ColorFunction(512, t0, t1); + ginfo.shading.shading_type = ShadingInfo::Parametric; + ginfo.continue_shading_f = false; + ginfo.continue_shading_b = false; + } + else + { + ginfo.shading.patch_colors = curve_colors; + ginfo.shading.shading_type = ShadingInfo::TensorCurveInterpolation; + } + return ginfo; + } }; } -#endif \ No newline at end of file +#endif diff --git a/Test/Applications/gradient/Gradient/mainwindow.cpp b/Test/Applications/gradient/Gradient/mainwindow.cpp index 6a14dbb50a..3f368e479c 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.cpp +++ b/Test/Applications/gradient/Gradient/mainwindow.cpp @@ -95,115 +95,17 @@ void GenerateImg(QImage &img, std::vector &points, Info &info) { void MainWindow::on_RenderPic_clicked() { - QImage pm(400, 400,QImage::Format_RGB888); + QImage pm(400, 400, QImage::Format_RGB888); GenerateImg(pm, points, info); //setColor2(pm, 0x0000FF); //pm.invertPixels(); - ui->lable_test->setPixmap(QPixmap::fromImage(pm)); + ui->lable_test->setPixmap(QPixmap::fromImage(pm)) ; ui->lable_test->setScaledContents(true); ui->lable_test->resize(pm.size()); pm.save("test.bmp"); } - -void MainWindow::on_AngleSlider_sliderMoved(int position) -{ - double angleT = 360. / 100 * position; - ui->lable_angle->setText(std::to_string(angleT).c_str()); - info.ginfo.setAngleDegrees(angleT); - this->on_RenderPic_clicked(); -} - -void MainWindow::on_OffsetSlider_sliderMoved(int position) -{ - double offset = ((double)position - 50.0) / 25.0; - ui->lable_offset->setText(std::to_string(offset).c_str()); - info.ginfo.linoffset = offset; - this->on_RenderPic_clicked(); -} - -void MainWindow::on_StretchSlide_sliderMoved(int position) -{ - double stretch = pow(2.0, (position - 50.) / 25.0); - ui->lable_stretch->setText(std::to_string(stretch).c_str()); - info.ginfo.linstretch = stretch; - this->on_RenderPic_clicked(); -} - -void MainWindow::on_DiscreteStepSlider_sliderMoved(int position) -{ - if (position == 0) { - info.ginfo.discrete_step = 0.0; - ui->label_discrete->setText("Continious"); - this->on_RenderPic_clicked(); - return; - } - info.ginfo.setStepByNum(position); - ui->label_discrete->setText(std::to_string(position).c_str()); - this->on_RenderPic_clicked(); -} - -void MainWindow::on_PathType_itemDoubleClicked(QListWidgetItem *item) -{ - on_PathType_itemClicked(item); - on_RenderPic_clicked(); -} - -void MainWindow::on_PathType_itemClicked(QListWidgetItem *item) -{ - if (item->text() == "Circle") { - points = drawCircle1(100, 53, 53, 50); - } - else if (item->text() == "Square") { - points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; - } - else if (item->text() == "Triangle") { - points = {{5, 10}, {40, 100}, {100, 1}}; - /* - * Пока чтобы тестить прямую интерполяцию цвета, нужно редактировать код - * И вычтавить info.ginfo.shading.shading_type как NSStructures::ShadingInfo::TriangleInterpolation - * Чтобы тестить параметрическую нужно выставить NSStructures::ShadingInfo::Parametric - * С опцией Parametric можно тестить другие градиенты. - * - */ - info.gradient_type = c_BrushTypeTriagnleMeshGradient; - info.ginfo.shading.shading_type = NSStructures::ShadingInfo::Parametric; - info.ginfo.shading.triangle = {{5 * 3.84, 10 * 3.84}, {40 * 3.84, 100 * 3.84}, {100 * 3.84, 1 * 3.84}}; - info.ginfo.shading.triangle_parameters = {0.0f, 0.5f, 1.0f} ; - info.ginfo.shading.triangle_colors = {{255,0,0, 255}, {255,255,0,255 }, {0,255,0,255}}; - - - } - else if (item->text() == "Patch") { - points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; - info.gradient_type = c_BrushTypeTensorCurveGradient ; - info.ginfo.shading.shading_type = NSStructures::ShadingInfo::CurveInterpolation; - info.ginfo.shading.patch = { - {{10, 80}, {20, 70}, {0, 20}, {10,10}}, - {{25, 75}, {40, 60}, {40, 40}, {20, 0}}, - {{90, 70}, {60,60}, {60, 40}, {70, 20}}, - {{80,80}, {40, 40}, {130, 70}, {80,10}} - }; - info.ginfo.shading.patch_parameters = { - {0 , 1}, - {1, 0.5} - }; - info.ginfo.shading.patch_colors = { - {{255, 0, 0}, {150, 255, 255}}, - {{0, 255, 0}, {0, 0, 255}} - }; - float mult = 4.0; - for (int i = 0; i < info.ginfo.shading.patch.size(); i++) - { - for (int j = 0; j < info.ginfo.shading.patch[0].size(); j++) - { - info.ginfo.shading.patch[i][j] = info.ginfo.shading.patch[i][j] * mult; - } - } - } -} - void MainWindow::on_GradientType_itemDoubleClicked(QListWidgetItem *item) { on_GradientType_itemClicked(item); @@ -212,68 +114,98 @@ void MainWindow::on_GradientType_itemDoubleClicked(QListWidgetItem *item) void MainWindow::on_GradientType_itemClicked(QListWidgetItem *item) { + points = {{0, 0}, {105, 0}, {105, 105}, {0, 105}}; if (item->text() == "Linear") { info.gradient_type = c_BrushTypePathNewLinearGradient; + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); } else if (item->text() == "Radial") { info.gradient_type = c_BrushTypePathRadialGradient; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); } - else if (item->text() == "Diamond") { - info.gradient_type = c_BrushTypePathDiamondGradient; + else if (item->text() == "Triangle") { + info.gradient_type = c_BrushTypeTriagnleMeshGradient; + info.ginfo = NSStructures::GInfoConstructor::get_triangle( + {{100, 100}, {300, 200}, {200, 350}}, + {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, + {}, false + ); + points = {{100 / 3.84, 100 / 3.84}, {300 / 3.84, 200 / 3.84}, {200 / 3.84, 350 / 3.84}}; } - else if (item->text() == "Conical") { - info.gradient_type = c_BrushTypePathConicalGradient; + else if (item->text() == "Functional" ) { + info.ginfo = NSStructures::GInfoConstructor::get_functional(0, 1, 0, 1, + {400, 0, 0, 400, 0, 0}); + } + else if (item->text() == "TriangleParametric" ) { + info.gradient_type = c_BrushTypeTriagnleMeshGradient; + info.ginfo = NSStructures::GInfoConstructor::get_triangle( + {{100, 100}, {300, 200}, {200, 350}}, + {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}, + {0, 0.4, 1}, true + ); + points = {{100 / 3.84, 100 / 3.84}, {300 / 3.84, 200 / 3.84}, {200 / 3.84, 350 / 3.84}}; + } + else if (item->text() == "CoonsPatch" ) { + info.gradient_type = c_BrushTypePathNewLinearGradient; + info.ginfo = NSStructures::GInfoConstructor::get_curve( + { + {100, 300}, {50, 250}, {150, 150}, {100, 100}, + {150, 50}, {250, 150}, {300, 100}, {250, 150}, + {350, 250}, {300, 300}, {250, 350}, {150,250} + }, + {0, 0.5, 1, 0.5}, + {{0, 0, 255}, {255, 0, 255}, + {255, 0, 0}, {0, 255, 0}}, + false + ); + } + else if (item->text() == "TesnorCoonsPatch" ) { + info.gradient_type = c_BrushTypePathNewLinearGradient; + info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve( + { + {{100, 300}, {150, 250}, {50, 150}, {100,100}}, + {{150, 250}, {170, 230}, {170, 170}, {50, 150}}, + {{350, 250}, {230, 230}, {230, 170}, {150, 250}}, + {{300, 300}, {250, 250}, {350, 150}, {300, 100}} + }, + {{0, 0.5}, {1, 0.5}}, + {{{0, 0, 255}, {255, 0, 255}}, {{255, 0, 0}, {0, 255, 0}}}, + false + ); + } + else if (item->text() == "CoonsPatchParametric") { + info.gradient_type = c_BrushTypeCurveGradient; + info.ginfo = NSStructures::GInfoConstructor::get_curve( + { + {100, 300}, {50, 250}, {150, 150}, {100, 100}, + {150, 50}, {250, 150}, {300, 100}, {250, 150}, + {350, 250}, {300, 300}, {250, 350}, {150,250} + }, + {0, 0.5, 1, 0.5}, + {{0, 0, 255}, {255, 0, 255}, + {255, 0, 0}, {0, 255, 0}}, + true + ); + } + else if (item->text() == "TensorCoonsPatchParametric") { + info.gradient_type = c_BrushTypeTensorCurveGradient; + info.ginfo = NSStructures::GInfoConstructor::get_tensor_curve( + { + {{100, 300}, {150, 250}, {50, 150}, {100,100}}, + {{150, 250}, {170, 230}, {170, 170}, {50, 150}}, + {{350, 250}, {230, 230}, {230, 170}, {150, 250}}, + {{300, 300}, {250, 250}, {350, 150}, {300, 100}} + }, + {{0, 0.5}, {1, 0.5}}, + {{{0, 0, 255}, {255, 0, 255}}, {{255, 0, 0}, {0, 255, 0}}}, + true + ); } } -void MainWindow::on_LittleRadiusSlider_sliderMoved(int position) -{ - double llr = (double)position / 100.0; - ui->lable_little_radius->setText(std::to_string(llr).c_str()); - info.ginfo.littleRadius = llr; - this->on_RenderPic_clicked(); -} -void MainWindow::on_LargeRadiusSlider_sliderMoved(int position) -{ - double lgr = (double)position / 100.0; - ui->lable_large_radius->setText(std::to_string(lgr).c_str()); - info.ginfo.largeRadius = lgr; - this->on_RenderPic_clicked(); -} - -void MainWindow::on_xcenterSlider_sliderMoved(int position) -{ - double xc = ((double)position - 50.0) / 25.0; - ui->lable_xcenter->setText(std::to_string(xc).c_str()); - info.ginfo.centerX = xc; - this->on_RenderPic_clicked(); -} - -void MainWindow::on_ycenterSlider_sliderMoved(int position) -{ - double yc = ((double)position - 50.0) / 25.0; - ui->lable_ycenter->setText(std::to_string(yc).c_str()); - info.ginfo.centerY = yc; - this->on_RenderPic_clicked(); -} - -void MainWindow::on_XSizeSlider_sliderMoved(int position) -{ - double xsize = pow(2.0, (position - 50.) / 25.0); - ui->lable_xsize->setText(std::to_string(xsize).c_str()); - info.ginfo.xsize = xsize; - this->on_RenderPic_clicked(); -} - -void MainWindow::on_YSizeSlider_sliderMoved(int position) -{ - double ysize = pow(2.0, (position - 50.) / 25.0); - ui->lable_ysize->setText(std::to_string(ysize).c_str()); - info.ginfo.ysize = ysize; - this->on_RenderPic_clicked(); -} void MainWindow::on_ColorSpaces_itemClicked(QListWidgetItem *item) { @@ -311,9 +243,122 @@ void MainWindow::on_ColorSpaces_itemDoubleClicked(QListWidgetItem *item) on_RenderPic_clicked(); } -void MainWindow::on_Reflected_CheckBox_clicked(bool checked) + +void MainWindow::on_Point1X_sliderMoved(int position) { - info.ginfo.continue_shading = checked; + info.p0.x= position; + if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); on_RenderPic_clicked(); } +void MainWindow::on_Point1Y_sliderMoved(int position) +{ + info.p0.y = position; + if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_Point2X_sliderMoved(int position) +{ + info.p1.x = position; + if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_Point2Y_sliderMoved(int position) +{ + info.p1.y = position; + if (info.gradient_type != c_BrushTypePathNewLinearGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + + +void MainWindow::on_CenterX0_valueChanged(int value) +{ + info.c0.x = value; + if (info.gradient_type != c_BrushTypePathRadialGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_CenterY0_valueChanged(int value) +{ + info.c0.y = value; + if (info.gradient_type != c_BrushTypePathRadialGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_CenterX1_valueChanged(int value) +{ + info.c1.x = value; + if (info.gradient_type != c_BrushTypePathRadialGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_CenterY1_valueChanged(int value) +{ + info.c1.y= value; + if (info.gradient_type != c_BrushTypePathRadialGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_r0slider_valueChanged(int value) +{ + info.r0 = value; + if (info.gradient_type != c_BrushTypePathRadialGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_r1slider_valueChanged(int value) +{ + info.r1 = value; + if (info.gradient_type != c_BrushTypePathRadialGradient) return; + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); +} + +void MainWindow::on_ContinueForvard_clicked(bool checked) +{ + info.cont_f= checked; + if (info.gradient_type == c_BrushTypePathNewLinearGradient) + { + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); + } + if (info.gradient_type == c_BrushTypePathRadialGradient) + { + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); + } +} + +void MainWindow::on_ContinueBack_clicked(bool checked) +{ + info.cont_b = checked; + if (info.gradient_type == c_BrushTypePathNewLinearGradient) + { + info.ginfo = NSStructures::GInfoConstructor::get_linear(info.p0, info.p1, 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); + } + if (info.gradient_type == c_BrushTypePathRadialGradient) + { + info.ginfo = NSStructures::GInfoConstructor::get_radial(info.c0, info.c1, info.r0, info.r1, + 0, 1, info.cont_b, info.cont_f); + on_RenderPic_clicked(); + } +} diff --git a/Test/Applications/gradient/Gradient/mainwindow.h b/Test/Applications/gradient/Gradient/mainwindow.h index f560a9bae0..38c1514778 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.h +++ b/Test/Applications/gradient/Gradient/mainwindow.h @@ -30,6 +30,13 @@ struct Color { }; struct Info { + // Для теста адаптора все вынес в инфо. + float r0, r1; + NSStructures::Point c0, c1; + NSStructures::Point p0, p1; + bool cont_b, cont_f; + + NSStructures::GradientInfo ginfo; int gradient_type; std::vector c; @@ -40,6 +47,16 @@ struct Info { p = {0.0,0.2,0.4,0.6,0.8,1}; n_colors = 6; ginfo.shading.shading_type = NSStructures::ShadingInfo::Parametric; + + + + r0 = 0; + r1 = 100; + c0 = {200, 200}; + c1 = {200, 200}; + p0 = {0, 0}; + p1 = {400, 400}; + cont_b = cont_f = false; }; ~Info() { } @@ -62,39 +79,37 @@ public: private slots: void on_RenderPic_clicked(); - void on_AngleSlider_sliderMoved(int position); - - void on_OffsetSlider_sliderMoved(int position); - - void on_StretchSlide_sliderMoved(int position); - - void on_DiscreteStepSlider_sliderMoved(int position); - - void on_PathType_itemDoubleClicked(QListWidgetItem *item); - - void on_PathType_itemClicked(QListWidgetItem *item); - void on_GradientType_itemDoubleClicked(QListWidgetItem *item); void on_GradientType_itemClicked(QListWidgetItem *item); - void on_LittleRadiusSlider_sliderMoved(int position); - - void on_LargeRadiusSlider_sliderMoved(int position); - - void on_XSizeSlider_sliderMoved(int position); - - void on_ycenterSlider_sliderMoved(int position); - - void on_xcenterSlider_sliderMoved(int position); - - void on_YSizeSlider_sliderMoved(int position); - void on_ColorSpaces_itemClicked(QListWidgetItem *item); void on_ColorSpaces_itemDoubleClicked(QListWidgetItem *item); - void on_Reflected_CheckBox_clicked(bool checked); + void on_Point1X_sliderMoved(int position); + + void on_Point1Y_sliderMoved(int position); + + void on_Point2X_sliderMoved(int position); + + void on_Point2Y_sliderMoved(int position); + + void on_CenterX0_valueChanged(int value); + + void on_CenterY0_valueChanged(int value); + + void on_CenterX1_valueChanged(int value); + + void on_CenterY1_valueChanged(int value); + + void on_r0slider_valueChanged(int value); + + void on_r1slider_valueChanged(int value); + + void on_ContinueForvard_clicked(bool checked); + + void on_ContinueBack_clicked(bool checked); private: Ui::MainWindow *ui; diff --git a/Test/Applications/gradient/Gradient/mainwindow.ui b/Test/Applications/gradient/Gradient/mainwindow.ui index f86eabdb61..669b64e5f0 100644 --- a/Test/Applications/gradient/Gradient/mainwindow.ui +++ b/Test/Applications/gradient/Gradient/mainwindow.ui @@ -52,412 +52,23 @@ false - - - - 610 - 10 - 91 - 21 - - - - Set Params - - - - - - 470 - 460 - 211 - 21 - - - - 100 - - - Qt::Horizontal - - - - - - 470 - 440 - 58 - 16 - - - - Angle - - - - - - 530 - 440 - 58 - 16 - - - - - - - - - - 470 - 410 - 211 - 16 - - - - 100 - - - 50 - - - Qt::Horizontal - - - - - - 470 - 380 - 58 - 16 - - - - LinOffset - - - - - - 550 - 380 - 58 - 16 - - - - - - - - - - 470 - 350 - 211 - 16 - - - - 100 - - - 50 - - - Qt::Horizontal - - - - - - 470 - 320 - 58 - 16 - - - - Stretch - - - - - - 550 - 320 - 58 - 16 - - - - - - - - - - 750 - 320 - 16 - 160 - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - 810 - 320 - 16 - 160 - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - 470 - 290 - 211 - 16 - - - - 100 - - - Qt::Horizontal - - - - - - 470 - 230 - 211 - 16 - - - - 100 - - - 100 - - - Qt::Horizontal - - - - - - 470 - 170 - 211 - 16 - - - - 100 - - - Qt::Horizontal - - - - - - 730 - 300 - 58 - 16 - - - - xsize - - - - - - 800 - 300 - 58 - 16 - - - - ysize - - - - - - 697 - 280 - 161 - 20 - - - - Qt::Horizontal - - - - - - 470 - 260 - 81 - 16 - - - - LittleRadius - - - - - - 570 - 260 - 58 - 16 - - - - - - - - - - 470 - 200 - 81 - 16 - - - - LargeRadius - - - - - - 580 - 200 - 58 - 16 - - - - - - - - - - 470 - 140 - 81 - 16 - - - - DiscreteStep - - - - - - 580 - 140 - 81 - 16 - - - - - - - - - - 750 - 110 - 16 - 160 - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - 810 - 110 - 16 - 160 - - - - 100 - - - 50 - - - Qt::Vertical - - 20 400 - 81 + 171 161 - Linear + Functional - Diamond + Linear @@ -467,7 +78,32 @@ - Conical + Triangle + + + + + CoonsPatch + + + + + TesnorCoonsPatch + + + + + TriangleParametric + + + + + CoonsPatchParametric + + + + + TensorCoonsPatchParametric @@ -484,127 +120,6 @@ Gradient Type - - - - 120 - 400 - 71 - 161 - - - - - Square - - - - - Patch - - - - - Circle - - - - - Triangle - - - - - - - 130 - 570 - 58 - 16 - - - - Path - - - - - - 730 - 90 - 58 - 16 - - - - xcenter - - - - - - 790 - 90 - 58 - 16 - - - - ycenter - - - - - - 750 - 270 - 58 - 16 - - - - 1 - - - - - - 810 - 270 - 58 - 16 - - - - 1 - - - - - - 750 - 480 - 58 - 16 - - - - 1 - - - - - - 810 - 480 - 51 - 20 - - - - 1 - - @@ -635,25 +150,6 @@ - - - true - - - - 600 - 80 - 81 - 22 - - - - Continue - - - true - - @@ -680,6 +176,252 @@ Double Click to change + + + + 460 + 30 + 160 + 16 + + + + 400 + + + Qt::Horizontal + + + + + + 460 + 60 + 160 + 16 + + + + 400 + + + Qt::Horizontal + + + + + + 460 + 90 + 160 + 16 + + + + 400 + + + 400 + + + Qt::Horizontal + + + + + + 460 + 120 + 160 + 16 + + + + 400 + + + 400 + + + Qt::Horizontal + + + + + + 460 + 10 + 151 + 18 + + + + Points XY Linear + + + + + + 740 + 170 + 58 + 18 + + + + r0 r1 + + + + + + 720 + 200 + 160 + 16 + + + + 200 + + + Qt::Horizontal + + + + + + 720 + 230 + 160 + 16 + + + + 200 + + + 100 + + + Qt::Horizontal + + + + + + 720 + 30 + 160 + 16 + + + + 400 + + + 200 + + + Qt::Horizontal + + + + + + 720 + 60 + 160 + 16 + + + + 400 + + + 200 + + + Qt::Horizontal + + + + + + 720 + 90 + 160 + 16 + + + + 400 + + + 200 + + + Qt::Horizontal + + + + + + 720 + 120 + 160 + 16 + + + + 400 + + + 200 + + + Qt::Horizontal + + + + + + 740 + 10 + 131 + 18 + + + + CenterXY Radial + + + + + + 380 + 420 + 141 + 24 + + + + Continue Forward + + + + + + 380 + 460 + 141 + 24 + + + + Continue Back + +