mirror of
https://github.com/mapmapteam/mapmap.git
synced 2026-06-16 12:33:19 +02:00
Merge branch 'ellipseshape' into develop
This commit is contained in:
+5
-5
@@ -518,13 +518,13 @@ uid MainWindow::createEllipseTextureMapping(uid mappingId,
|
||||
else
|
||||
{
|
||||
Paint::ptr paint = mappingManager->getPaintById(paintId);
|
||||
Q_ASSERT(src.size() == 4 && dst.size() == 4);
|
||||
Q_ASSERT(src.size() == 5 && dst.size() == 5);
|
||||
|
||||
Shape::ptr inputEllipse( new Ellipse(src[0], src[1], src[2], dst[3]));
|
||||
Shape::ptr outputEllipse(new Ellipse(dst[0], dst[1], dst[2], dst[3]));
|
||||
Shape::ptr inputEllipse( new Ellipse(src[0], src[1], src[2], dst[3], dst[4]));
|
||||
Shape::ptr outputEllipse(new Ellipse(dst[0], dst[1], dst[2], dst[3], dst[4]));
|
||||
|
||||
// Add it to the manager.
|
||||
Mapping::ptr mapping(new TextureMapping(paint, inputEllipse, outputEllipse, mappingId));
|
||||
Mapping::ptr mapping(new TextureMapping(paint, outputEllipse, inputEllipse, mappingId));
|
||||
uid id = mappingManager->addMapping(mapping);
|
||||
|
||||
// Add it to the GUI.
|
||||
@@ -595,7 +595,7 @@ uid MainWindow::createTriangleColorMapping(uid mappingId,
|
||||
|
||||
uid MainWindow::createEllipseColorMapping(uid mappingId,
|
||||
uid paintId,
|
||||
const QList<QPointF> &dst)
|
||||
const QVector<QPointF> &dst)
|
||||
{
|
||||
// Cannot create element with already existing id or element for which no paint exists.
|
||||
if (Mapping::getUidAllocator().exists(mappingId) ||
|
||||
|
||||
+1
-1
@@ -141,7 +141,7 @@ public slots:
|
||||
*/
|
||||
uid createEllipseColorMapping(uid mappingId,
|
||||
uid paintId,
|
||||
const QList<QPointF> &dst);
|
||||
const QVector<QPointF> &dst);
|
||||
|
||||
private:
|
||||
// Methods.
|
||||
|
||||
+38
-7
@@ -156,6 +156,21 @@ void ProjectReader::parseMapping(const QDomElement& mapping)
|
||||
_xml.raiseError(QObject::tr("Cannot create mesh texture mapping"));
|
||||
|
||||
}
|
||||
else if (mappingAttrType == "ellipse_texture")
|
||||
{
|
||||
// Parse destination ellipse.
|
||||
_parseEllipse(dst, dstPoints);
|
||||
|
||||
// Get / parse source shape.
|
||||
QDomElement src = mapping.firstChildElement("source");
|
||||
QVector<QPointF> srcPoints;
|
||||
_parseEllipse(src, srcPoints);
|
||||
|
||||
uid id = _window->createEllipseTextureMapping(mappingAttrId.toInt(), mappingAttrPaintId.toInt(), srcPoints, dstPoints);
|
||||
|
||||
if (id == NULL_UID)
|
||||
_xml.raiseError(QObject::tr("Cannot create ellipse texture mapping"));
|
||||
}
|
||||
else if (mappingAttrType == "triangle_color")
|
||||
{
|
||||
// Parse destination triangle.
|
||||
@@ -168,7 +183,7 @@ void ProjectReader::parseMapping(const QDomElement& mapping)
|
||||
}
|
||||
else if (mappingAttrType == "quad_color")
|
||||
{
|
||||
// Parse destination triangle.
|
||||
// Parse destination quad.
|
||||
_parseQuad(dst, dstPoints);
|
||||
|
||||
uid id = _window->createQuadColorMapping(mappingAttrId.toInt(), mappingAttrPaintId.toInt(), dstPoints);
|
||||
@@ -176,11 +191,21 @@ void ProjectReader::parseMapping(const QDomElement& mapping)
|
||||
if (id == NULL_UID)
|
||||
_xml.raiseError(QObject::tr("Cannot create quad color mapping"));
|
||||
}
|
||||
else if (mappingAttrType == "ellipse_color")
|
||||
{
|
||||
// Parse destination ellipse.
|
||||
_parseEllipse(dst, dstPoints);
|
||||
|
||||
uid id = _window->createEllipseColorMapping(mappingAttrId.toInt(), mappingAttrPaintId.toInt(), dstPoints);
|
||||
|
||||
if (id == NULL_UID)
|
||||
_xml.raiseError(QObject::tr("Cannot create ellipse color mapping"));
|
||||
}
|
||||
else
|
||||
_xml.raiseError(QObject::tr("Unsupported mapping type: %1.").arg(mappingAttrType));
|
||||
}
|
||||
|
||||
void ProjectReader::_parseStandardShape(const QString& type, int nVertices, const QDomElement& shape, QVector<QPointF>& points)
|
||||
void ProjectReader::_parseStandardShape(const QString& type, const QDomElement& shape, QVector<QPointF>& points, int nVertices)
|
||||
{
|
||||
// Check that the element is really a triangle.
|
||||
QString typeAttr = shape.attribute("shape", "");
|
||||
@@ -198,19 +223,25 @@ void ProjectReader::_parseStandardShape(const QString& type, int nVertices, cons
|
||||
vertex = vertex.nextSiblingElement("vertex");
|
||||
}
|
||||
|
||||
if (points.size() != nVertices)
|
||||
_xml.raiseError(QObject::tr("Shape has %1 vertices: expected %2.").arg(points.size()).arg(nVertices));
|
||||
if (nVertices >= 0 && points.size() != nVertices)
|
||||
_xml.raiseError(QObject::tr("Shape of type '%1' has %2 vertices: expected %3.").arg(type).arg(points.size()).arg(nVertices));
|
||||
}
|
||||
|
||||
void ProjectReader::_parseQuad(const QDomElement& quad, QVector<QPointF>& points)
|
||||
{
|
||||
_parseStandardShape("quad", 4, quad, points);
|
||||
_parseStandardShape("quad", quad, points, 4);
|
||||
}
|
||||
|
||||
|
||||
void ProjectReader::_parseTriangle(const QDomElement& triangle, QVector<QPointF>& points)
|
||||
{
|
||||
_parseStandardShape("triangle", 3, triangle, points);
|
||||
_parseStandardShape("triangle", triangle, points, 3);
|
||||
}
|
||||
|
||||
void ProjectReader::_parseEllipse(const QDomElement& ellipse, QVector<QPointF>& points)
|
||||
{
|
||||
_parseStandardShape("ellipse", ellipse, points);
|
||||
if (points.size() != 4 && points.size() != 5)
|
||||
_xml.raiseError(QObject::tr("Shape has %1 vertices: expected 4 or 5.").arg(points.size()));
|
||||
}
|
||||
|
||||
void ProjectReader::_parseMesh(const QDomElement& mesh, QVector<QPointF>& points, int& nColumns, int& nRows)
|
||||
|
||||
+2
-1
@@ -37,10 +37,11 @@ private:
|
||||
void parsePaint(const QDomElement& paint);
|
||||
void parseMapping(const QDomElement& mapping);
|
||||
|
||||
void _parseStandardShape(const QString& type, int nVertices, const QDomElement& shape, QVector<QPointF>& points);
|
||||
void _parseStandardShape(const QString& type, const QDomElement& shape, QVector<QPointF>& points, int nVertices=-1);
|
||||
void _parseQuad(const QDomElement& quad, QVector<QPointF>& points);
|
||||
void _parseTriangle(const QDomElement& triangle, QVector<QPointF>& points);
|
||||
void _parseMesh(const QDomElement& mesh, QVector<QPointF>& points, int& nColumns, int& nRows);
|
||||
void _parseEllipse(const QDomElement& ellipse, QVector<QPointF>& points);
|
||||
QPointF _parseVertex(const QDomElement& vertex);
|
||||
|
||||
// void readPaint(); //Paint *item);
|
||||
|
||||
@@ -458,12 +458,10 @@ void Ellipse::setVertex(int i, const QPointF& v)
|
||||
// Center control point (make sure it stays inside!).
|
||||
else if (hasCenterControl())
|
||||
{
|
||||
// Map point as vector on a unit circle.
|
||||
QVector2D vector(toUnitCircle().map(v));
|
||||
|
||||
// Clip control point.
|
||||
Shape::setVertex(4, vector.length() <= 1 ?
|
||||
v :
|
||||
fromUnitCircle().map(vector.normalized().toPointF()));
|
||||
Shape::setVertex(4, clipInside(v));
|
||||
}
|
||||
|
||||
// Just to be sure.
|
||||
sanitize();
|
||||
}
|
||||
|
||||
@@ -213,6 +213,16 @@ protected:
|
||||
class Ellipse : public Shape {
|
||||
public:
|
||||
Ellipse() {}
|
||||
Ellipse(QPointF p1, QPointF p2, QPointF p3, QPointF p4, QPointF p5)
|
||||
{
|
||||
_addVertex(p1);
|
||||
_addVertex(p2);
|
||||
_addVertex(p3);
|
||||
_addVertex(p4);
|
||||
_addVertex(p5);
|
||||
sanitize();
|
||||
}
|
||||
|
||||
Ellipse(QPointF p1, QPointF p2, QPointF p3, QPointF p4, bool hasCenterControl=true)
|
||||
{
|
||||
_addVertex(p1);
|
||||
@@ -220,47 +230,94 @@ public:
|
||||
_addVertex(p3);
|
||||
_addVertex(p4);
|
||||
if (hasCenterControl)
|
||||
_addVertex(getCenter()); // add a point in the center
|
||||
_addVertex(getCenter());
|
||||
sanitize();
|
||||
}
|
||||
|
||||
/// Remaps points so as to make sure this is a correct ellipse, keeping vertices 0 and 2 as
|
||||
/// reference for the horizzontal axis.
|
||||
void sanitize()
|
||||
{
|
||||
// Get horizontal axis rotated 90 degrees CW
|
||||
QVector2D hAxis = getHorizontalAxis();
|
||||
const QVector2D center(getCenter());
|
||||
QVector2D hAxisRotated(hAxis.y(), -hAxis.x());
|
||||
|
||||
// Project vertex 1 onto it.
|
||||
QVector2D vAxisNormalized = hAxisRotated.normalized();
|
||||
|
||||
QVector2D vFromCenter = QVector2D(getVertex(1)) - center;
|
||||
const QVector2D& projection = QVector2D::dotProduct( vFromCenter, vAxisNormalized ) * vAxisNormalized;
|
||||
Shape::setVertex(1, (center + projection).toPointF());
|
||||
Shape::setVertex(3, (center - projection).toPointF());
|
||||
|
||||
if (hasCenterControl())
|
||||
{
|
||||
// Clip control point.
|
||||
Shape::setVertex(4, clipInside(getVertex(4)));
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~Ellipse() {}
|
||||
|
||||
virtual QString getType() const { return "ellipse"; }
|
||||
|
||||
qreal getRotationRadians() const {
|
||||
qreal getRotationRadians() const
|
||||
{
|
||||
QVector2D hAxis = getHorizontalAxis();
|
||||
return atan2( hAxis.y(), hAxis.x() );
|
||||
}
|
||||
|
||||
qreal getRotation() const {
|
||||
qreal getRotation() const
|
||||
{
|
||||
return radiansToDegrees( getRotationRadians() );
|
||||
}
|
||||
|
||||
bool hasCenterControl() const {
|
||||
bool hasCenterControl() const
|
||||
{
|
||||
return (nVertices() == 5);
|
||||
}
|
||||
|
||||
/// If v is outside boundaries, remap it to the border.
|
||||
QPointF clipInside(const QPointF& v) const
|
||||
{
|
||||
// Map point as vector on a unit circle.
|
||||
QVector2D vector(toUnitCircle().map(v));
|
||||
|
||||
// Clip control point.
|
||||
return (vector.length() <= 1 ?
|
||||
v :
|
||||
fromUnitCircle().map(vector.normalized().toPointF()));
|
||||
|
||||
}
|
||||
|
||||
// QRect getBoundingRect() const {
|
||||
// return QRect(0, getVerticalAxis().manhattanLength(),
|
||||
// getHorizontalAxis().manhattanLength(), getVerticalAxis().manhattanLength());
|
||||
// }
|
||||
//
|
||||
QPointF getCenter() const {
|
||||
QPointF getCenter() const
|
||||
{
|
||||
return (QVector2D(getVertex(0)) - (getHorizontalAxis() / 2)).toPointF();
|
||||
}
|
||||
|
||||
QVector2D getHorizontalAxis() const {
|
||||
QVector2D getHorizontalAxis() const
|
||||
{
|
||||
return QVector2D(getVertex(0)) - QVector2D(getVertex(2));
|
||||
}
|
||||
|
||||
QVector2D getVerticalAxis() const {
|
||||
QVector2D getVerticalAxis() const
|
||||
{
|
||||
return QVector2D(getVertex(1)) - QVector2D(getVertex(3));
|
||||
}
|
||||
|
||||
qreal getHorizontalRadius() const {
|
||||
qreal getHorizontalRadius() const
|
||||
{
|
||||
return getHorizontalAxis().length() / 2;
|
||||
}
|
||||
|
||||
qreal getVerticalRadius() const {
|
||||
qreal getVerticalRadius() const
|
||||
{
|
||||
return getVerticalAxis().length() / 2;
|
||||
}
|
||||
|
||||
@@ -276,7 +333,8 @@ public:
|
||||
*/
|
||||
virtual bool includesPoint(qreal x, qreal y);
|
||||
|
||||
virtual bool includesPoint(const QPointF& p) {
|
||||
virtual bool includesPoint(const QPointF& p)
|
||||
{
|
||||
return includesPoint(p.x(), p.y());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user