|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/**
|
|
Toshihiro Shimizu |
890ddd |
* @author Fabrizio Morciano <fabrizio.morciano@gmail.com></fabrizio.morciano@gmail.com>
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
#define _STLP_DEBUG 1
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/StrokeDeformationImpl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/StrokeDeformation.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/SquarePotential.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/StrokeParametricDeformer.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "ext/NotSimmetricBezierPotential.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/ContextStatus.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/Designer.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "ext/TriParam.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <tcurves.h></tcurves.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <tstrokeutil.h></tstrokeutil.h>
|
|
Toshihiro Shimizu |
890ddd |
//#include <tvectorimage.h></tvectorimage.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <tmathutil.h></tmathutil.h>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <algorithm></algorithm>
|
|
Toshihiro Shimizu |
890ddd |
#include <iterator></iterator>
|
|
Toshihiro Shimizu |
890ddd |
#include <vector></vector>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "DeformationSelector.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace ToonzExt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
* Avoid to reduce curves with great zoom out.
|
|
Toshihiro Shimizu |
890ddd |
* assert that pixelSize and factor > 0.0
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
double computeReductionFactor(double pixelSize, double factor) {
|
|
Shinya Kitaoka |
120a6e |
assert(pixelSize > 0.0 && factor > 0.0);
|
|
Shinya Kitaoka |
120a6e |
if (factor <= 0.0) factor = 1.0;
|
|
Shinya Kitaoka |
120a6e |
if (pixelSize <= 0.0 || pixelSize > 1.0) pixelSize = 1.0;
|
|
Shinya Kitaoka |
120a6e |
return pixelSize * factor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
double retrieveParamAtLengthWithOffset(const TStroke *stroke2change,
|
|
Shinya Kitaoka |
120a6e |
double length, // = 0.5 * strokeLength,
|
|
Shinya Kitaoka |
120a6e |
double offset) {
|
|
Shinya Kitaoka |
120a6e |
if (!isValid(stroke2change) || !isValid(offset) || length < 0) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double strokeLength = stroke2change->getLength();
|
|
Shinya Kitaoka |
120a6e |
assert(strokeLength >= 0.0 && "Not valid length");
|
|
Shinya Kitaoka |
120a6e |
if (strokeLength < 0) {
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double lengthAtW = stroke2change->getLength(offset);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(strokeLength >= lengthAtW &&
|
|
Shinya Kitaoka |
120a6e |
"Position of parameter is greater than stroke length!!!");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (strokeLength < lengthAtW) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double newLength = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (stroke2change->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
if (length >= 0)
|
|
Shinya Kitaoka |
120a6e |
newLength = length > lengthAtW ? length + lengthAtW : lengthAtW - length;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
newLength = std::min(length + lengthAtW, strokeLength);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return stroke2change->getParameterAtLength(newLength);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool rotateStroke(const TStroke *stroke2change, TStroke *&rotated, double &from,
|
|
Shinya Kitaoka |
120a6e |
double &to, TPointD &old_w0_pos) {
|
|
Shinya Kitaoka |
120a6e |
if (!stroke2change || !isValid(from) || !isValid(to)) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rotated = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// save position of w=0 (useful to retrieve this
|
|
Shinya Kitaoka |
120a6e |
// position after changes)
|
|
Shinya Kitaoka |
120a6e |
old_w0_pos = convert(stroke2change->getControlPoint(0));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double rotateAtLength = stroke2change->getLength(to);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(rotateAtLength >= 0.0);
|
|
Shinya Kitaoka |
120a6e |
if (rotateAtLength < 0) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TStroke*
|
|
Shinya Kitaoka |
120a6e |
rotated = ToonzExt::rotateControlPoint(stroke2change, ToonzExt::EvenInt(0),
|
|
Shinya Kitaoka |
120a6e |
rotateAtLength);
|
|
Shinya Kitaoka |
120a6e |
if (!rotated) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
from = rotated->getW(stroke2change->getPoint(from));
|
|
Shinya Kitaoka |
120a6e |
to = rotated->getW(stroke2change->getPoint(to));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// save some other information (style, etc..)
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::cloneStrokeStatus(stroke2change, rotated);
|
|
Shinya Kitaoka |
120a6e |
return true; // rotated;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *rotateControlPointAtPoint(const TStroke *stroke, const TPointD &pnt) {
|
|
Shinya Kitaoka |
120a6e |
if (!stroke || tdistance2(stroke->getPoint(0.0), pnt) < sq(TConsts::epsilon))
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double w = stroke->getW(pnt);
|
|
Shinya Kitaoka |
120a6e |
TPointD theSamePnt = stroke->getPoint(w);
|
|
Shinya Kitaoka |
120a6e |
double length = stroke->getLength(w);
|
|
Shinya Kitaoka |
120a6e |
return ToonzExt::rotateControlPoint(stroke, ToonzExt::EvenInt(0), length);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool findExtremesFromActionLength(double toolActionLength,
|
|
Shinya Kitaoka |
120a6e |
const TStroke *stroke, double w,
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Interval &out) {
|
|
Shinya Kitaoka |
120a6e |
out = ToonzExt::Interval(-1.0, -1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!stroke || 0.0 > w || w > 1.0) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double emiToolSize = 0.5 * toolActionLength;
|
|
Shinya Kitaoka |
120a6e |
double strokelength = stroke->getLength();
|
|
Shinya Kitaoka |
120a6e |
double lengthAtParam = stroke->getLength(w);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(emiToolSize >= 0.0 && strokelength >= 0.0 && lengthAtParam >= 0.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (emiToolSize > strokelength * 0.5) {
|
|
Shinya Kitaoka |
120a6e |
if (stroke->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
emiToolSize = strokelength * 0.5;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// first and second are the same
|
|
Shinya Kitaoka |
120a6e |
lengthAtParam += emiToolSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (lengthAtParam > strokelength) lengthAtParam -= strokelength;
|
|
Shinya Kitaoka |
120a6e |
out.first = out.second = stroke->getParameterAtLength(lengthAtParam);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
out.first = 0.0;
|
|
Shinya Kitaoka |
120a6e |
out.second = 1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (emiToolSize < 0.0 || strokelength < 0.0 || lengthAtParam < 0.0)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// [out] now is length, range 0,length
|
|
Shinya Kitaoka |
120a6e |
out.first = lengthAtParam - emiToolSize;
|
|
Shinya Kitaoka |
120a6e |
out.second = lengthAtParam + emiToolSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (stroke->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
if (out.first < 0.0) {
|
|
Shinya Kitaoka |
120a6e |
out.first = strokelength + out.first;
|
|
Shinya Kitaoka |
120a6e |
assert(out.first < strokelength);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (out.second > strokelength) {
|
|
Shinya Kitaoka |
120a6e |
out.second = out.second - strokelength;
|
|
Shinya Kitaoka |
120a6e |
assert(0.0 < out.second && out.second < strokelength);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
out.first = std::max(out.first, 0.0);
|
|
Shinya Kitaoka |
120a6e |
out.second = std::min(out.second, strokelength);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// [out] now is parameter, range 0,1
|
|
Shinya Kitaoka |
120a6e |
out.first = stroke->getParameterAtLength(out.first);
|
|
Shinya Kitaoka |
120a6e |
out.second = stroke->getParameterAtLength(out.second);
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
if (!stroke->isSelfLoop()) assert(out.first <= out.second);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool areDifferent(const TStroke *ref1, const TStroke *ref2) {
|
|
Shinya Kitaoka |
120a6e |
if (!isValid(ref1) || !isValid(ref2)) return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int cpCount1 = ref1->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int cpCount2 = ref2->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
if (cpCount1 != cpCount2) return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (--cpCount1 >= 0) {
|
|
Shinya Kitaoka |
120a6e |
if (ref1->getControlPoint(cpCount1) != ref2->getControlPoint(cpCount1))
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(cpCount1 == -1);
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *StrokeDeformationImpl::copyOfLastSelectedStroke_ =
|
|
Shinya Kitaoka |
120a6e |
0; // deep copy stroke selected previously
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const ContextStatus *&StrokeDeformationImpl::getImplStatus() {
|
|
Shinya Kitaoka |
120a6e |
// if multi threading this datas need to be serialized
|
|
Shinya Kitaoka |
120a6e |
// a ref to status
|
|
Shinya Kitaoka |
120a6e |
static const ContextStatus *contextStatus_instance;
|
|
Shinya Kitaoka |
120a6e |
return contextStatus_instance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *&StrokeDeformationImpl::getLastSelectedStroke() {
|
|
Shinya Kitaoka |
120a6e |
static TStroke *lastSelectedStroke_instance;
|
|
Shinya Kitaoka |
120a6e |
return lastSelectedStroke_instance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void StrokeDeformationImpl::setLastSelectedStroke(TStroke *stroke) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *&lastSelStroke = getLastSelectedStroke();
|
|
Shinya Kitaoka |
120a6e |
lastSelStroke = stroke;
|
|
Shinya Kitaoka |
120a6e |
if (lastSelStroke) {
|
|
Shinya Kitaoka |
120a6e |
delete copyOfLastSelectedStroke_;
|
|
Shinya Kitaoka |
120a6e |
copyOfLastSelectedStroke_ = new TStroke(*lastSelStroke);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int &StrokeDeformationImpl::getLastSelectedDegree() {
|
|
Shinya Kitaoka |
120a6e |
static int lastSelectedDegree_instance;
|
|
Shinya Kitaoka |
120a6e |
return lastSelectedDegree_instance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void StrokeDeformationImpl::setLastSelectedDegree(int degree) {
|
|
Shinya Kitaoka |
120a6e |
getLastSelectedDegree() = degree;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Intervals &StrokeDeformationImpl::getSpiresList() {
|
|
Shinya Kitaoka |
120a6e |
static ToonzExt::Intervals listOfSpire_instance;
|
|
Shinya Kitaoka |
120a6e |
return listOfSpire_instance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Intervals &StrokeDeformationImpl::getStraightsList() {
|
|
Shinya Kitaoka |
120a6e |
static ToonzExt::Intervals listOfStraight_instance;
|
|
Shinya Kitaoka |
120a6e |
return listOfStraight_instance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
StrokeDeformationImpl::StrokeDeformationImpl() {
|
|
Shinya Kitaoka |
120a6e |
shortcutKey_ = ContextStatus::NONE;
|
|
Shinya Kitaoka |
120a6e |
cursorId_ = -1;
|
|
Shinya Kitaoka |
120a6e |
this->reset();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
StrokeDeformationImpl::~StrokeDeformationImpl() {
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(strokes_);
|
|
Shinya Kitaoka |
120a6e |
delete potential_;
|
|
Shinya Kitaoka |
120a6e |
potential_ = 0;
|
|
Shinya Kitaoka |
120a6e |
delete deformer_;
|
|
Shinya Kitaoka |
120a6e |
deformer_ = 0;
|
|
Shinya Kitaoka |
120a6e |
delete copyOfLastSelectedStroke_;
|
|
Shinya Kitaoka |
120a6e |
copyOfLastSelectedStroke_ = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool StrokeDeformationImpl::activate_impl(const ContextStatus *status) {
|
|
Shinya Kitaoka |
120a6e |
assert(status && "Not status available");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!status || !this->init(status)) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double w = status->w_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Interval extremes = this->getExtremes();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke2transform;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!this->computeStroke2Transform(status, stroke2transform, w, extremes))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// to avoid strange behaviour in limit's value
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(extremes.first, w)) w = extremes.first;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(extremes.second, w)) w = extremes.second;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(extremes.first <= w && w <= extremes.second);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (extremes.first > w || w > extremes.second) {
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> splitParameter;</double>
|
|
Shinya Kitaoka |
120a6e |
splitParameter.push_back(extremes.first);
|
|
Shinya Kitaoka |
120a6e |
splitParameter.push_back(extremes.second);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(strokes_.empty());
|
|
Shinya Kitaoka |
120a6e |
if (!strokes_.empty()) clearPointerContainer(strokes_);
|
|
Shinya Kitaoka |
120a6e |
splitStroke(*stroke2transform, splitParameter, strokes_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(strokes_.size() == 3);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// I don't know how to manage properly this case
|
|
Shinya Kitaoka |
120a6e |
if (strokes_.size() != 3) {
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(strokes_);
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// stroke to change
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_ = strokes_[1];
|
|
Shinya Kitaoka |
120a6e |
assert(stroke2manipulate_ && " Not valid reference to stroke to move!!!");
|
|
Shinya Kitaoka |
120a6e |
if (!stroke2manipulate_) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// remove empty stroke
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TStroke *tmp_stroke = strokes_[2];
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(tmp_stroke->getLength())) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstroke *="">::iterator it = strokes_.begin();</tstroke>
|
|
Shinya Kitaoka |
120a6e |
std::advance(it, 2);
|
|
Shinya Kitaoka |
120a6e |
strokes_.erase(it);
|
|
Shinya Kitaoka |
120a6e |
delete tmp_stroke;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
tmp_stroke = strokes_[0];
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(tmp_stroke->getLength())) {
|
|
Shinya Kitaoka |
120a6e |
strokes_.erase(strokes_.begin());
|
|
Shinya Kitaoka |
120a6e |
delete tmp_stroke;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// little movement of control points to have not empty
|
|
Shinya Kitaoka |
120a6e |
// length
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(stroke2manipulate_->getLength())) {
|
|
Shinya Kitaoka |
120a6e |
int count = stroke2manipulate_->getControlPointCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
assert(count > 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint pnt0 = stroke2manipulate_->getControlPoint(0),
|
|
Shinya Kitaoka |
120a6e |
pntn = stroke2manipulate_->getControlPoint(count),
|
|
Shinya Kitaoka |
120a6e |
delta = TThickPoint(2.0 * TConsts::epsilon,
|
|
Shinya Kitaoka |
120a6e |
-2.0 * TConsts::epsilon, 0.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_->setControlPoint(0, pnt0 - delta);
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_->setControlPoint(count, pntn + delta);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// simple check for empty chunk
|
|
Shinya Kitaoka |
120a6e |
int cp_count = stroke2manipulate_->getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *tq;
|
|
Shinya Kitaoka |
120a6e |
bool haveEmpty = false;
|
|
Shinya Kitaoka |
120a6e |
while (--cp_count >= 0) {
|
|
Shinya Kitaoka |
120a6e |
tq = stroke2manipulate_->getChunk(cp_count);
|
|
Shinya Kitaoka |
120a6e |
// assert( tq->getLength() != 0.0 );
|
|
Shinya Kitaoka |
120a6e |
if (tq->getLength() == 0.0) haveEmpty = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (haveEmpty) {
|
|
Shinya Kitaoka |
120a6e |
const double reductionFactor =
|
|
Shinya Kitaoka |
120a6e |
computeReductionFactor(getImplStatus()->pixelSize_, 1.0);
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_->reduceControlPoints(reductionFactor);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD pntOnStroke = stroke2transform->getPoint(w);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// parameter need to be recomputed to match
|
|
Shinya Kitaoka |
120a6e |
// with new stroke
|
|
Shinya Kitaoka |
120a6e |
w = stroke2manipulate_->getW(pntOnStroke);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// prevStyle_ = stroke2transform->getStyle();
|
|
Shinya Kitaoka |
120a6e |
// set a style for error
|
|
Shinya Kitaoka |
120a6e |
// stroke2manipulate_->setStyle( 4 );
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// in this deformer all stroke need to be moved
|
|
Shinya Kitaoka |
120a6e |
double lengthOfAction = this->findActionLength();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool exception = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
// create a new stroke deformer
|
|
Shinya Kitaoka |
120a6e |
delete deformer_;
|
|
Shinya Kitaoka |
120a6e |
deformer_ = new StrokeParametricDeformer(
|
|
Shinya Kitaoka |
120a6e |
lengthOfAction, w, stroke2manipulate_, potential_->clone());
|
|
Shinya Kitaoka |
120a6e |
} catch (std::invalid_argument &) {
|
|
Shinya Kitaoka |
120a6e |
exception = true;
|
|
Shinya Kitaoka |
120a6e |
assert(!"Invalid argument");
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
exception = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(deformer_ && "Deformer is not available");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (exception) {
|
|
Shinya Kitaoka |
120a6e |
deformer_ = 0;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(getImplStatus() != 0 && "ContextStatus is null???");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!getImplStatus()) {
|
|
Shinya Kitaoka |
120a6e |
delete deformer_;
|
|
Shinya Kitaoka |
120a6e |
this->reset();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// change the threshold value of increser,
|
|
Shinya Kitaoka |
120a6e |
// if value is greater than diff add control points
|
|
Shinya Kitaoka |
120a6e |
deformer_->setDiff(getImplStatus()->deformerSensibility_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// just to be sure to have a control point where
|
|
Shinya Kitaoka |
120a6e |
// stroke is selected
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_->insertControlPoints(w);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// two different case:
|
|
Shinya Kitaoka |
120a6e |
// (1) point at w=0 is not in stroke to transform
|
|
Shinya Kitaoka |
120a6e |
// (2) point at w=0 is in stroke to transform
|
|
Shinya Kitaoka |
120a6e |
// in case (2) it is mandatory to retrieve the
|
|
Shinya Kitaoka |
120a6e |
// parameter where stroke2transform is equal to
|
|
Shinya Kitaoka |
120a6e |
// w=0 and store it.
|
|
Shinya Kitaoka |
120a6e |
// old_w0_pos_ will be used in deactivate method
|
|
Shinya Kitaoka |
120a6e |
if (old_w0_pos_ != TConsts::napd) {
|
|
Shinya Kitaoka |
120a6e |
double w = stroke2manipulate_->getW(old_w0_pos_);
|
|
Shinya Kitaoka |
120a6e |
TPointD pnt = stroke2manipulate_->getPoint(w);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tdistance2(pnt, old_w0_pos_) < sq(TConsts::epsilon)) {
|
|
Shinya Kitaoka |
120a6e |
// the this position can be modifyed during drag
|
|
Shinya Kitaoka |
120a6e |
old_w0_ = w;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
old_w0_ = -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool test = increaseControlPoints(*stroke2manipulate_, *deformer_,
|
|
Shinya Kitaoka |
120a6e |
getImplStatus()->pixelSize_);
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
// New Increaser behaviour
|
|
Shinya Kitaoka |
120a6e |
deformer_->setMouseMove(0,100);
|
|
Shinya Kitaoka |
120a6e |
extremes_ = Toonz::increase_cp (stroke2manipulate_,
|
|
Shinya Kitaoka |
120a6e |
deformer_);
|
|
Shinya Kitaoka |
120a6e |
//*/
|
|
Shinya Kitaoka |
120a6e |
if (!test) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_->disableComputeOfCaches();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void StrokeDeformationImpl::update_impl(const TPointD &delta) {
|
|
Shinya Kitaoka |
120a6e |
assert(stroke2manipulate_ && deformer_ &&
|
|
Shinya Kitaoka |
120a6e |
"Stroke and Deformer are available");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!stroke2manipulate_ || !deformer_) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// update delta in deformer
|
|
Shinya Kitaoka |
120a6e |
deformer_->setMouseMove(delta.x, delta.y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
modifyControlPoints(*stroke2manipulate_, *deformer_);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *StrokeDeformationImpl::deactivate_impl() {
|
|
Shinya Kitaoka |
120a6e |
if (!stroke2manipulate_ || !getImplStatus()) {
|
|
Shinya Kitaoka |
120a6e |
this->reset();
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// retrieve the point
|
|
Shinya Kitaoka |
120a6e |
if (old_w0_ != -1) old_w0_pos_ = stroke2manipulate_->getPoint(old_w0_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const double reductionFactor =
|
|
Shinya Kitaoka |
120a6e |
computeReductionFactor(getImplStatus()->pixelSize_, 3.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// stroke2manipulate_->enableComputeOfCaches ();
|
|
Shinya Kitaoka |
120a6e |
// stroke2manipulate_->reduceControlPoints (reductionFactor);
|
|
Shinya Kitaoka |
120a6e |
const int size = stroke2manipulate_->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> pnt(size);</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < size; ++i)
|
|
Shinya Kitaoka |
120a6e |
pnt[i] = stroke2manipulate_->getControlPoint(i);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstroke *="">::iterator it =</tstroke>
|
|
Shinya Kitaoka |
120a6e |
std::find(strokes_.begin(), strokes_.end(), stroke2manipulate_);
|
|
Shinya Kitaoka |
120a6e |
assert(it != strokes_.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int pos = std::distance(strokes_.begin(), it);
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_ = 0;
|
|
Shinya Kitaoka |
120a6e |
delete strokes_[pos];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *tmpStroke = new TStroke(pnt);
|
|
Shinya Kitaoka |
120a6e |
assert((tmpStroke != 0) && "Not valid stroke!");
|
|
Shinya Kitaoka |
120a6e |
strokes_[pos] = tmpStroke;
|
|
Shinya Kitaoka |
120a6e |
strokes_[pos]->reduceControlPoints(reductionFactor);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// strokes_[pos] = TStroke::interpolate(pnt,
|
|
Shinya Kitaoka |
120a6e |
// reductionFactor,
|
|
Shinya Kitaoka |
120a6e |
// false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *ref = Toonz::merge(strokes_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::cloneStrokeStatus(getImplStatus()->stroke2change_, ref);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (old_w0_pos_ != TConsts::napd) {
|
|
Shinya Kitaoka |
120a6e |
// restore (if necessary) the initial position of
|
|
Shinya Kitaoka |
120a6e |
// a stroke
|
|
Shinya Kitaoka |
120a6e |
TStroke *rotated = rotateControlPointAtPoint(ref, old_w0_pos_);
|
|
Shinya Kitaoka |
120a6e |
if (rotated) {
|
|
Shinya Kitaoka |
120a6e |
delete ref;
|
|
Shinya Kitaoka |
120a6e |
ref = rotated;
|
|
Shinya Kitaoka |
120a6e |
if (getImplStatus())
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::cloneStrokeStatus(getImplStatus()->stroke2change_, ref);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
delete ref;
|
|
Shinya Kitaoka |
120a6e |
ref = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
this->reset();
|
|
Shinya Kitaoka |
120a6e |
return ref;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void StrokeDeformationImpl::reset() {
|
|
Shinya Kitaoka |
120a6e |
old_w0_ = -1;
|
|
Shinya Kitaoka |
120a6e |
old_w0_pos_ = TConsts::napd;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
deformer_ = 0;
|
|
Shinya Kitaoka |
120a6e |
getImplStatus() = 0;
|
|
Shinya Kitaoka |
120a6e |
this->setLastSelectedDegree(-1);
|
|
Shinya Kitaoka |
120a6e |
this->setLastSelectedStroke(0);
|
|
Shinya Kitaoka |
120a6e |
this->getSpiresList().clear();
|
|
Shinya Kitaoka |
120a6e |
this->getStraightsList().clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke2manipulate_ = 0;
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(strokes_); // stroke2move is deleted here (it
|
|
Shinya Kitaoka |
120a6e |
// is in vector)
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *StrokeDeformationImpl::getTransformedStroke() {
|
|
Shinya Kitaoka |
120a6e |
return this->stroke2manipulate_;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Potential *StrokeDeformationImpl::getPotential() {
|
|
Shinya Kitaoka |
120a6e |
return this->potential_;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void StrokeDeformationImpl::draw(Designer *designer) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void StrokeDeformationImpl::setPotential(Potential *potential) {
|
|
Shinya Kitaoka |
120a6e |
assert(potential);
|
|
Shinya Kitaoka |
120a6e |
potential_ = potential;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool StrokeDeformationImpl::check(const ContextStatus *status) {
|
|
Shinya Kitaoka |
120a6e |
if (!status || !this->init(status)) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return this->check_(status);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD &StrokeDeformationImpl::oldW0() { return old_w0_pos_; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Interval StrokeDeformationImpl::getExtremes() {
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Interval extremes = ToonzExt::Interval(-1.0, -1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!getImplStatus()) return extremes;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if it is manual
|
|
Shinya Kitaoka |
120a6e |
if (getImplStatus()->isManual_ == true) {
|
|
Shinya Kitaoka |
120a6e |
findExtremesFromActionLength(getImplStatus()->lengthOfAction_,
|
|
Shinya Kitaoka |
120a6e |
getImplStatus()->stroke2change_,
|
|
Shinya Kitaoka |
120a6e |
getImplStatus()->w_, extremes);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// if there are some special key down all will be managed in deformation
|
|
Shinya Kitaoka |
120a6e |
this->findExtremes_(getImplStatus(), extremes);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return extremes;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool StrokeDeformationImpl::init(const ContextStatus *status) {
|
|
Shinya Kitaoka |
120a6e |
if (!status || !isValid(status->stroke2change_) || !isValid(status->w_)) {
|
|
Shinya Kitaoka |
120a6e |
this->reset();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getImplStatus() = status;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!this->getLastSelectedStroke() ||
|
|
Shinya Kitaoka |
120a6e |
this->getLastSelectedStroke() != status->stroke2change_ ||
|
|
Shinya Kitaoka |
120a6e |
areDifferent(copyOfLastSelectedStroke_, status->stroke2change_) ||
|
|
Shinya Kitaoka |
120a6e |
(this->getLastSelectedDegree() == -1) ||
|
|
Shinya Kitaoka |
120a6e |
(this->getLastSelectedDegree() != status->cornerSize_)) {
|
|
Shinya Kitaoka |
120a6e |
this->getSpiresList().clear();
|
|
Shinya Kitaoka |
120a6e |
this->getStraightsList().clear();
|
|
Shinya Kitaoka |
120a6e |
// recompute cache
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::findCorners(status->stroke2change_, this->getSpiresList(),
|
|
Shinya Kitaoka |
120a6e |
this->getStraightsList(), status->cornerSize_,
|
|
Shinya Kitaoka |
120a6e |
TConsts::epsilon);
|
|
Shinya Kitaoka |
120a6e |
this->setLastSelectedStroke(status->stroke2change_);
|
|
Shinya Kitaoka |
120a6e |
this->setLastSelectedDegree(status->cornerSize_);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool StrokeDeformationImpl::computeStroke2Transform(
|
|
Shinya Kitaoka |
120a6e |
const ContextStatus *status, TStroke *&stroke2transform, double &w,
|
|
Shinya Kitaoka |
120a6e |
ToonzExt::Interval &extremes) {
|
|
Shinya Kitaoka |
120a6e |
if (!status || !isValid(w)) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke2transform = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (status->stroke2change_->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
if (extremes.first > extremes.second) {
|
|
Shinya Kitaoka |
120a6e |
double new_w = (extremes.first + extremes.second) * 0.5;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!rotateStroke(status->stroke2change_, stroke2transform, w, new_w,
|
|
Shinya Kitaoka |
120a6e |
old_w0_pos_))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ContextStatus tmpStatus = *status;
|
|
Shinya Kitaoka |
120a6e |
tmpStatus.stroke2change_ = stroke2transform;
|
|
Shinya Kitaoka |
120a6e |
tmpStatus.w_ = w;
|
|
Shinya Kitaoka |
120a6e |
this->check(&tmpStatus);
|
|
Shinya Kitaoka |
120a6e |
extremes = this->getExtremes();
|
|
Shinya Kitaoka |
120a6e |
this->init(status);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
} else if (extremes.first == extremes.second) {
|
|
Shinya Kitaoka |
120a6e |
double positionOfFixPoint = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// there are two different cases
|
|
Shinya Kitaoka |
120a6e |
// a) only one corner
|
|
Shinya Kitaoka |
120a6e |
// b) only two corners
|
|
Shinya Kitaoka |
120a6e |
switch (this->getSpiresList().size()) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
assert(extremes.first == -1);
|
|
Shinya Kitaoka |
120a6e |
positionOfFixPoint = retrieveParamAtLengthWithOffset(
|
|
Shinya Kitaoka |
120a6e |
status->stroke2change_, status->stroke2change_->getLength() * 0.5,
|
|
Shinya Kitaoka |
120a6e |
w);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1:
|
|
Shinya Kitaoka |
120a6e |
if (extremes.first != -1)
|
|
Shinya Kitaoka |
120a6e |
positionOfFixPoint = retrieveParamAtLengthWithOffset(
|
|
Shinya Kitaoka |
120a6e |
status->stroke2change_, status->stroke2change_->getLength() * 0.5,
|
|
Shinya Kitaoka |
120a6e |
w);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
positionOfFixPoint = this->getSpiresList()[0].first;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
// also forced mode
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(extremes.first != -1);
|
|
Shinya Kitaoka |
120a6e |
// if( extremes.first == -1 )
|
|
Shinya Kitaoka |
120a6e |
// positionOfFixPoint=retrieveParamAtLengthWithOffset(status->stroke2change_,
|
|
Shinya Kitaoka |
120a6e |
// status->stroke2change_->getLength()*0.5,
|
|
Shinya Kitaoka |
120a6e |
// w);
|
|
Shinya Kitaoka |
120a6e |
// else
|
|
Shinya Kitaoka |
120a6e |
positionOfFixPoint = extremes.first;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!rotateStroke(status->stroke2change_, stroke2transform, w,
|
|
Shinya Kitaoka |
120a6e |
positionOfFixPoint, old_w0_pos_))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
extremes = ToonzExt::Interval(0.0, 1.0);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!isValid(extremes.first) || !isValid(extremes.second)) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
if (!stroke2transform)
|
|
Shinya Kitaoka |
120a6e |
stroke2transform = new TStroke(*status->stroke2change_);
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// End Of File
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|