From d1b1d00e1090c769826e380cd2c52d4b220bcfdf Mon Sep 17 00:00:00 2001 From: Tats Date: Mon, 6 Jul 2015 17:53:37 -0600 Subject: [PATCH] Integrated ellipse texture mapping. --- Mapper.cpp | 238 ++++++++++++++++++++++++++--------------------------- Mapper.h | 36 ++++---- 2 files changed, 138 insertions(+), 136 deletions(-) diff --git a/Mapper.cpp b/Mapper.cpp index e9cbbae..6609a89 100644 --- a/Mapper.cpp +++ b/Mapper.cpp @@ -356,6 +356,12 @@ void TextureGraphicsItem::_doDrawInput(QPainter* painter, bool selected) } } +void TextureGraphicsItem::_doDrawControls(QPainter* painter) +{ + painter->setPen(MM::SHAPE_STROKE); + painter->drawPath(shape()); +} + void TextureGraphicsItem::_preDraw(QPainter* painter) { painter->beginNativePainting(); @@ -425,6 +431,14 @@ void TriangleTextureGraphicsItem::_doDrawOutput(QPainter* painter, bool selected } } +void PolygonTextureGraphicsItem::_doDrawControls(QPainter* painter) +{ + painter->setPen(MM::SHAPE_STROKE); + Polygon* poly = static_cast(_shape.get()); + Q_ASSERT(poly); + painter->drawPolygon(mapFromScene(poly->toPolygon())); +} + void MeshTextureGraphicsItem::_doDrawOutput(QPainter* painter, bool selected) { Q_UNUSED(painter); @@ -473,6 +487,109 @@ void MeshTextureGraphicsItem::_doDrawControls(QPainter* painter) painter->drawPolygon(mapFromScene(mesh->toPolygon())); } +QPainterPath EllipseTextureGraphicsItem::shape() const +{ + // Create path for ellipse. + QPainterPath path; + Ellipse* ellipse = static_cast(_shape.get()); + Q_ASSERT(ellipse); + QTransform transform; + transform.translate(ellipse->getCenter().x(), ellipse->getCenter().y()); + transform.rotate(ellipse->getRotation()); + path.addEllipse(QPoint(0,0), ellipse->getHorizontalRadius(), ellipse->getVerticalRadius()); + return mapFromScene(transform.map(path)); +} + +QRectF EllipseTextureGraphicsItem::boundingRect() const +{ + return shape().boundingRect(); +} + +void EllipseTextureGraphicsItem::_doDrawOutput(QPainter* painter, bool selected) +{ + Q_UNUSED(painter); + // Get input and output ellipses. + std::tr1::shared_ptr inputEllipse = std::tr1::static_pointer_cast(_inputShape); + std::tr1::shared_ptr outputEllipse = std::tr1::static_pointer_cast(_shape); + + // Start / end angle. + //const float startAngle = 0; + //const float endAngle = 2*M_PI; + + // + //float angle; + QPointF currentInputPoint; + QPointF prevInputPoint(0, 0); + QPointF currentOutputPoint; + QPointF prevOutputPoint(0, 0); + + // Input ellipse parameters. + const QPointF& inputCenter = inputEllipse->getCenter(); + const QPointF& inputControlCenter = inputEllipse->getVertex(4); + float inputHorizRadius = inputEllipse->getHorizontalRadius(); + float inputVertRadius = inputEllipse->getVerticalRadius(); + float inputRotation = inputEllipse->getRotationRadians(); + + // Output ellipse parameters. + const QPointF& outputCenter = mapFromScene(outputEllipse->getCenter()); + const QPointF& outputControlCenter = mapFromScene(outputEllipse->getVertex(4)); + float outputHorizRadius = outputEllipse->getHorizontalRadius(); + float outputVertRadius = outputEllipse->getVerticalRadius(); + float outputRotation = outputEllipse->getRotationRadians(); + + // Variation in angle at each step of the loop. + const int N_TRIANGLES = 100; + const float ANGLE_STEP = 2*M_PI/N_TRIANGLES; + + float circleAngle = 0; + for (int i=0; i<=N_TRIANGLES; i++, circleAngle += ANGLE_STEP) + { + // Set next (current) points. + _setPointOfEllipseAtAngle(currentInputPoint, inputCenter, inputHorizRadius, inputVertRadius, inputRotation, circleAngle); + _setPointOfEllipseAtAngle(currentOutputPoint, outputCenter, outputHorizRadius, outputVertRadius, outputRotation, circleAngle); + + // We don't draw the first point. + if (i > 0) + { + // Draw triangle. + glBegin(GL_TRIANGLES); + Util::setGlTexPoint(*_texture, inputControlCenter, outputControlCenter); + Util::setGlTexPoint(*_texture, prevInputPoint, prevOutputPoint); + Util::setGlTexPoint(*_texture, currentInputPoint, currentOutputPoint); + glEnd(); + } + + // Save point for next iteration. + prevInputPoint.setX(currentInputPoint.x()); + prevInputPoint.setY(currentInputPoint.y()); + prevOutputPoint.setX(currentOutputPoint.x()); + prevOutputPoint.setY(currentOutputPoint.y()); + } +} + +void EllipseTextureGraphicsItem::_setPointOfEllipseAtAngle(QPointF& point, const QPointF& center, float hRadius, float vRadius, float rotation, float circularAngle) +{ + float xCirc = sin(circularAngle) * hRadius; + float yCirc = cos(circularAngle) * vRadius; + float distance = sqrt( xCirc*xCirc + yCirc*yCirc ); + float angle = atan2( xCirc, yCirc ); + rotation = 2*M_PI-rotation; // rotation needs to be inverted (CW <-> CCW) + point.setX( sin(angle + rotation) * distance + center.x() ); + point.setY( cos(angle + rotation) * distance + center.y() ); +} + +void EllipseTextureGraphicsItem::_doDrawControls(QPainter* painter) +{ + painter->setPen(MM::SHAPE_STROKE); + painter->setBrush(Qt::NoBrush); + + // Just draw the path. + painter->drawPath(shape()); + +// std::tr1::shared_ptr outputEllipse = std::tr1::static_pointer_cast(_shape); +// Util::drawControlsEllipse(painter, selectedVertices, *outputEllipse); +} + Mapper::Mapper(Mapping::ptr mapping) : _mapping(mapping), _graphicsItem(NULL), @@ -819,127 +936,10 @@ void MeshTextureMapper::setValue(QtProperty* property, const QVariant& value) TextureMapper::setValue(property, value); } -void MeshTextureMapper::drawControls(QPainter* painter, const QList* selectedVertices) -{ - std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(outputShape); - Util::drawControlsMesh(painter, selectedVertices, *outputMesh); -} - -void MeshTextureMapper::drawInputControls(QPainter* painter, const QList* selectedVertices) -{ - std::tr1::shared_ptr inputMesh = std::tr1::static_pointer_cast(inputShape); - Util::drawControlsMesh(painter, selectedVertices, *inputMesh); -} - -void MeshTextureMapper::_doDraw(QPainter* painter) -{ - Q_UNUSED(painter); - std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(outputShape); - std::tr1::shared_ptr inputMesh = std::tr1::static_pointer_cast(inputShape); - QVector > outputQuads = outputMesh->getQuads2d(); - QVector > inputQuads = inputMesh->getQuads2d(); - for (int x = 0; x < outputMesh->nHorizontalQuads(); x++) - { - for (int y = 0; y < outputMesh->nVerticalQuads(); y++) - { - Quad& outputQuad = outputQuads[x][y]; - Quad& inputQuad = inputQuads[x][y]; - glBegin(GL_QUADS); - for (int i = 0; i < 4; i++) - { - Util::setGlTexPoint(*texture, inputQuad.getVertex(i), outputQuad.getVertex(i)); - } - glEnd(); - } - } -} - EllipseTextureMapper::EllipseTextureMapper(std::tr1::shared_ptr mapping) : PolygonTextureMapper(mapping) { + _graphicsItem = new EllipseTextureGraphicsItem(_mapping, true); + _inputGraphicsItem = new EllipseTextureGraphicsItem(_mapping, false); } -void EllipseTextureMapper::drawControls(QPainter* painter, const QList* selectedVertices) -{ - std::tr1::shared_ptr outputEllipse = std::tr1::static_pointer_cast(outputShape); - Util::drawControlsEllipse(painter, selectedVertices, *outputEllipse); -} - -void EllipseTextureMapper::drawInputControls(QPainter* painter, const QList* selectedVertices) -{ - std::tr1::shared_ptr inputEllipse = std::tr1::static_pointer_cast(inputShape); - Util::drawControlsEllipse(painter, selectedVertices, *inputEllipse); -} - -void EllipseTextureMapper::_doDraw(QPainter* painter) -{ - Q_UNUSED(painter); - // Get input and output ellipses. - std::tr1::shared_ptr inputEllipse = std::tr1::static_pointer_cast(inputShape); - std::tr1::shared_ptr outputEllipse = std::tr1::static_pointer_cast(outputShape); - - // Start / end angle. - //const float startAngle = 0; - //const float endAngle = 2*M_PI; - - // - //float angle; - QPointF currentInputPoint; - QPointF prevInputPoint(0, 0); - QPointF currentOutputPoint; - QPointF prevOutputPoint(0, 0); - - // Input ellipse parameters. - const QPointF& inputCenter = inputEllipse->getCenter(); - const QPointF& inputControlCenter = inputEllipse->getVertex(4); - float inputHorizRadius = inputEllipse->getHorizontalRadius(); - float inputVertRadius = inputEllipse->getVerticalRadius(); - float inputRotation = inputEllipse->getRotationRadians(); - - // Output ellipse parameters. - const QPointF& outputCenter = outputEllipse->getCenter(); - const QPointF& outputControlCenter = outputEllipse->getVertex(4); - float outputHorizRadius = outputEllipse->getHorizontalRadius(); - float outputVertRadius = outputEllipse->getVerticalRadius(); - float outputRotation = outputEllipse->getRotationRadians(); - - // Variation in angle at each step of the loop. - const int N_TRIANGLES = 100; - const float ANGLE_STEP = 2*M_PI/N_TRIANGLES; - - float circleAngle = 0; - for (int i=0; i<=N_TRIANGLES; i++, circleAngle += ANGLE_STEP) - { - // Set next (current) points. - _setPointOfEllipseAtAngle(currentInputPoint, inputCenter, inputHorizRadius, inputVertRadius, inputRotation, circleAngle); - _setPointOfEllipseAtAngle(currentOutputPoint, outputCenter, outputHorizRadius, outputVertRadius, outputRotation, circleAngle); - - // We don't draw the first point. - if (i > 0) - { - // Draw triangle. - glBegin(GL_TRIANGLES); - Util::setGlTexPoint(*texture, inputControlCenter, outputControlCenter); - Util::setGlTexPoint(*texture, prevInputPoint, prevOutputPoint); - Util::setGlTexPoint(*texture, currentInputPoint, currentOutputPoint); - glEnd(); - } - - // Save point for next iteration. - prevInputPoint.setX(currentInputPoint.x()); - prevInputPoint.setY(currentInputPoint.y()); - prevOutputPoint.setX(currentOutputPoint.x()); - prevOutputPoint.setY(currentOutputPoint.y()); - } -} - -void EllipseTextureMapper::_setPointOfEllipseAtAngle(QPointF& point, const QPointF& center, float hRadius, float vRadius, float rotation, float circularAngle) -{ - float xCirc = sin(circularAngle) * hRadius; - float yCirc = cos(circularAngle) * vRadius; - float distance = sqrt( xCirc*xCirc + yCirc*yCirc ); - float angle = atan2( xCirc, yCirc ); - rotation = 2*M_PI-rotation; // rotation needs to be inverted (CW <-> CCW) - point.setX( sin(angle + rotation) * distance + center.x() ); - point.setY( cos(angle + rotation) * distance + center.y() ); -} diff --git a/Mapper.h b/Mapper.h index f0608c7..d11f43a 100644 --- a/Mapper.h +++ b/Mapper.h @@ -165,7 +165,7 @@ protected: virtual void _doDrawOutput(QPainter* painter, bool selected) = 0; virtual void _doDrawInput(QPainter* painter, bool selected); - virtual void _doDrawControls(QPainter* painter) { Q_UNUSED(painter); } + virtual void _doDrawControls(QPainter* painter); void _preDraw(QPainter* painter); void _postDraw(QPainter* painter); @@ -182,12 +182,8 @@ public: PolygonTextureGraphicsItem(Mapping::ptr mapping, bool output=true) : TextureGraphicsItem(mapping, output) {} virtual ~PolygonTextureGraphicsItem(){} - virtual void _doDrawControls(QPainter* painter) { - painter->setPen(MM::SHAPE_STROKE); - Polygon* poly = static_cast(_shape.get()); - Q_ASSERT(poly); - painter->drawPolygon(mapFromScene(poly->toPolygon())); - } + virtual void _doDrawControls(QPainter* painter); + virtual QPainterPath shape() const; virtual QRectF boundingRect() const; }; @@ -214,6 +210,22 @@ public: virtual void _doDrawControls(QPainter* painter); }; +/// Graphics item for textured mesh. +class EllipseTextureGraphicsItem : public TextureGraphicsItem +{ +public: + EllipseTextureGraphicsItem(Mapping::ptr mapping, bool output=true) : TextureGraphicsItem(mapping, output) {} + virtual ~EllipseTextureGraphicsItem(){} + + virtual QPainterPath shape() const; + virtual QRectF boundingRect() const; + + virtual void _doDrawOutput(QPainter* painter, bool selected); + virtual void _doDrawControls(QPainter* painter); + + static void _setPointOfEllipseAtAngle(QPointF& point, const QPointF& center, float hRadius, float vRadius, float rotation, float circularAngle); +}; + /** * A way to draw on some kind of shape. * @@ -400,15 +412,9 @@ public: MeshTextureMapper(std::tr1::shared_ptr mapping); virtual ~MeshTextureMapper() {} - virtual void drawControls(QPainter* painter, const QList* selectedVertices=0); - virtual void drawInputControls(QPainter* painter, const QList* selectedVertices=0); - public slots: virtual void setValue(QtProperty* property, const QVariant& value); -protected: - virtual void _doDraw(QPainter* painter); - private: QtVariantProperty* _meshItem; }; @@ -420,11 +426,7 @@ public: EllipseTextureMapper(std::tr1::shared_ptr mapping); virtual ~EllipseTextureMapper() {} - virtual void drawControls(QPainter* painter, const QList* selectedVertices=0); - virtual void drawInputControls(QPainter* painter, const QList* selectedVertices=0); - protected: - virtual void _doDraw(QPainter* painter); static void _setPointOfEllipseAtAngle(QPointF& point, const QPointF& center, float hRadius, float vRadius, float rotation, float circularAngle); };