| #include "ext/OverallDesigner.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> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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); |
| } |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| 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); |
| |
| |
| std::vector<double> corners; |
| |
| ToonzExt::cornersDetector(s, cornerSize, corners); |
| if (corners.empty()) return; |
| |
| int i, size = corners.size(); |
| |
| glColor3d(0.8, 1.0, 0.3); |
| |
| 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); |
| |
| 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; |
| |
| |
| 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 |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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) { |
| |
| |
| |
| |
| 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); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |