#ifdef WIN32
#define NOMINMAX
#endif
#include "ext/OverallDesigner.h"
//#include "ext/StrokeParametricDeformer.h"
#include "ext/StrokeDeformation.h"
#include "ext/SmoothDeformation.h"
#include "ext/CornerDeformation.h"
#include "ext/StraightCornerDeformation.h"
#include "ext/Selector.h"
#include "ext/ContextStatus.h"
#include "tcurves.h"
#include <tstroke.h>
#include <tgl.h>
#include <tgeometry.h>
#include <drawutil.h>
#include <sstream>
/*
#ifdef _DEBUG
#undef _DEBUG
#define RESTORE_DEBUG
#endif
//*/
//-----------------------------------------------------------------------------
namespace
{
void extglDrawText(const TPointD &p,
const std::string &s,
void *character = GLUT_BITMAP_TIMES_ROMAN_10)
{
glPushMatrix();
glTranslated(p.x, p.y, 0);
if (character <= GLUT_STROKE_MONO_ROMAN) {
double factor = 0.07;
glScaled(factor, factor, factor);
for (int i = 0; i < (int)s.size(); i++)
glutStrokeCharacter(character, s[i]);
} else
for (int i = 0; i < (int)s.size(); i++)
glutBitmapCharacter(character, s[i]);
glPopMatrix();
}
//---------------------------------------------------------------------------
void drawSign(const TPointD &p,
const TPointD &v,
double size)
{
if (size == 0.0)
return;
size = fabs(size);
TPointD v90 = rotate90(v);
TPointD v270 = rotate270(v);
glBegin(GL_LINES);
glVertex2d(p.x, p.y);
v90 = normalize(v90);
v90 = v90 * size;
v90 = p + v90;
glVertex2d(v90.x, v90.y);
glEnd();
glBegin(GL_LINES);
glVertex2d(p.x, p.y);
v270 = normalize(v270);
v270 = v270 * size;
v270 = p + v270;
glVertex2d(v270.x, v270.y);
glEnd();
}
//---------------------------------------------------------------------------
void drawCross(const TPointD &p,
double size)
{
TPointD
v1 = TPointD(1, 1);
TPointD
v2 = TPointD(1, -1);
drawSign(p, v1, size);
drawSign(p, v2, size);
}
//---------------------------------------------------------------------------
/**
* Try to verify if it is possible to call
* some method of this stroke.
*/
bool isValid(const TStroke *s)
{
if (!s)
return false;
const int
cpCount = s->getControlPointCount();
int
i;
for (i = 0;
i < cpCount;
++i)
s->getControlPoint(i);
const int
chunkCount = s->getChunkCount();
for (i = 0;
i < chunkCount;
++i)
s->getChunk(i);
return true;
}
//---------------------------------------------------------------------------
void showCP(const TStroke *s,
double pixelSize)
{
if (!s)
return;
// show control points
const int
countCP = s->getControlPointCount();
TThickPoint
p1;
for (int i = 0;
i < countCP;
++i) {
p1 = s->getControlPoint(i);
if (i & 1)
glColor3d(1.0, 0.0, 0.0);
else
glColor3d(1.0, 1.0, 0.0);
drawCross(convert(p1),
p1.thick * pixelSize);
tglDrawCircle(convert(p1),
p1.thick * pixelSize);
}
}
//---------------------------------------------------------------------------
void drawStrokeCenterLine(const TStroke *stroke,
double pixelSize,
const ToonzExt::Interval &vals)
{
double
from = vals.first,
to = vals.second;
if (!stroke ||
pixelSize < 0.0)
return;
from = std::max(std::min(from, 1.0), 0.0);
to = std::max(std::min(to, 1.0), 0.0);
if (from < to) {
drawStrokeCenterline(*stroke,
pixelSize,
from,
to);
} else {
drawStrokeCenterline(*stroke,
pixelSize,
from,
1.0);
drawStrokeCenterline(*stroke,
pixelSize,
0.0,
to);
}
tglDrawDisk(stroke->getPoint(from),
5.0 * pixelSize);
tglDrawDisk(stroke->getPoint(to),
5.0 * pixelSize);
#ifdef _DEBUG
glColor3d(1.0, 0.0, 0.0);
tglDrawDisk(stroke->getPoint(0.0),
9.0 * pixelSize);
#endif
}
//---------------------------------------------------------------------------
void showCorners(const TStroke *s,
int cornerSize,
double pixelSize)
{
if (!s)
return;
const TPointD
offset(20, 20);
// show corners
vector<double>
corners;
ToonzExt::cornersDetector(s,
cornerSize,
corners);
if (corners.empty())
return;
int
i,
size = corners.size();
glColor3d(0.8, 1.0, 0.3);
// find interval with corner like extremes
for (i = 0;
i < size;
++i) {
double
tmp = corners[i];
TPointD
pnt = s->getPoint(tmp);
double
large = 5.0;
drawCross(pnt,
large * pixelSize);
glColor3d(0.7, 0.7, 0.7);
std::ostringstream oss;
oss << "[" << tmp << "]";
extglDrawText(TPointD(pnt.x, pnt.y) + offset, oss.str());
}
corners.clear();
ToonzExt::straightCornersDetector(s,
corners);
if (corners.empty())
return;
size = corners.size();
glColor3d(0.8, 1.0, 0.3);
// find interval with corner like extremes
for (i = 0;
i < size;
++i) {
double
tmp = corners[i];
TPointD
pnt = s->getPoint(tmp);
double
large = 5.0;
drawCross(pnt,
large * pixelSize);
glColor3d(0.7, 0.2, 0.2);
std::ostringstream oss;
oss << "[" << tmp << "]";
extglDrawText(TPointD(pnt.x, pnt.y) - offset, oss.str());
}
}
}
//-----------------------------------------------------------------------------
ToonzExt::OverallDesigner::OverallDesigner(int x,
int y)
: x_(x), y_(y)
{
pixelSize_ = sqrt(this->getPixelSize2());
scale_ = pixelSize_ != 0.0 ? pixelSize_ : 1.0;
}
//-----------------------------------------------------------------------------
ToonzExt::OverallDesigner::~OverallDesigner()
{
}
//-----------------------------------------------------------------------------
void ToonzExt::OverallDesigner::draw(ToonzExt::SmoothDeformation *sd)
{
#ifdef _DEBUG
glPushMatrix();
{
this->setPosition();
TCubic c;
c.setP0(TPointD(0.0, 0.0));
c.setP1(TPointD(4.0, 12.0));
c.setP2(TPointD(12.0, 12.0));
c.setP3(TPointD(16.0, 0.0));
glColor3d(1.0, 0.0, 1.0);
tglDraw(c, 100, GL_LINE);
}
glPopMatrix();
#endif
}
//-----------------------------------------------------------------------------
void ToonzExt::OverallDesigner::draw(ToonzExt::CornerDeformation *sd)
{
#ifdef _DEBUG
glPushMatrix();
{
this->setPosition();
TCubic c;
c.setP0(TPointD(0.0, 0.0));
c.setP1(TPointD(0.0, 12.0));
c.setP2(TPointD(6.0, 12.0));
c.setP3(TPointD(12.0, 12.0));
glColor3d(1.0, 0.0, 1.0);
tglDraw(c, 100, GL_LINE);
c.setP0(TPointD(12.0, 12.0));
c.setP1(TPointD(6.0, 8.0));
c.setP2(TPointD(6.0, 4.0));
c.setP3(TPointD(12.0, 0.0));
tglDraw(c, 100, GL_LINE);
}
glPopMatrix();
#endif
}
//-----------------------------------------------------------------------------
void ToonzExt::OverallDesigner::draw(ToonzExt::StraightCornerDeformation *sd)
{
#ifdef _DEBUG
glPushMatrix();
{
this->setPosition();
glColor3d(0.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
tglVertex(TPointD(0.0, 0.0));
tglVertex(TPointD(8.0, 12.0));
tglVertex(TPointD(16.0, 0.0));
glEnd();
}
glPopMatrix();
#endif
}
//-----------------------------------------------------------------------------
void ToonzExt::OverallDesigner::draw(ToonzExt::StrokeDeformation *sd)
{
if (sd) {
const TStroke *
s;
//glColor3d(1.0,0.0,1.0);
s = sd->getCopiedStroke();
if (s) {
const ContextStatus *
status = sd->getStatus();
double
w = 0.0,
pixelSize = 1.0;
if (status) {
w = status->w_;
pixelSize = status->pixelSize_ < 0 ? 1.0 : status->pixelSize_;
}
#ifdef _DEBUG
drawCross(s->getPoint(0),
2 * pixelSize);
tglDrawCircle(s->getPoint(w), 8 * pixelSize);
drawCross(s->getPoint(w), 8 * pixelSize);
#endif
ToonzExt::Interval
ex = sd->getExtremes();
drawStrokeCenterLine(s,
pixelSize_,
ex);
if (status) {
#ifdef _DEBUG
glColor3d(0, 0, 0);
showCorners(s,
status->cornerSize_,
pixelSize);
glColor3d(0, 0, 0);
TPointD
offset = normalize(TPointD(1.0, 1.0)) * 20.0;
std::ostringstream oss;
oss << "(" << this->x_
<< "," << this->y_
<< ")\n{" << w
<< ",{" << sd->getExtremes().first
<< "," << sd->getExtremes().second
<< "}}";
extglDrawText(TPointD(x_, y_) + offset, oss.str());
glColor3d(0.5, 1.0, 0.5);
showCP(s,
pixelSize);
#endif
}
}
/*
glColor3d(1.0,1.0,0.0);
s = sd->getStroke();
if(s)
{
drawCross( s->getPoint(0),
4);
drawStrokeCenterLine(s,
pixelSize_,
ToonzExt::Interval(0,1));
}
*/
s = sd->getTransformedStroke();
glColor3d(1.0, 0.0, 0.0);
if (s) {
#ifdef _DEBUG
isValid(s);
#endif
drawStrokeCenterline(*s,
pixelSize_);
}
#ifdef _DEBUG
{
const TStroke
*c = sd->getCopiedStroke(),
*s = sd->getStroke();
if (c && s) {
//glColor3d(1,1,0);
//tglDrawDisk(s->getPoint(0.0),
// 5*pixelSize_);
int count = std::min(c->getControlPointCount(),
s->getControlPointCount());
for (int i = 0;
i < count;
++i) {
TThickPoint
ccp = c->getControlPoint(i);
TThickPoint
scp = s->getControlPoint(i);
}
}
}
#endif
}
}
//-----------------------------------------------------------------------------
void ToonzExt::OverallDesigner::setPosition()
{
TPointD
offset(1, -1);
offset = normalize(offset) * (20.0 * scale_);
glTranslated(x_ + offset.x,
y_ + offset.y,
0.0);
glScalef(scale_,
scale_,
scale_);
}
//-----------------------------------------------------------------------------
void ToonzExt::OverallDesigner::draw(ToonzExt::Selector *selector)
{
if (!selector)
return;
const TStroke *
ref = selector->getStroke();
if (!ref)
return;
double
length_at_w = ref->getLength(selector->getW()),
emi_selector_length = selector->getLength() * 0.5,
stroke_length = ref->getLength();
ToonzExt::Interval
interval;
if (ref->isSelfLoop()) {
interval.first = length_at_w - emi_selector_length;
if (interval.first < 0.0)
interval.first = stroke_length + interval.first;
interval.first = ref->getParameterAtLength(interval.first);
interval.second = length_at_w + emi_selector_length;
if (interval.second > stroke_length)
interval.second = interval.second - stroke_length;
interval.second = ref->getParameterAtLength(interval.second);
} else {
interval.first = ref->getParameterAtLength(std::max(0.0, length_at_w - emi_selector_length));
interval.second = ref->getParameterAtLength(std::min(stroke_length, length_at_w + emi_selector_length));
}
float
prev_line_width = 1.0;
glGetFloatv(GL_LINE_WIDTH,
&prev_line_width);
glLineWidth(2.0);
drawStrokeCenterLine(ref,
pixelSize_,
interval);
glLineWidth(prev_line_width);
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
/*
#ifdef RESTORE_DEBUG
#undef RESTORE_DEBUG
#define _DEBUG 1
#endif
//*/