|
Toshihiro Shimizu |
890ddd |
#include "ext/NotSimmetricBezierPotential.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <tmathutil.h></tmathutil.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <tcurves.h></tcurves.h>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <algorithm></algorithm>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
using namespace ToonzExt;
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
typedef unary_function<double, double=""> unary_functionDD;</double,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class myBlendFunc : unary_functionDD {
|
|
Shinya Kitaoka |
120a6e |
// TCubic c;
|
|
Shinya Kitaoka |
120a6e |
TQuadratic curve;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
myBlendFunc(double t = 0.0) {
|
|
Shinya Kitaoka |
120a6e |
curve.setP0(TPointD(0.0, 1.0));
|
|
Shinya Kitaoka |
120a6e |
curve.setP1(TPointD(0.5 * (1.0 - t), 1.0));
|
|
Shinya Kitaoka |
120a6e |
curve.setP2(TPointD(1.0, 0.0));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
result_type operator()(argument_type x) {
|
|
Shinya Kitaoka |
120a6e |
result_type out = 0.0;
|
|
Shinya Kitaoka |
120a6e |
x = fabs(x);
|
|
Shinya Kitaoka |
120a6e |
if (x >= 1.0) return 0.0;
|
|
Shinya Kitaoka |
120a6e |
out = curve.getPoint(x).y;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::NotSimmetricBezierPotential::~NotSimmetricBezierPotential() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToonzExt::NotSimmetricBezierPotential::setParameters_(const TStroke *ref,
|
|
Shinya Kitaoka |
120a6e |
double w,
|
|
Shinya Kitaoka |
120a6e |
double al) {
|
|
Shinya Kitaoka |
120a6e |
assert(ref);
|
|
Shinya Kitaoka |
120a6e |
ref_ = ref;
|
|
Shinya Kitaoka |
120a6e |
par_ = w;
|
|
Shinya Kitaoka |
120a6e |
actionLength_ = al;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
strokeLength_ = ref->getLength();
|
|
Shinya Kitaoka |
120a6e |
lenghtAtParam_ = ref->getLength(par_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// lunghezza dal pto di click all'inizio della curva
|
|
Shinya Kitaoka |
120a6e |
leftFactor_ = min(lenghtAtParam_,
|
|
Shinya Kitaoka |
120a6e |
actionLength_ * 0.5); // lenghtAtParam_ / strokeLength_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// lunghezza dal pto di click alla fine
|
|
Shinya Kitaoka |
120a6e |
rightFactor_ = min(strokeLength_ - lenghtAtParam_, actionLength_ * 0.5);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double ToonzExt::NotSimmetricBezierPotential::value_(double value2test) const {
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 <= value2test && value2test <= 1.0);
|
|
Shinya Kitaoka |
120a6e |
return this->compute_value(value2test);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// normalization of parameter in range interval
|
|
Shinya Kitaoka |
120a6e |
double ToonzExt::NotSimmetricBezierPotential::compute_shape(
|
|
Shinya Kitaoka |
120a6e |
double value2test) const {
|
|
Shinya Kitaoka |
120a6e |
double x = ref_->getLength(value2test);
|
|
Shinya Kitaoka |
120a6e |
double shape = this->actionLength_ * 0.5;
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(shape)) shape = 1.0;
|
|
Shinya Kitaoka |
120a6e |
x = (x - lenghtAtParam_) / shape;
|
|
Shinya Kitaoka |
120a6e |
return x;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double ToonzExt::NotSimmetricBezierPotential::compute_value(
|
|
Shinya Kitaoka |
120a6e |
double value2test) const {
|
|
Shinya Kitaoka |
120a6e |
myBlendFunc me;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// on extremes use
|
|
Shinya Kitaoka |
120a6e |
// 2
|
|
Shinya Kitaoka |
120a6e |
// 1-x
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// when is near to extreme uses a mix notation
|
|
Shinya Kitaoka |
120a6e |
double x = 0.0;
|
|
Shinya Kitaoka |
120a6e |
double res = 0.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// lenght at parameter
|
|
Shinya Kitaoka |
120a6e |
x = ref_->getLength(value2test);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const double tolerance = 0.0; // need to be pixel based
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if is an extreme
|
|
Shinya Kitaoka |
120a6e |
if (max(lenghtAtParam_, 0.0) < tolerance ||
|
|
Shinya Kitaoka |
120a6e |
max(strokeLength_ - lenghtAtParam_, 0.0) < tolerance) {
|
|
Shinya Kitaoka |
120a6e |
double tmp_al = actionLength_ * 0.5;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// compute correct parameter considering offset
|
|
Shinya Kitaoka |
120a6e |
// try to have a square curve like shape
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
// 2
|
|
Shinya Kitaoka |
120a6e |
// m = x
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
if (leftFactor_ <= tolerance)
|
|
Shinya Kitaoka |
120a6e |
x = 1.0 - x / tmp_al;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
x = (x - (strokeLength_ - tmp_al)) / tmp_al;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (x < 0.0) return 0.0;
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 <= x && x <= 1.0 + TConsts::epsilon);
|
|
Shinya Kitaoka |
120a6e |
x = std::min(x, 1.0); // just to avoid problem in production code
|
|
Shinya Kitaoka |
120a6e |
res = sq(x);
|
|
Shinya Kitaoka |
120a6e |
} else // when is not an extreme
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double lenght_at_value2test = ref_->getLength(value2test);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const double min_level = 0.01;
|
|
Shinya Kitaoka |
120a6e |
// if check a parameter over click point
|
|
Shinya Kitaoka |
120a6e |
if (lenght_at_value2test >= lenghtAtParam_) {
|
|
Shinya Kitaoka |
120a6e |
// check if extreme can be moved from this parameter configuration
|
|
Shinya Kitaoka |
120a6e |
double tmp_x = this->compute_shape(1.0);
|
|
Shinya Kitaoka |
120a6e |
double tmp_res = me(tmp_x);
|
|
Shinya Kitaoka |
120a6e |
if (tmp_res > min_level) {
|
|
Shinya Kitaoka |
120a6e |
// please note that in this case
|
|
Shinya Kitaoka |
120a6e |
// lenghtAtParam_ + rightFactor_ == strokeLength_
|
|
Shinya Kitaoka |
120a6e |
// (by ctor).
|
|
Shinya Kitaoka |
120a6e |
if (rightFactor_ != 0.0)
|
|
Shinya Kitaoka |
120a6e |
x = (lenght_at_value2test - lenghtAtParam_) / rightFactor_;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
x = 0.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 - TConsts::epsilon <= x && x <= 1.0 + TConsts::epsilon);
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(x)) x = 0.0;
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(x, 1.0)) x = 1.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double how_many_of_shape =
|
|
Shinya Kitaoka |
120a6e |
(strokeLength_ - lenghtAtParam_) / (actionLength_ * 0.5);
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 <= how_many_of_shape && how_many_of_shape <= 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myBlendFunc bf(how_many_of_shape);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return bf(x);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// leftFactor_
|
|
Shinya Kitaoka |
120a6e |
double tmp_x = this->compute_shape(0.0);
|
|
Shinya Kitaoka |
120a6e |
double tmp_res = me(tmp_x);
|
|
Shinya Kitaoka |
120a6e |
if (tmp_res > min_level) {
|
|
Shinya Kitaoka |
120a6e |
double x = lenght_at_value2test / leftFactor_;
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 <= x && x <= 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// then movement use another shape
|
|
Shinya Kitaoka |
120a6e |
double diff = x - 1.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double how_many_of_shape = lenghtAtParam_ / (actionLength_ * 0.5);
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 <= how_many_of_shape && how_many_of_shape <= 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myBlendFunc bf(how_many_of_shape);
|
|
Shinya Kitaoka |
120a6e |
return bf(diff);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// default behaviour is an exp
|
|
Shinya Kitaoka |
120a6e |
x = this->compute_shape(value2test);
|
|
Shinya Kitaoka |
120a6e |
res = me(x);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return res;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Potential *ToonzExt::NotSimmetricBezierPotential::clone() {
|
|
Shinya Kitaoka |
120a6e |
return new NotSimmetricBezierPotential;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// End Of File
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|