/************************************************************************ ** ** @file vlayoutdetail.cpp ** @author Roman Telezhynskyi ** @date 2 1, 2015 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. ** Copyright (C) 2015 Valentina project ** All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** Valentina is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Valentina. If not, see . ** *************************************************************************/ #include "vlayoutdetail.h" #include "vlayoutdetail_p.h" //--------------------------------------------------------------------------------------------------------------------- VLayoutDetail::VLayoutDetail() :VAbstractDetail(), d(new VLayoutDetailData) {} //--------------------------------------------------------------------------------------------------------------------- VLayoutDetail::VLayoutDetail(const VLayoutDetail &detail) :VAbstractDetail(detail), d (detail.d) {} //--------------------------------------------------------------------------------------------------------------------- VLayoutDetail &VLayoutDetail::operator=(const VLayoutDetail &detail) { if ( &detail == this ) { return *this; } VAbstractDetail::operator=(detail); d = detail.d; return *this; } //--------------------------------------------------------------------------------------------------------------------- VLayoutDetail::~VLayoutDetail() {} //--------------------------------------------------------------------------------------------------------------------- QVector VLayoutDetail::GetContour() const { return d->contour; } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::SetCountour(const QVector &points) { d->contour = points; // Contour can't be closed if (d->contour.first() == d->contour.last()) { d->contour.removeLast(); } } //--------------------------------------------------------------------------------------------------------------------- QVector VLayoutDetail::GetSeamAllowencePoints() const { return d->seamAllowence; } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::SetSeamAllowencePoints(const QVector &points) { d->seamAllowence = points; // Seam allowence can't be closed if (d->seamAllowence.first() == d->seamAllowence.last()) { d->seamAllowence.removeLast(); } } //--------------------------------------------------------------------------------------------------------------------- QVector VLayoutDetail::GetLayoutAllowence() const { return Map(d->layoutAllowence); } //--------------------------------------------------------------------------------------------------------------------- QMatrix VLayoutDetail::GetMatrix() const { return d->matrix; } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::SetMatrix(const QMatrix &matrix) { d->matrix = matrix; } //--------------------------------------------------------------------------------------------------------------------- qreal VLayoutDetail::GetLayoutWidth() const { return d->layoutWidth; } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::SetLayoutWidth(const qreal &value) { d->layoutWidth = value; } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::Translate(qreal dx, qreal dy) { d->matrix = d->matrix.translate(dx, dy); } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::Rotate(const QPointF &originPoint, qreal degrees) { Translate(-originPoint.x(), -originPoint.y()); d->matrix = d->matrix.rotate(degrees); Translate(originPoint.x(), originPoint.y()); } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::Mirror(const QLineF &edge) { if (edge.isNull()) { return; } QLineF axis = QLineF(edge.x1(), edge.y1(), 100, edge.y2()); // Ox axis qreal angle = edge.angleTo(axis); Rotate(edge.p1(), angle); d->matrix = d->matrix.scale(d->matrix.m11()*-1, d->matrix.m22()); Rotate(edge.p1(), 360 - angle); } //--------------------------------------------------------------------------------------------------------------------- int VLayoutDetail::EdgesCount() const { return d->layoutAllowence.count(); } //--------------------------------------------------------------------------------------------------------------------- QLineF VLayoutDetail::Edge(int i) const { if (i < 1 || i > EdgesCount()) { // Doesn't exist such edge return QLineF(); } const QVector points = GetLayoutAllowence(); QLineF edge; if (i < EdgesCount()) { edge = QLineF(points.at(i-1), points.at(i)); } else { edge = QLineF(points.at(EdgesCount()-1), points.at(0)); } return edge; } //--------------------------------------------------------------------------------------------------------------------- int VLayoutDetail::EdgeByPoint(const QPointF &p1) const { if (p1.isNull()) { return 0; } if (EdgesCount() < 3) { return 0; } const QVector points = GetLayoutAllowence(); for (int i=0; i< points.size(); i++) { if (points.at(i) == p1) { return i+1; } } return 0; // Did not find edge } //--------------------------------------------------------------------------------------------------------------------- QRectF VLayoutDetail::BoundingRect() const { QVector points = GetLayoutAllowence(); points.append(points.first()); return QPolygonF(points).boundingRect(); } //--------------------------------------------------------------------------------------------------------------------- void VLayoutDetail::SetLayoutAllowence() { if (d->layoutWidth > 0) { if (getSeamAllowance()) { d->layoutAllowence = Equidistant(d->seamAllowence, EquidistantType::CloseEquidistant, d->layoutWidth); } else { d->layoutAllowence = Equidistant(d->contour, EquidistantType::CloseEquidistant, d->layoutWidth); } } else { d->layoutAllowence.clear(); } } //--------------------------------------------------------------------------------------------------------------------- QVector VLayoutDetail::Map(const QVector &points) const { QVector p; for (int i = 0; i < points.size(); ++i) { p.append(d->matrix.map(points.at(i))); } if (d->matrix.m11() < 0) { QList list = p.toList(); for(int k=0, s=list.size(), max=(s/2); k