| #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); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |