| #include "ext/NotSymmetricBezierPotential.h" |
| #include "tstroke.h" |
| |
| #include <tmathutil.h> |
| #include <tcurves.h> |
| |
| #include <algorithm> |
| |
| using namespace std; |
| |
| using namespace std; |
| using namespace ToonzExt; |
| |
| |
| namespace { |
| typedef unary_function<double, double> unary_functionDD; |
| |
| |
| |
| class myBlendFunc : unary_functionDD { |
| |
| TQuadratic curve; |
| |
| public: |
| myBlendFunc(double t = 0.0) { |
| curve.setP0(TPointD(0.0, 1.0)); |
| curve.setP1(TPointD(0.5 * (1.0 - t), 1.0)); |
| curve.setP2(TPointD(1.0, 0.0)); |
| } |
| |
| result_type operator()(argument_type x) { |
| result_type out = 0.0; |
| x = fabs(x); |
| if (x >= 1.0) return 0.0; |
| out = curve.getPoint(x).y; |
| return out; |
| } |
| }; |
| } |
| |
| |
| |
| ToonzExt::NotSymmetricBezierPotential::~NotSymmetricBezierPotential() {} |
| |
| |
| |
| void ToonzExt::NotSymmetricBezierPotential::setParameters_(const TStroke *ref, |
| double w, |
| double al) { |
| assert(ref); |
| ref_ = ref; |
| par_ = w; |
| actionLength_ = al; |
| |
| strokeLength_ = ref->getLength(); |
| lengthAtParam_ = ref->getLength(par_); |
| |
| |
| leftFactor_ = min(lengthAtParam_, |
| actionLength_ * 0.5); |
| |
| |
| rightFactor_ = min(strokeLength_ - lengthAtParam_, actionLength_ * 0.5); |
| } |
| |
| |
| |
| double ToonzExt::NotSymmetricBezierPotential::value_(double value2test) const { |
| assert(0.0 <= value2test && value2test <= 1.0); |
| return this->compute_value(value2test); |
| } |
| |
| |
| |
| |
| double ToonzExt::NotSymmetricBezierPotential::compute_shape( |
| double value2test) const { |
| double x = ref_->getLength(value2test); |
| double shape = this->actionLength_ * 0.5; |
| if (isAlmostZero(shape)) shape = 1.0; |
| x = (x - lengthAtParam_) / shape; |
| return x; |
| } |
| |
| |
| |
| double ToonzExt::NotSymmetricBezierPotential::compute_value( |
| double value2test) const { |
| myBlendFunc me; |
| |
| |
| |
| |
| |
| |
| |
| double x = 0.0; |
| double res = 0.0; |
| |
| |
| x = ref_->getLength(value2test); |
| |
| const double tolerance = 0.0; |
| |
| |
| if (max(lengthAtParam_, 0.0) < tolerance || |
| max(strokeLength_ - lengthAtParam_, 0.0) < tolerance) { |
| double tmp_al = actionLength_ * 0.5; |
| |
| |
| |
| |
| |
| |
| |
| if (leftFactor_ <= tolerance) |
| x = 1.0 - x / tmp_al; |
| else |
| x = (x - (strokeLength_ - tmp_al)) / tmp_al; |
| |
| if (x < 0.0) return 0.0; |
| assert(0.0 <= x && x <= 1.0 + TConsts::epsilon); |
| x = std::min(x, 1.0); |
| res = sq(x); |
| } else |
| { |
| double length_at_value2test = ref_->getLength(value2test); |
| |
| const double min_level = 0.01; |
| |
| if (length_at_value2test >= lengthAtParam_) { |
| |
| double tmp_x = this->compute_shape(1.0); |
| double tmp_res = me(tmp_x); |
| if (tmp_res > min_level) { |
| |
| |
| |
| if (rightFactor_ != 0.0) |
| x = (length_at_value2test - lengthAtParam_) / rightFactor_; |
| else |
| x = 0.0; |
| |
| assert(0.0 - TConsts::epsilon <= x && x <= 1.0 + TConsts::epsilon); |
| if (isAlmostZero(x)) x = 0.0; |
| if (areAlmostEqual(x, 1.0)) x = 1.0; |
| |
| double how_many_of_shape = |
| (strokeLength_ - lengthAtParam_) / (actionLength_ * 0.5); |
| assert(0.0 <= how_many_of_shape && how_many_of_shape <= 1.0); |
| |
| myBlendFunc bf(how_many_of_shape); |
| |
| return bf(x); |
| } |
| } else { |
| |
| double tmp_x = this->compute_shape(0.0); |
| double tmp_res = me(tmp_x); |
| if (tmp_res > min_level) { |
| double x = length_at_value2test / leftFactor_; |
| assert(0.0 <= x && x <= 1.0); |
| |
| |
| double diff = x - 1.0; |
| |
| double how_many_of_shape = lengthAtParam_ / (actionLength_ * 0.5); |
| assert(0.0 <= how_many_of_shape && how_many_of_shape <= 1.0); |
| |
| myBlendFunc bf(how_many_of_shape); |
| return bf(diff); |
| } |
| } |
| |
| |
| x = this->compute_shape(value2test); |
| res = me(x); |
| } |
| return res; |
| } |
| |
| |
| |
| ToonzExt::Potential *ToonzExt::NotSymmetricBezierPotential::clone() { |
| return new NotSymmetricBezierPotential; |
| } |
| |
| |
| |
| |