Subversion Repositories DIN Is Noise

Rev

Rev 2197 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* warper.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/



#include "warper.h"
#include "vector2d.h"
#include "ui_list.h"
#include "console.h"

#include <vector>
using namespace std;

extern ui_list uis;

warper::warper () : x ("warpx.crv"), y ("warpy.crv"), ed ("warper.ed") {
  ed.add (&x, &lis);
  ed.add (&y, &lis);
  back_ed = 0;
  name = "Warper";
}

warper::~warper () {
  x.save ("warpx.crv");
  y.save ("warpy.crv");
  widget_save ("d_warper", ctrls);
}

void warper::setup () {

  plugin::setup ();

  ctrls.push_back (&b_edit);
  num_ctrls = ctrls.size ();

  b_edit.set_text ("Edit");

  widget_load ("d_warper", ctrls);

  b_edit.set_listener (this);

  for (int i = 0; i < num_ctrls; ++i) {
    widget* ci = ctrls[i];
    if (ci != &cb_auto_apply) ci->set_color (clr.r, clr.g, clr.b);
  }


  solx (&x);
  soly (&y);

  lis.wp = this;

}

void warper::clicked (button& b) {
  if (&b == &b_edit) {
    if (b_edit.text == "Edit") {
      b_edit.set_text ("Go back");
      back_ed = uis.crved;
      uis.set_current (&ed);
    } else {
      uis.set_current (back_ed);
      b_edit.set_text ("Edit");
    }
  } else plugin::clicked (b);
}

void warper::warp (float& x, float& y, const box<float>& bbox) {
  // normalise
  float nx = (x - bbox.left) * bbox.width_1;
  float ny = (y - bbox.bottom) * bbox.height_1;
  // warp
  float wx = solx (nx);
  float wy = soly (ny);
  // remap
  x = bbox.left + wx * bbox.width;
  y = bbox.bottom + wy * bbox.height;
}

void warper::render () {}

int warper::apply (multi_curve& in) {

  // warp vertices, left and right tangents and evaluate
  //
  points_array& v = in.vertices;
  points_array& lt = in.left_tangents;
  points_array& rt = in.right_tangents;
  int n = v.size ();
  if (n < 2) return 0;

  box<float> bbox;
  in.calc_bbox (bbox);

  for (int i = 0; i < n; ++i) {
    point<float>& vi = v[i];
    point<float>& lti = lt[i];
    point<float>& rti = rt[i];
    warp (vi.x, vi.y, bbox);
    warp (lti.x, lti.y, bbox);
    warp (rti.x, rti.y, bbox);
  }  

  for (int i = 0, j = n - 1; i < j; ++i) in.curv[i].eval = 1;
  in.evaluate ();

  return 1;

}

void warper::draw (curve_editor* ed) {}

void warp_listener::edited (curve_editor* ed, int i) {
  multi_curve* crv = ed->get_curve (i);
  if (crv == &wp->x) wp->solx (&wp->x); else wp->soly (&wp->y);
  if (wp->cb_auto_apply.state) {
    multi_curve& in = *wp->back_ed->get_picked_curve ();
    wp->apply (in);
  }
}