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