Improve handling four ways grainlines.
This commit is contained in:
parent
894e2dffac
commit
1311c794c3
|
@ -29,11 +29,13 @@
|
|||
|
||||
#include <QtMath>
|
||||
|
||||
#include "vpsheet.h"
|
||||
#include "vplayout.h"
|
||||
#include "../vlayout/vtextmanager.h"
|
||||
#include "../vlayout/vlayoutpiecepath.h"
|
||||
#include "../vgeometry/vlayoutplacelabel.h"
|
||||
#include "../vlayout/vlayoutpiecepath.h"
|
||||
#include "../vlayout/vtextmanager.h"
|
||||
#include "qline.h"
|
||||
#include "vpiecegrainline.h"
|
||||
#include "vplayout.h"
|
||||
#include "vpsheet.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QLoggingCategory>
|
||||
|
@ -154,12 +156,7 @@ void VPPiece::Update(const VPPiecePtr &piece)
|
|||
SetInternalPaths(piece->GetInternalPaths());
|
||||
SetPassmarks(piece->GetPassmarks());
|
||||
SetPlaceLabels(piece->GetPlaceLabels());
|
||||
|
||||
SetGrainlineEnabled(piece->IsGrainlineEnabled());
|
||||
SetGrainlineAngle(piece->GrainlineAngle());
|
||||
SetGrainlineArrowType(piece->GrainlineArrowType());
|
||||
SetGrainlinePoints(piece->GetGrainline());
|
||||
|
||||
SetGrainline(piece->GetGrainline());
|
||||
SetPieceLabelRect(piece->GetPieceLabelRect());
|
||||
SetPieceLabelData(piece->GetPieceLabelData());
|
||||
SetPatternLabelRect(piece->GetPatternLabelRect());
|
||||
|
@ -225,112 +222,62 @@ void VPPiece::RotateToGrainline(const VPTransformationOrigon &origin)
|
|||
return;
|
||||
}
|
||||
|
||||
const QVector<QPointF> grainlinePoints = GetMappedGrainline();
|
||||
if (grainlinePoints.count() < 2)
|
||||
const QLineF grainline = GetMappedGrainlineMainLine();
|
||||
if (grainline.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QLineF grainline(ConstFirst(grainlinePoints), ConstLast(grainlinePoints));
|
||||
|
||||
QLineF canonical(ConstFirst(grainlinePoints).x(), ConstFirst(grainlinePoints).y(),
|
||||
ConstFirst(grainlinePoints).x()+100, ConstFirst(grainlinePoints).y());
|
||||
|
||||
GrainlineType grainlineType = sheet->GrainlineOrientation();
|
||||
|
||||
auto DegreesAtFront = [grainline, canonical, grainlineType]()
|
||||
QLineF fabricGrainline(grainline.p1().x(), grainline.p1().y(), grainline.p1().x() + 100, grainline.p1().y());
|
||||
if (sheet->GrainlineOrientation() == GrainlineType::Vertical)
|
||||
{
|
||||
QLineF atFront = canonical;
|
||||
if (grainlineType == GrainlineType::Vertical)
|
||||
{
|
||||
atFront.setAngle(90);
|
||||
fabricGrainline.setAngle(fabricGrainline.angle() - 90);
|
||||
}
|
||||
|
||||
qreal angleTo = grainline.angleTo(atFront);
|
||||
return angleTo;
|
||||
};
|
||||
QVector<qreal> angles;
|
||||
angles.reserve(4);
|
||||
|
||||
auto DegreesAtRear = [grainline, canonical, grainlineType]()
|
||||
const VPieceGrainline pieceGrainline = GetGrainline();
|
||||
|
||||
if (pieceGrainline.IsArrowUpEnabled())
|
||||
{
|
||||
QLineF atRear = canonical;
|
||||
atRear.setAngle(grainlineType == GrainlineType::Vertical ? 270 : 180);
|
||||
angles.append(grainline.angleTo(fabricGrainline));
|
||||
}
|
||||
|
||||
qreal angleTo = grainline.angleTo(atRear);
|
||||
return angleTo;
|
||||
};
|
||||
if (pieceGrainline.IsArrowDownEnabled())
|
||||
{
|
||||
QLineF arrow = grainline;
|
||||
arrow.setAngle(arrow.angle() + 180);
|
||||
angles.append(arrow.angleTo(fabricGrainline));
|
||||
}
|
||||
|
||||
if (pieceGrainline.IsArrowLeftEnabled())
|
||||
{
|
||||
QLineF arrow = grainline;
|
||||
arrow.setAngle(arrow.angle() + 90);
|
||||
angles.append(arrow.angleTo(fabricGrainline));
|
||||
}
|
||||
|
||||
if (pieceGrainline.IsArrowRightEnabled())
|
||||
{
|
||||
QLineF arrow = grainline;
|
||||
arrow.setAngle(arrow.angle() - 90);
|
||||
angles.append(arrow.angleTo(fabricGrainline));
|
||||
}
|
||||
|
||||
GrainlineArrowDirection type = GrainlineArrowType();
|
||||
qreal degrees = 0;
|
||||
|
||||
if (type == GrainlineArrowDirection::atFront)
|
||||
if (not angles.isEmpty())
|
||||
{
|
||||
degrees = DegreesAtFront();
|
||||
}
|
||||
else if (type == GrainlineArrowDirection::atRear)
|
||||
{
|
||||
degrees = DegreesAtRear();
|
||||
}
|
||||
else if (type == GrainlineArrowDirection::atBoth)
|
||||
{
|
||||
const qreal atFront = DegreesAtFront();
|
||||
if (atFront <= 90 || atFront >= 270)
|
||||
{
|
||||
degrees = atFront;
|
||||
}
|
||||
else
|
||||
{
|
||||
degrees = DegreesAtRear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const qreal atFront = DegreesAtFront();
|
||||
if (atFront <= 45)
|
||||
{
|
||||
degrees = atFront;
|
||||
}
|
||||
else if (atFront > 45 && atFront < 90)
|
||||
{
|
||||
degrees = atFront - 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
degrees = atFront - 90 * qFloor(atFront / 90);
|
||||
}
|
||||
degrees = *std::min_element(angles.constBegin(), angles.constEnd());
|
||||
}
|
||||
|
||||
if (origin.custom)
|
||||
{
|
||||
Rotate(MappedDetailBoundingRect().center(), degrees);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rotate(origin.origin, degrees);
|
||||
}
|
||||
Rotate(origin.custom ? MappedDetailBoundingRect().center() : origin.origin, degrees);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetGrainlineEnabled(bool enabled)
|
||||
void VPPiece::SetGrainline(const VPieceGrainline &grainline)
|
||||
{
|
||||
VLayoutPiece::SetGrainlineEnabled(enabled);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetGrainlineAngle(qreal angle)
|
||||
{
|
||||
VLayoutPiece::SetGrainlineAngle(angle);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetGrainlineArrowType(GrainlineArrowDirection type)
|
||||
{
|
||||
VLayoutPiece::SetGrainlineArrowType(type);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPPiece::SetGrainlinePoints(const QVector<QPointF> &points)
|
||||
{
|
||||
VLayoutPiece::SetGrainlinePoints(points);
|
||||
VLayoutPiece::SetGrainline(grainline);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -528,7 +475,7 @@ auto VPPiece::IsValid(QString &error) const -> bool
|
|||
return false;
|
||||
}
|
||||
|
||||
if (IsGrainlineEnabled() && GetGrainline().isEmpty())
|
||||
if (IsGrainlineEnabled() && not GetGrainline().IsShapeValid())
|
||||
{
|
||||
error = tr("Grainline is empty");
|
||||
return false;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "../vlayout/vlayoutpiece.h"
|
||||
#include "../layout/layoutdef.h"
|
||||
#include "vpiecegrainline.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||
#include "../vmisc/defglobal.h"
|
||||
|
@ -92,10 +93,7 @@ public:
|
|||
auto Layout() const -> VPLayoutPtr;
|
||||
void SetLayout(const VPLayoutPtr &layout);
|
||||
|
||||
void SetGrainlineEnabled(bool enabled);
|
||||
void SetGrainlineAngle(qreal angle);
|
||||
void SetGrainlineArrowType(GrainlineArrowDirection type);
|
||||
void SetGrainlinePoints(const QVector<QPointF> &points);
|
||||
void SetGrainline(const VPieceGrainline &grainline);
|
||||
|
||||
auto GetPieceLabelRect() const -> QVector<QPointF>;
|
||||
void SetPieceLabelRect(const QVector<QPointF> &rect);
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
|
||||
#include "undocommands/vpundopiecemove.h"
|
||||
#include "undocommands/vpundomovepieceonsheet.h"
|
||||
#include "vpiecegrainline.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
@ -465,19 +466,8 @@ void VPGraphicsPiece::InitGrainlineItem()
|
|||
|
||||
if(piece->IsGrainlineEnabled())
|
||||
{
|
||||
QPainterPath grainline;
|
||||
QVector<QPointF> grainLinepoints = piece->GetMappedGrainline();
|
||||
if(!grainLinepoints.isEmpty())
|
||||
{
|
||||
grainline.moveTo(ConstFirst(grainLinepoints));
|
||||
for (int i = 1; i < grainLinepoints.size(); i++)
|
||||
{
|
||||
grainline.lineTo(grainLinepoints.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
m_grainlineItem = new VGraphicsFillItem(this);
|
||||
m_grainlineItem->setPath(grainline);
|
||||
m_grainlineItem->setPath(VLayoutPiece::GrainlinePath(piece->GetMappedGrainlineShape()));
|
||||
|
||||
VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
|
||||
QPen pen(PieceColor(), settings->GetLayoutLineWidth(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <QFont>
|
||||
#include <QXmlStreamAttributes>
|
||||
#include <ciso646>
|
||||
#include "vpiecegrainline.h"
|
||||
#include "vplayoutfilereader.h"
|
||||
#include "vplayoutliterals.h"
|
||||
#include "../layout/vpsheet.h"
|
||||
|
@ -109,29 +110,60 @@ auto StringToPath(const QString &path) -> QVector<QPointF>
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto StringToGrainlineArrowDirrection(const QString &dirrection) -> GrainlineArrowDirection
|
||||
{
|
||||
const QStringList arrows
|
||||
{
|
||||
ML::atFrontStr, // 0
|
||||
ML::atRearStr, // 1
|
||||
ML::atFourWayStr, // 2
|
||||
ML::atBothStr // 3
|
||||
const QStringList arrows{
|
||||
ML::twoWaysUpDownStr, // 0
|
||||
ML::oneWayUpStr, // 1
|
||||
ML::oneWayDownStr, // 2
|
||||
ML::fourWaysStr, // 3
|
||||
ML::twoWaysUpLeftStr, // 4
|
||||
ML::twoWaysUpRightStr, // 5
|
||||
ML::twoWaysDownLeftStr, // 6
|
||||
ML::twoWaysDownRightStr, // 7
|
||||
ML::threeWaysUpDownLeftStr, // 8
|
||||
ML::threeWaysUpDownRightStr, // 9
|
||||
ML::threeWaysUpLeftRightStr, // 10
|
||||
ML::threeWaysDownLeftRightStr, // 11
|
||||
};
|
||||
|
||||
GrainlineArrowDirection arrowDirection = GrainlineArrowDirection::atBoth;
|
||||
GrainlineArrowDirection arrowDirection = GrainlineArrowDirection::twoWaysUpDown;
|
||||
switch (arrows.indexOf(dirrection))
|
||||
{
|
||||
case 0:// at front
|
||||
arrowDirection = GrainlineArrowDirection::atFront;
|
||||
case 1: // oneWayUp
|
||||
arrowDirection = GrainlineArrowDirection::oneWayUp;
|
||||
break;
|
||||
case 1:// at rear
|
||||
arrowDirection = GrainlineArrowDirection::atRear;
|
||||
case 2: // oneWayDown
|
||||
arrowDirection = GrainlineArrowDirection::oneWayDown;
|
||||
break;
|
||||
case 2:// at four way
|
||||
arrowDirection = GrainlineArrowDirection::atFourWay;
|
||||
case 3: // fourWays
|
||||
arrowDirection = GrainlineArrowDirection::fourWays;
|
||||
break;
|
||||
case 3:// at both
|
||||
case 4: // twoWaysUpLeft
|
||||
arrowDirection = GrainlineArrowDirection::twoWaysUpLeft;
|
||||
break;
|
||||
case 5: // twoWaysUpRight
|
||||
arrowDirection = GrainlineArrowDirection::twoWaysUpRight;
|
||||
break;
|
||||
case 6: // twoWaysDownLeft
|
||||
arrowDirection = GrainlineArrowDirection::twoWaysDownLeft;
|
||||
break;
|
||||
case 7: // twoWaysDownRight
|
||||
arrowDirection = GrainlineArrowDirection::twoWaysDownRight;
|
||||
break;
|
||||
case 8: // threeWaysUpDownLeft
|
||||
arrowDirection = GrainlineArrowDirection::threeWaysUpDownLeft;
|
||||
break;
|
||||
case 9: // threeWaysUpDownRight
|
||||
arrowDirection = GrainlineArrowDirection::threeWaysUpDownRight;
|
||||
break;
|
||||
case 10: // threeWaysUpLeftRight
|
||||
arrowDirection = GrainlineArrowDirection::threeWaysUpLeftRight;
|
||||
break;
|
||||
case 11: // threeWaysDownLeftRight
|
||||
arrowDirection = GrainlineArrowDirection::threeWaysDownLeftRight;
|
||||
break;
|
||||
case 0: // twoWaysUpDown
|
||||
default:
|
||||
arrowDirection = GrainlineArrowDirection::atBoth;
|
||||
arrowDirection = GrainlineArrowDirection::twoWaysUpDown;
|
||||
break;
|
||||
}
|
||||
return arrowDirection;
|
||||
|
@ -600,23 +632,26 @@ void VPLayoutFileReader::ReadGrainline(const VPPiecePtr &piece)
|
|||
{
|
||||
AssertRootTag(ML::TagGrainline);
|
||||
|
||||
VPieceGrainline grainline;
|
||||
|
||||
QXmlStreamAttributes attribs = attributes();
|
||||
bool enabled = ReadAttributeBool(attribs, ML::AttrEnabled, falseStr);
|
||||
piece->SetGrainlineEnabled(enabled);
|
||||
QVector<QPointF> path = StringToPath(readElementText());
|
||||
grainline.SetEnabled(enabled);
|
||||
QLineF mainLine = StringToLine(readElementText());
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
piece->SetGrainlineAngle(ReadAttributeDouble(attribs, ML::AttrAngle, QChar('0')));
|
||||
QString arrowDirection = ReadAttributeEmptyString(attribs, ML::AttrArrowDirection);
|
||||
piece->SetGrainlineArrowType(StringToGrainlineArrowDirrection(arrowDirection));
|
||||
grainline.SetArrowType(StringToGrainlineArrowDirrection(arrowDirection));
|
||||
|
||||
if (path.isEmpty())
|
||||
if (mainLine.isNull())
|
||||
{
|
||||
throw VException(tr("Error in line %1. Grainline is empty.").arg(lineNumber()));
|
||||
throw VException(tr("Error in line %1. Grainline main line is empty.").arg(lineNumber()));
|
||||
}
|
||||
piece->SetGrainlinePoints(path);
|
||||
grainline.SetMainLine(mainLine);
|
||||
}
|
||||
|
||||
piece->SetGrainline(grainline);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -115,17 +115,33 @@ auto LinesToString(const QVector<QLineF> &lines) -> QString
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto GrainlineArrowDirrectionToString(GrainlineArrowDirection type) -> QString
|
||||
{
|
||||
switch(type)
|
||||
switch (type)
|
||||
{
|
||||
case GrainlineArrowDirection::atFront:
|
||||
return ML::atFrontStr;
|
||||
case GrainlineArrowDirection::atRear:
|
||||
return ML::atRearStr;
|
||||
case GrainlineArrowDirection::atFourWay:
|
||||
return ML::atFourWayStr;
|
||||
case GrainlineArrowDirection::atBoth:
|
||||
case GrainlineArrowDirection::oneWayUp:
|
||||
return ML::oneWayUpStr;
|
||||
case GrainlineArrowDirection::oneWayDown:
|
||||
return ML::oneWayDownStr;
|
||||
case GrainlineArrowDirection::fourWays:
|
||||
return ML::fourWaysStr;
|
||||
case GrainlineArrowDirection::twoWaysUpLeft:
|
||||
return ML::twoWaysUpLeftStr;
|
||||
case GrainlineArrowDirection::twoWaysUpRight:
|
||||
return ML::twoWaysUpRightStr;
|
||||
case GrainlineArrowDirection::twoWaysDownLeft:
|
||||
return ML::twoWaysDownLeftStr;
|
||||
case GrainlineArrowDirection::twoWaysDownRight:
|
||||
return ML::twoWaysDownRightStr;
|
||||
case GrainlineArrowDirection::threeWaysUpDownLeft:
|
||||
return ML::threeWaysUpDownLeftStr;
|
||||
case GrainlineArrowDirection::threeWaysUpDownRight:
|
||||
return ML::threeWaysUpDownRightStr;
|
||||
case GrainlineArrowDirection::threeWaysUpLeftRight:
|
||||
return ML::threeWaysUpLeftRightStr;
|
||||
case GrainlineArrowDirection::threeWaysDownLeftRight:
|
||||
return ML::threeWaysDownLeftRightStr;
|
||||
case GrainlineArrowDirection::twoWaysUpDown:
|
||||
default:
|
||||
return ML::atBothStr;
|
||||
return ML::twoWaysUpDownStr;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
@ -304,9 +320,8 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
|
|||
[](bool enabled) noexcept {return not enabled;});
|
||||
if (piece->IsGrainlineEnabled())
|
||||
{
|
||||
SetAttribute(ML::AttrAngle, piece->GrainlineAngle());
|
||||
SetAttribute(ML::AttrArrowDirection, GrainlineArrowDirrectionToString(piece->GrainlineArrowType()));
|
||||
writeCharacters(PathToString(piece->GetGrainline()));
|
||||
SetAttribute(ML::AttrArrowDirection, GrainlineArrowDirrectionToString(piece->GetGrainline().GetArrowType()));
|
||||
writeCharacters(LineToString(piece->GetGrainlineMainLine()));
|
||||
}
|
||||
writeEndElement();
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ class VLayoutPoint;
|
|||
class VPLayoutFileWriter : public QXmlStreamWriter
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(VPLayoutFileWriter) // NOLINT
|
||||
|
||||
public:
|
||||
VPLayoutFileWriter()= default;
|
||||
~VPLayoutFileWriter()= default;
|
||||
|
|
|
@ -85,7 +85,6 @@ const QString AttrTransform = QStringLiteral("transform"); // NOLINT(
|
|||
const QString AttrShowSeamline = QStringLiteral("showSeamline"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrEnabled = QStringLiteral("enabled"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrBuiltIn = QStringLiteral("builtIn"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrAngle = QStringLiteral("angle"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrArrowDirection = QStringLiteral("arrowDirection"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrType = QStringLiteral("type"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrBaseLine = QStringLiteral("baseLine"); // NOLINT(cert-err58-cpp)
|
||||
|
@ -115,10 +114,18 @@ const QString AttrY = QStringLiteral("y"); // NOLINT(cert-err
|
|||
const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp)
|
||||
const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp)
|
||||
|
||||
const QString atFrontStr = QStringLiteral("atFront"); // NOLINT(cert-err58-cpp)
|
||||
const QString atRearStr = QStringLiteral("atRear"); // NOLINT(cert-err58-cpp)
|
||||
const QString atFourWayStr = QStringLiteral("atFourWay"); // NOLINT(cert-err58-cpp)
|
||||
const QString atBothStr = QStringLiteral("atBoth"); // NOLINT(cert-err58-cpp)
|
||||
const QString oneWayUpStr = QStringLiteral("oneWayUp"); // NOLINT(cert-err58-cpp)
|
||||
const QString oneWayDownStr = QStringLiteral("oneWayDown"); // NOLINT(cert-err58-cpp)
|
||||
const QString fourWaysStr = QStringLiteral("fourWays"); // NOLINT(cert-err58-cpp)
|
||||
const QString twoWaysUpDownStr = QStringLiteral("twoWaysUpDown"); // NOLINT(cert-err58-cpp)
|
||||
const QString twoWaysUpLeftStr = QStringLiteral("twoWaysUpLeft"); // NOLINT(cert-err58-cpp)
|
||||
const QString twoWaysUpRightStr = QStringLiteral("twoWaysUpRight"); // NOLINT(cert-err58-cpp)
|
||||
const QString twoWaysDownLeftStr = QStringLiteral("twoWaysDownLeft"); // NOLINT(cert-err58-cpp)
|
||||
const QString twoWaysDownRightStr = QStringLiteral("twoWaysDownRight"); // NOLINT(cert-err58-cpp)
|
||||
const QString threeWaysUpDownLeftStr = QStringLiteral("threeWaysUpDownLeft"); // NOLINT(cert-err58-cpp)
|
||||
const QString threeWaysUpDownRightStr = QStringLiteral("threeWaysUpDownRight"); // NOLINT(cert-err58-cpp)
|
||||
const QString threeWaysUpLeftRightStr = QStringLiteral("threeWaysUpLeftRight"); // NOLINT(cert-err58-cpp)
|
||||
const QString threeWaysDownLeftRightStr = QStringLiteral("threeWaysDownLeftRight"); // NOLINT(cert-err58-cpp)
|
||||
|
||||
const QChar groupSep = QLatin1Char(';');
|
||||
const QChar coordintatesSep = QLatin1Char(',');
|
||||
|
|
|
@ -90,7 +90,6 @@ extern const QString AttrTransform;
|
|||
extern const QString AttrShowSeamline;
|
||||
extern const QString AttrEnabled;
|
||||
extern const QString AttrBuiltIn;
|
||||
extern const QString AttrAngle;
|
||||
extern const QString AttrArrowDirection;
|
||||
extern const QString AttrType;
|
||||
extern const QString AttrBaseLine;
|
||||
|
@ -120,10 +119,18 @@ extern const QString AttrY;
|
|||
extern const QString AttrTurnPoint;
|
||||
extern const QString AttrCurvePoint;
|
||||
|
||||
extern const QString atFrontStr;
|
||||
extern const QString atRearStr;
|
||||
extern const QString atFourWayStr;
|
||||
extern const QString atBothStr;
|
||||
extern const QString oneWayUpStr;
|
||||
extern const QString oneWayDownStr;
|
||||
extern const QString fourWaysStr;
|
||||
extern const QString twoWaysUpDownStr;
|
||||
extern const QString twoWaysUpLeftStr;
|
||||
extern const QString twoWaysUpRightStr;
|
||||
extern const QString twoWaysDownLeftStr;
|
||||
extern const QString twoWaysDownRightStr;
|
||||
extern const QString threeWaysUpDownLeftStr;
|
||||
extern const QString threeWaysUpDownRightStr;
|
||||
extern const QString threeWaysUpLeftRightStr;
|
||||
extern const QString threeWaysDownLeftRightStr;
|
||||
|
||||
extern const QChar groupSep;
|
||||
extern const QChar coordintatesSep;
|
||||
|
|
|
@ -1138,23 +1138,23 @@ void MainWindowsNoGUI::ExportScene(const QList<QGraphicsScene *> &scenes,
|
|||
exporter.SetFileName(name);
|
||||
exporter.SetImageRect(paper->rect());
|
||||
|
||||
QPen defaultPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(), Qt::SolidLine,
|
||||
Qt::RoundCap, Qt::RoundJoin);
|
||||
|
||||
switch (m_dialogSaveLayout->Format())
|
||||
{
|
||||
case LayoutExportFormats::SVG:
|
||||
paper->setVisible(false);
|
||||
exporter.SetPen(QPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(),
|
||||
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
exporter.SetPen(defaultPen);
|
||||
exporter.ExportToSVG(scene, details.at(i));
|
||||
paper->setVisible(true);
|
||||
break;
|
||||
case LayoutExportFormats::PDF:
|
||||
exporter.SetPen(QPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(),
|
||||
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
exporter.SetPen(defaultPen);
|
||||
exporter.ExportToPDF(scene, details.at(i));
|
||||
break;
|
||||
case LayoutExportFormats::PNG:
|
||||
exporter.SetPen(QPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(),
|
||||
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
exporter.SetPen(defaultPen);
|
||||
exporter.ExportToPNG(scene, details.at(i));
|
||||
break;
|
||||
case LayoutExportFormats::OBJ:
|
||||
|
@ -1163,13 +1163,11 @@ void MainWindowsNoGUI::ExportScene(const QList<QGraphicsScene *> &scenes,
|
|||
paper->setVisible(true);
|
||||
break;
|
||||
case LayoutExportFormats::PS:
|
||||
exporter.SetPen(QPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(),
|
||||
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
exporter.SetPen(defaultPen);
|
||||
exporter.ExportToPS(scene, details.at(i));
|
||||
break;
|
||||
case LayoutExportFormats::EPS:
|
||||
exporter.SetPen(QPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(),
|
||||
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
exporter.SetPen(defaultPen);
|
||||
exporter.ExportToEPS(scene, details.at(i));
|
||||
break;
|
||||
case LayoutExportFormats::DXF_AC1006_Flat:
|
||||
|
@ -1227,8 +1225,7 @@ void MainWindowsNoGUI::ExportScene(const QList<QGraphicsScene *> &scenes,
|
|||
paper->setVisible(true);
|
||||
break;
|
||||
case LayoutExportFormats::TIF:
|
||||
exporter.SetPen(QPen(Qt::black, VAbstractApplication::VApp()->Settings()->WidthHairLine(),
|
||||
Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
exporter.SetPen(defaultPen);
|
||||
exporter.ExportToTIF(scene, details.at(i));
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -96,5 +96,6 @@
|
|||
<file>schema/layout/v0.1.2.xsd</file>
|
||||
<file>schema/layout/v0.1.3.xsd</file>
|
||||
<file>schema/layout/v0.1.4.xsd</file>
|
||||
<file>schema/layout/v0.1.5.xsd</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
579
src/libs/ifc/schema/layout/v0.1.5.xsd
Normal file
579
src/libs/ifc/schema/layout/v0.1.5.xsd
Normal file
|
@ -0,0 +1,579 @@
|
|||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="layout">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="properties">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="units" name="unit"/>
|
||||
<xs:element type="xs:string" name="title"/>
|
||||
<xs:element type="xs:string" name="description"/>
|
||||
<xs:element name="control">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:boolean" name="warningSuperposition"/>
|
||||
<xs:attribute type="xs:boolean" name="warningOutOfBound"/>
|
||||
<xs:attribute type="xs:boolean" name="stickyEdges"/>
|
||||
<xs:attribute type="xs:boolean" name="followGrainline"/>
|
||||
<xs:attribute type="xs:float" name="piecesGap"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="tiles">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="size">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:float" name="width" use="required"/>
|
||||
<xs:attribute type="xs:float" name="length" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="margin">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:float" name="top"/>
|
||||
<xs:attribute type="xs:float" name="right"/>
|
||||
<xs:attribute type="xs:float" name="bottom"/>
|
||||
<xs:attribute type="xs:float" name="left"/>
|
||||
<xs:attribute type="xs:boolean" name="ignoreMargins"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:boolean" name="visible"/>
|
||||
<xs:attribute type="xs:string" name="matchingMarks"/>
|
||||
<xs:attribute type="xs:boolean" name="printScheme"/>
|
||||
<xs:attribute type="xs:boolean" name="tileNumber"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="scale">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="LayoutScale" name="xScale"/>
|
||||
<xs:attribute type="LayoutScale" name="yScale"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="watermark">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:boolean" name="showPreview" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="unplacedPieces">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="piece" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="seamLine">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:double" name="x" use="required"/>
|
||||
<xs:attribute type="xs:double" name="y" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="seamAllowance">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:double" name="x" use="required"/>
|
||||
<xs:attribute type="xs:double" name="y" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="grainline">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="LinePathOrEmpty">
|
||||
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
|
||||
<xs:attribute type="ArrowDirection" name="arrowDirection" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="notches">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="notch" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
|
||||
<xs:attribute type="NotchType" name="type" use="optional"/>
|
||||
<xs:attribute type="LinePath" name="baseLine" use="optional"/>
|
||||
<xs:attribute type="LinesPath" name="path" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="internalPaths">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="internalPath" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="point" minOccurs="2" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:double" name="x" use="required"/>
|
||||
<xs:attribute type="xs:double" name="y" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:boolean" name="cut" use="optional"/>
|
||||
<xs:attribute type="CurvePenStyle" name="penStyle" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="markers">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="marker" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="Transformation" name="transform" use="required"/>
|
||||
<xs:attribute type="MarkerType" name="type" use="required"/>
|
||||
<xs:attribute type="PointPath" name="center" use="required"/>
|
||||
<xs:attribute type="RectPath" name="box" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="labels">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="pieceLabel" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="lines">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="alignment" use="optional"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="font"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="shape" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="lines">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="alignment" use="optional"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="font"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="shape" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="uid" type="uuid" use="required"/>
|
||||
<xs:attribute type="xs:string" name="name"/>
|
||||
<xs:attribute type="xs:boolean" name="mirrored"/>
|
||||
<xs:attribute type="xs:boolean" name="forbidFlipping"/>
|
||||
<xs:attribute type="xs:boolean" name="forceFlipping"/>
|
||||
<xs:attribute type="xs:boolean" name="sewLineOnDrawing"/>
|
||||
<xs:attribute type="Transformation" name="transform"/>
|
||||
<xs:attribute type="xs:string" name="gradationLabel"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="copyNumber"/>
|
||||
<xs:attribute type="xs:boolean" name="showSeamline"/>
|
||||
<xs:attribute type="xs:float" name="xScale"/>
|
||||
<xs:attribute type="xs:float" name="yScale"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="sheets">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="sheet" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:string" name="name"/>
|
||||
<xs:element name="size">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:float" name="width" use="required"/>
|
||||
<xs:attribute type="xs:float" name="length" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="margin">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:float" name="top"/>
|
||||
<xs:attribute type="xs:float" name="right"/>
|
||||
<xs:attribute type="xs:float" name="bottom"/>
|
||||
<xs:attribute type="xs:float" name="left"/>
|
||||
<xs:attribute type="xs:boolean" name="ignoreMargins"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="pieces">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="piece" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="seamLine">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:double" name="x" use="required"/>
|
||||
<xs:attribute type="xs:double" name="y" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="seamAllowance">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:double" name="x" use="required"/>
|
||||
<xs:attribute type="xs:double" name="y" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="grainline">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="LinePathOrEmpty">
|
||||
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
|
||||
<xs:attribute type="ArrowDirection" name="arrowDirection" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="notches">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="notch" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
|
||||
<xs:attribute type="NotchType" name="type" use="optional"/>
|
||||
<xs:attribute type="LinePath" name="baseLine" use="optional"/>
|
||||
<xs:attribute type="LinesPath" name="path" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="internalPaths">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="internalPath" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="point" minOccurs="2" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="xs:double" name="x" use="required"/>
|
||||
<xs:attribute type="xs:double" name="y" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:boolean" name="cut" use="optional"/>
|
||||
<xs:attribute type="CurvePenStyle" name="penStyle" use="optional"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="markers">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:element name="marker" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:attribute type="Transformation" name="transform" use="required"/>
|
||||
<xs:attribute type="MarkerType" name="type" use="required"/>
|
||||
<xs:attribute type="PointPath" name="center" use="required"/>
|
||||
<xs:attribute type="RectPath" name="box" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="labels">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="pieceLabel" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="lines">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
|
||||
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="font"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="PathNotEmpty" name="shape" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="lines">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
|
||||
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
|
||||
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="font"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="PathNotEmpty" name="shape" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="uid" type="uuid" use="required"/>
|
||||
<xs:attribute type="xs:string" name="name"/>
|
||||
<xs:attribute type="xs:boolean" name="mirrored"/>
|
||||
<xs:attribute type="xs:boolean" name="forbidFlipping"/>
|
||||
<xs:attribute type="xs:boolean" name="forceFlipping"/>
|
||||
<xs:attribute type="xs:boolean" name="sewLineOnDrawing"/>
|
||||
<xs:attribute type="Transformation" name="transform"/>
|
||||
<xs:attribute type="xs:string" name="gradationLabel"/>
|
||||
<xs:attribute type="xs:unsignedInt" name="copyNumber"/>
|
||||
<xs:attribute type="xs:boolean" name="showSeamline"/>
|
||||
<xs:attribute type="xs:float" name="xScale"/>
|
||||
<xs:attribute type="xs:float" name="yScale"/>
|
||||
<xs:attribute type="xs:float" name="zValue"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="GrainlineType" name="grainlineType"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="formatVersion" name="version" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!--Types-->
|
||||
<xs:simpleType name="formatVersion">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="units">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="mm"/>
|
||||
<xs:enumeration value="cm"/>
|
||||
<xs:enumeration value="inch"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="uuid">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="|\{[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}\}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="ArrowDirection">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="oneWayUp"/>
|
||||
<xs:enumeration value="oneWayDown"/>
|
||||
<xs:enumeration value="twoWaysUpDown"/>
|
||||
<xs:enumeration value="fourWays"/>
|
||||
<xs:enumeration value="twoWaysUpLeft"/>
|
||||
<xs:enumeration value="twoWaysUpRight"/>
|
||||
<xs:enumeration value="twoWaysDownLeft"/>
|
||||
<xs:enumeration value="twoWaysDownRight"/>
|
||||
<xs:enumeration value="threeWaysUpDownLeft"/>
|
||||
<xs:enumeration value="threeWaysUpDownRight"/>
|
||||
<xs:enumeration value="threeWaysUpLeftRight"/>
|
||||
<xs:enumeration value="threeWaysDownLeftRight"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="NotchType">
|
||||
<xs:restriction base="xs:unsignedInt">
|
||||
<xs:enumeration value="0"/>
|
||||
<!--OneLine-->
|
||||
<xs:enumeration value="1"/>
|
||||
<!--TwoLines-->
|
||||
<xs:enumeration value="2"/>
|
||||
<!--ThreeLines-->
|
||||
<xs:enumeration value="3"/>
|
||||
<!--TMark-->
|
||||
<xs:enumeration value="4"/>
|
||||
<!--VMark-->
|
||||
<xs:enumeration value="5"/>
|
||||
<!--VMark2-->
|
||||
<xs:enumeration value="6"/>
|
||||
<!--UMark-->
|
||||
<xs:enumeration value="7"/>
|
||||
<!--BoxMark-->
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="CurvePenStyle">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="hair"/>
|
||||
<xs:enumeration value="dashLine"/>
|
||||
<xs:enumeration value="dotLine"/>
|
||||
<xs:enumeration value="dashDotLine"/>
|
||||
<xs:enumeration value="dashDotDotLine"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="MarkerType">
|
||||
<xs:restriction base="xs:unsignedInt">
|
||||
<xs:enumeration value="0"/><!--Segment-->
|
||||
<xs:enumeration value="1"/><!--Rectangle-->
|
||||
<xs:enumeration value="2"/><!--Cross-->
|
||||
<xs:enumeration value="3"/><!--Tshaped-->
|
||||
<xs:enumeration value="4"/><!--Doubletree-->
|
||||
<xs:enumeration value="5"/><!--Corner-->
|
||||
<xs:enumeration value="6"/><!--Triangle-->
|
||||
<xs:enumeration value="7"/><!--Hshaped-->
|
||||
<xs:enumeration value="8"/><!--Button-->
|
||||
<xs:enumeration value="9"/><!--Circle-->
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="AlignmentType">
|
||||
<xs:restriction base="xs:unsignedInt">
|
||||
<xs:enumeration value="0"/><!--default (no aligns)-->
|
||||
<xs:enumeration value="1"/><!--aligns with the left edge-->
|
||||
<xs:enumeration value="2"/><!--aligns with the right edge-->
|
||||
<xs:enumeration value="4"/><!--Centers horizontally in the available space-->
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="Transformation">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){8,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="PathNotEmpty">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\s){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="PathOrEmpty">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="|([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\s){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="LinePathOrEmpty">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="|[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="LinePath">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="LinesPath">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\*){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="PointPath">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="RectPath">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){3,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="GrainlineType">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="horizontal"/>
|
||||
<xs:enumeration value="vertical"/>
|
||||
<xs:enumeration value="notFixed"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="LayoutScale">
|
||||
<xs:restriction base="xs:float">
|
||||
<xs:minInclusive value="0.01"/>
|
||||
<xs:maxInclusive value="3"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:schema>
|
|
@ -946,15 +946,31 @@
|
|||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="arrowType">
|
||||
<xs:restriction base="xs:unsignedInt">
|
||||
<xs:restriction base="xs:integer">
|
||||
<xs:enumeration value="0"/>
|
||||
<!--Both-->
|
||||
<!-- Represents a two-way arrow pointing up and down -->
|
||||
<xs:enumeration value="1"/>
|
||||
<!--Front-->
|
||||
<!-- Represents a one-way arrow pointing up -->
|
||||
<xs:enumeration value="2"/>
|
||||
<!--Rear-->
|
||||
<!-- Represents a one-way arrow pointing down -->
|
||||
<xs:enumeration value="3"/>
|
||||
<!--For way-->
|
||||
<!-- Represents a four-way arrow pointing in all directions -->
|
||||
<xs:enumeration value="4"/>
|
||||
<!-- Represents a two-way arrow pointing up and left -->
|
||||
<xs:enumeration value="5"/>
|
||||
<!-- Represents a two-way arrow pointing up and right -->
|
||||
<xs:enumeration value="6"/>
|
||||
<!-- Represents a two-way arrow pointing down and left -->
|
||||
<xs:enumeration value="7"/>
|
||||
<!-- Represents a two-way arrow pointing down and right -->
|
||||
<xs:enumeration value="8"/>
|
||||
<!-- Represents a three-way arrow pointing up, down, and left -->
|
||||
<xs:enumeration value="9"/>
|
||||
<!-- Represents a three-way arrow pointing up, down, and right -->
|
||||
<xs:enumeration value="10"/>
|
||||
<!-- Represents a three-way arrow pointing up, left, and right -->
|
||||
<xs:enumeration value="11"/>
|
||||
<!-- Represents a three-way arrow pointing down, left, and right -->
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="pieceVersion">
|
||||
|
|
|
@ -196,6 +196,14 @@ inline void VDomDocument::SetAttribute<QString>(QDomElement &domElement, const Q
|
|||
domElement.setAttribute(name, value);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template <>
|
||||
inline void VDomDocument::SetAttribute<QLatin1String>(QDomElement &domElement, const QString &name,
|
||||
const QLatin1String &value) const
|
||||
{
|
||||
domElement.setAttribute(name, value);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template <>
|
||||
inline void VDomDocument::SetAttribute<QChar>(QDomElement &domElement, const QString &name, const QChar &value) const
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "../exception/vexception.h"
|
||||
#include "../ifcdef.h"
|
||||
#include "../vlayout/vlayoutpoint.h"
|
||||
#include "compatibility.h"
|
||||
#include "vpatterndb/floatItemData/floatitemdef.h"
|
||||
|
||||
/*
|
||||
* Version rules:
|
||||
|
@ -39,8 +41,8 @@
|
|||
*/
|
||||
|
||||
const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0");
|
||||
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.4");
|
||||
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.4.xsd");
|
||||
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.5");
|
||||
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.5.xsd");
|
||||
|
||||
//VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
|
||||
//VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
|
||||
|
@ -55,14 +57,17 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, strInternalPathTag, (QLatin1String("int
|
|||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strMarkerTag, (QLatin1String("marker"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strPointTag, (QLatin1String("point"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strPieceTag, (QLatin1String("piece"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strGrainlineTag, (QLatin1String("grainline"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrX, (QLatin1String("x"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrY, (QLatin1String("y"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrTurnPoint, (QLatin1String("turnPoint"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrCurvePoint, (QLatin1String("curvePoint"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrId, (QLatin1String("id"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrUId, (QLatin1String("uid"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrAngle, (QLatin1String("angle"))) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strAttrArrowDirection, (QLatin1String("arrowDirection"))) // NOLINT
|
||||
|
||||
//const QChar groupSep = QLatin1Char(';');
|
||||
const QChar groupSep = QLatin1Char(';');
|
||||
const QChar coordintatesSep = QLatin1Char(',');
|
||||
const QChar pointsSep = QLatin1Char(' ');
|
||||
//const QChar itemsSep = QLatin1Char('*');
|
||||
|
@ -92,6 +97,13 @@ auto StringV0_1_2ToPath(const QString &path) -> QVector<QPointF>
|
|||
|
||||
return p;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template <class T> auto NumberToString(T number) -> QString
|
||||
{
|
||||
const QLocale locale = QLocale::c();
|
||||
return locale.toString(number, 'g', 12).remove(LocaleGroupSeparator(locale));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -120,13 +132,13 @@ auto VLayoutConverter::GetFormatVersionStr() const -> QString
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutConverter::XSDSchemas() -> QHash<unsigned int, QString>
|
||||
{
|
||||
static auto schemas = QHash <unsigned, QString>
|
||||
{
|
||||
static auto schemas = QHash<unsigned, QString>{
|
||||
std::make_pair(FormatVersion(0, 1, 0), QStringLiteral("://schema/layout/v0.1.0.xsd")),
|
||||
std::make_pair(FormatVersion(0, 1, 1), QStringLiteral("://schema/layout/v0.1.1.xsd")),
|
||||
std::make_pair(FormatVersion(0, 1, 2), QStringLiteral("://schema/layout/v0.1.2.xsd")),
|
||||
std::make_pair(FormatVersion(0, 1, 3), QStringLiteral("://schema/layout/v0.1.3.xsd")),
|
||||
std::make_pair(FormatVersion(0, 1, 4), CurrentSchema),
|
||||
std::make_pair(FormatVersion(0, 1, 4), QStringLiteral("://schema/layout/v0.1.4.xsd")),
|
||||
std::make_pair(FormatVersion(0, 1, 5), CurrentSchema),
|
||||
};
|
||||
|
||||
return schemas;
|
||||
|
@ -159,10 +171,11 @@ void VLayoutConverter::ApplyPatches()
|
|||
ToV0_1_3();
|
||||
Q_FALLTHROUGH();
|
||||
case (FormatVersion(0, 1, 3)):
|
||||
ToV0_1_4();
|
||||
case (FormatVersion(0, 1, 4)):
|
||||
ToV0_1_5();
|
||||
ValidateXML(CurrentSchema);
|
||||
Q_FALLTHROUGH();
|
||||
case (FormatVersion(0, 1, 4)):
|
||||
case (FormatVersion(0, 1, 5)):
|
||||
break;
|
||||
default:
|
||||
InvalidVersion(m_ver);
|
||||
|
@ -264,6 +277,100 @@ void VLayoutConverter::ConvertPathToV0_1_3(QDomElement &node)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutConverter::ConvertPiecesToV0_1_5()
|
||||
{
|
||||
// TODO. Delete if minimal supported version is 0.1.5
|
||||
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 5), "Time to refactor the code.");
|
||||
|
||||
QDomNodeList grainlineTags = elementsByTagName(*strGrainlineTag);
|
||||
for (int i = 0; i < grainlineTags.size(); ++i)
|
||||
{
|
||||
QDomElement node = grainlineTags.at(i).toElement();
|
||||
if (node.isElement())
|
||||
{
|
||||
// remove angle attribute
|
||||
if (node.hasAttribute(*strAttrAngle))
|
||||
{
|
||||
node.removeAttribute(*strAttrAngle);
|
||||
}
|
||||
|
||||
// convert arrowDirection
|
||||
if (node.hasAttribute(*strAttrArrowDirection))
|
||||
{
|
||||
QString arrowDirection = node.attribute(*strAttrArrowDirection);
|
||||
|
||||
const QStringList arrows{
|
||||
"atFront", // 0
|
||||
"atRear", // 1
|
||||
"atFourWay", // 2
|
||||
"atBoth" // 3
|
||||
};
|
||||
|
||||
switch (arrows.indexOf(arrowDirection))
|
||||
{
|
||||
case 0: // at front
|
||||
SetAttribute(node, *strAttrArrowDirection, QLatin1String("oneWayUp"));
|
||||
break;
|
||||
case 1: // at rear
|
||||
SetAttribute(node, *strAttrArrowDirection, QLatin1String("oneWayDown"));
|
||||
break;
|
||||
case 2: // at four way
|
||||
SetAttribute(node, *strAttrArrowDirection, QLatin1String("fourWays"));
|
||||
break;
|
||||
case 3: // at both
|
||||
default:
|
||||
SetAttribute(node, *strAttrArrowDirection, QLatin1String("twoWaysUpDown"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto StringToPath = [](const QString &path) -> QVector<QPointF>
|
||||
{
|
||||
auto StringToPoint = [](const QString &point) -> QPointF
|
||||
{
|
||||
QStringList coordinates = point.split(coordintatesSep);
|
||||
if (coordinates.count() == 2)
|
||||
{
|
||||
return {coordinates.at(0).toDouble(), coordinates.at(1).toDouble()};
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
QVector<QPointF> p;
|
||||
if (path.isEmpty())
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
QStringList points = path.split(pointsSep);
|
||||
p.reserve(points.size());
|
||||
for (const auto &point : points)
|
||||
{
|
||||
p.append(StringToPoint(point));
|
||||
}
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
const QVector<QPointF> path = StringToPath(node.text());
|
||||
if (not path.isEmpty())
|
||||
{
|
||||
auto LineToString = [](const QLineF &line) -> QString
|
||||
{
|
||||
auto PointToString = [](const QPointF &p) -> QString
|
||||
{ return NumberToString(p.x()) + coordintatesSep + NumberToString(p.y()); };
|
||||
|
||||
return PointToString(line.p1()) + groupSep + PointToString(line.p2());
|
||||
};
|
||||
|
||||
node.firstChild().toText().setData(LineToString(QLineF(ConstFirst(path), ConstLast(path))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutConverter::ToV0_1_3()
|
||||
{
|
||||
|
@ -277,11 +384,11 @@ void VLayoutConverter::ToV0_1_3()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutConverter::ToV0_1_4()
|
||||
void VLayoutConverter::ToV0_1_5()
|
||||
{
|
||||
// TODO. Delete if minimal supported version is 0.1.4
|
||||
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 4),
|
||||
"Time to refactor the code.");
|
||||
SetVersion(QStringLiteral("0.1.4"));
|
||||
// TODO. Delete if minimal supported version is 0.1.5
|
||||
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 5), "Time to refactor the code.");
|
||||
ConvertPiecesToV0_1_5();
|
||||
SetVersion(QStringLiteral("0.1.5"));
|
||||
Save();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
static const QString LayoutMaxVerStr;
|
||||
static const QString CurrentSchema;
|
||||
static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0);
|
||||
static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 4);
|
||||
static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 5);
|
||||
|
||||
static auto XSDSchemas() -> QHash <unsigned, QString>;
|
||||
|
||||
|
@ -69,8 +69,10 @@ protected:
|
|||
void ConvertPiecesToV0_1_3();
|
||||
void ConvertPathToV0_1_3(QDomElement &node);
|
||||
|
||||
void ConvertPiecesToV0_1_5();
|
||||
|
||||
void ToV0_1_3();
|
||||
void ToV0_1_4();
|
||||
void ToV0_1_5();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vdxfengine.h"
|
||||
|
||||
#include <QLineF>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QColor>
|
||||
#include <QDateTime>
|
||||
|
@ -866,10 +866,10 @@ void VDxfEngine::ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBloc
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VDxfEngine::ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail)
|
||||
{
|
||||
const QVector<QPointF> grainline = detail.GetMappedGrainline();
|
||||
if (grainline.count() > 1)
|
||||
const QLineF grainlineMainLine = detail.GetMappedGrainlineMainLine();
|
||||
if (not grainlineMainLine.isNull())
|
||||
{
|
||||
if (DRW_Entity *e = AAMALine(QLineF(ConstFirst(grainline), ConstLast(grainline)), *layer7))
|
||||
if (DRW_Entity *e = AAMALine(grainlineMainLine, *layer7))
|
||||
{
|
||||
detailBlock->ent.push_back(e);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vabstractpiece.h"
|
||||
#include "qline.h"
|
||||
#include "qmath.h"
|
||||
#include "vabstractpiece_p.h"
|
||||
#include "../vmisc/vabstractvalapplication.h"
|
||||
#include "../vgeometry/vpointf.h"
|
||||
|
@ -37,7 +39,7 @@
|
|||
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
|
||||
#include "../vpatterndb/vcontainer.h"
|
||||
#include "../vpatterndb/calculator.h"
|
||||
#include "testpath.h"
|
||||
#include "../vwidgets/vpiecegrainline.h"
|
||||
#include "vrawsapoint.h"
|
||||
|
||||
#include <QLineF>
|
||||
|
@ -1603,7 +1605,6 @@ auto VAbstractPiece::RollbackSeamAllowance(QVector<VRawSAPoint> points, const QL
|
|||
return points;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractPiece::IsItemContained(const QRectF &parentBoundingRect, const QVector<QPointF> &shape, qreal &dX,
|
||||
qreal &dY) -> bool
|
||||
|
@ -1749,81 +1750,48 @@ auto VAbstractPiece::FindGrainlineGeometry(const VGrainlineData& geom, const VCo
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractPiece::GrainlinePoints(const VGrainlineData &geom, const VContainer *pattern, const QRectF &boundingRect,
|
||||
qreal &dAng) -> QVector<QPointF>
|
||||
auto VAbstractPiece::GrainlineMainLine(const VGrainlineData &geom, const VContainer *pattern,
|
||||
const QRectF &boundingRect) -> QLineF
|
||||
{
|
||||
SCASSERT(pattern != nullptr)
|
||||
|
||||
QPointF pt1;
|
||||
qreal dLen = 0;
|
||||
if ( not FindGrainlineGeometry(geom, pattern, dLen, dAng, pt1))
|
||||
qreal dAng = 0;
|
||||
if (not FindGrainlineGeometry(geom, pattern, dLen, dAng, pt1))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
qreal rotation = dAng;
|
||||
QPointF pt2(pt1.x() + dLen * qCos(dAng), pt1.y() - dLen * qSin(dAng));
|
||||
|
||||
QPointF pt2(pt1.x() + dLen * qCos(rotation), pt1.y() - dLen * qSin(rotation));
|
||||
|
||||
const qreal dArrowLen = ToPixel(0.5, *pattern->GetPatternUnit());
|
||||
const qreal dArrowAng = M_PI/9;
|
||||
VPieceGrainline grainline(QLineF(pt1, pt2), geom.GetArrowType());
|
||||
|
||||
QVector<QPointF> v;
|
||||
v << pt1;
|
||||
|
||||
if (geom.GetArrowType() != GrainlineArrowDirection::atFront)
|
||||
if (grainline.IsFourWays())
|
||||
{
|
||||
v << QPointF(pt1.x() + dArrowLen * qCos(rotation + dArrowAng),
|
||||
pt1.y() - dArrowLen * qSin(rotation + dArrowAng));
|
||||
v << QPointF(pt1.x() + dArrowLen * qCos(rotation - dArrowAng),
|
||||
pt1.y() - dArrowLen * qSin(rotation - dArrowAng));
|
||||
v << pt1;
|
||||
|
||||
if (geom.GetArrowType() == GrainlineArrowDirection::atFourWay)
|
||||
{ // second double arrow
|
||||
QLineF line(pt2, pt1);
|
||||
line.setLength(line.length() - dArrowLen - dArrowLen*0.5);
|
||||
|
||||
v << line.p2();
|
||||
v << QPointF(line.p2().x() + dArrowLen * qCos(rotation + dArrowAng),
|
||||
line.p2().y() - dArrowLen * qSin(rotation + dArrowAng));
|
||||
v << QPointF(line.p2().x() + dArrowLen * qCos(rotation - dArrowAng),
|
||||
line.p2().y() - dArrowLen * qSin(rotation - dArrowAng));
|
||||
v << line.p2();
|
||||
QLineF mainLine = grainline.GetMainLine();
|
||||
QLineF secondaryLine = grainline.SecondaryLine();
|
||||
v = {mainLine.p1(), mainLine.p2(), secondaryLine.p1(), secondaryLine.p2()};
|
||||
}
|
||||
}
|
||||
|
||||
if (geom.GetArrowType() != GrainlineArrowDirection::atFourWay)
|
||||
else
|
||||
{
|
||||
v << pt2;
|
||||
QLineF mainLine = grainline.GetMainLine();
|
||||
v = {mainLine.p1(), mainLine.p2()};
|
||||
}
|
||||
|
||||
if (geom.GetArrowType() != GrainlineArrowDirection::atRear)
|
||||
qreal dX = 0;
|
||||
qreal dY = 0;
|
||||
if (not IsItemContained(boundingRect, v, dX, dY))
|
||||
{
|
||||
rotation += M_PI;
|
||||
pt1.rx() = + dX;
|
||||
pt1.ry() = + dY;
|
||||
|
||||
if (geom.GetArrowType() == GrainlineArrowDirection::atFourWay)
|
||||
{ // first double arrow
|
||||
QLineF line(pt1, pt2);
|
||||
line.setLength(line.length() - dArrowLen - dArrowLen*0.5);
|
||||
|
||||
v << line.p2();
|
||||
v << QPointF(line.p2().x() + dArrowLen * qCos(rotation + dArrowAng),
|
||||
line.p2().y() - dArrowLen * qSin(rotation + dArrowAng));
|
||||
v << QPointF(line.p2().x() + dArrowLen * qCos(rotation - dArrowAng),
|
||||
line.p2().y() - dArrowLen * qSin(rotation - dArrowAng));
|
||||
v << line.p2();
|
||||
v << pt2;
|
||||
pt2.rx() = + dX;
|
||||
pt2.ry() = + dY;
|
||||
}
|
||||
|
||||
v << QPointF(pt2.x() + dArrowLen * qCos(rotation + dArrowAng),
|
||||
pt2.y() - dArrowLen * qSin(rotation + dArrowAng));
|
||||
v << QPointF(pt2.x() + dArrowLen * qCos(rotation - dArrowAng),
|
||||
pt2.y() - dArrowLen * qSin(rotation - dArrowAng));
|
||||
v << pt2;
|
||||
}
|
||||
|
||||
return CorrectPosition(boundingRect, v);
|
||||
return {pt1, pt2};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -126,8 +126,8 @@ public:
|
|||
static auto RollbackSeamAllowance(QVector<VRawSAPoint> points, const QLineF &cuttingEdge,
|
||||
bool *success) -> QVector<VRawSAPoint>;
|
||||
|
||||
static auto GrainlinePoints(const VGrainlineData &geom, const VContainer *pattern,
|
||||
const QRectF &boundingRect, qreal &dAng) -> QVector<QPointF>;
|
||||
static auto GrainlineMainLine(const VGrainlineData &geom, const VContainer *pattern,
|
||||
const QRectF &boundingRect) -> QLineF;
|
||||
|
||||
friend auto operator<< (QDataStream& dataStream, const VAbstractPiece& piece) -> QDataStream&;
|
||||
friend auto operator>> (QDataStream& dataStream, VAbstractPiece& piece) -> QDataStream&;
|
||||
|
|
|
@ -33,6 +33,11 @@ VGraphicsFillItem::VGraphicsFillItem(QGraphicsItem *parent)
|
|||
:QGraphicsPathItem(parent)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VGraphicsFillItem::VGraphicsFillItem(const QPainterPath &path, QGraphicsItem *parent)
|
||||
:QGraphicsPathItem(path, parent)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VGraphicsFillItem::~VGraphicsFillItem()
|
||||
{}
|
||||
|
@ -54,6 +59,8 @@ void VGraphicsFillItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*
|
|||
{
|
||||
pen = painter->pen();
|
||||
pen.setWidthF(width);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
pen.setJoinStyle(Qt::RoundJoin);
|
||||
}
|
||||
painter->setPen(pen);
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
* @brief VGraphicsFillItem Constructor
|
||||
*/
|
||||
explicit VGraphicsFillItem(QGraphicsItem *parent = nullptr);
|
||||
|
||||
VGraphicsFillItem(const QPainterPath &path, QGraphicsItem *parent = nullptr);
|
||||
/**
|
||||
* @brief ~VGraphicsFillItem Destructor
|
||||
*/
|
||||
|
|
|
@ -46,23 +46,27 @@
|
|||
#include <QUuid>
|
||||
#include <QtMath>
|
||||
|
||||
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
|
||||
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
|
||||
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
|
||||
#include "../vpatterndb/variables/vmeasurement.h"
|
||||
#include "../vmisc/vabstractvalapplication.h"
|
||||
#include "../vgeometry/vlayoutplacelabel.h"
|
||||
#include "../vgeometry/vplacelabelitem.h"
|
||||
#include "../vgeometry/vpointf.h"
|
||||
#include "../vmisc/compatibility.h"
|
||||
#include "../vmisc/literals.h"
|
||||
#include "../vpatterndb/vcontainer.h"
|
||||
#include "../vmisc/vabstractvalapplication.h"
|
||||
#include "../vpatterndb/calculator.h"
|
||||
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
|
||||
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
|
||||
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
|
||||
#include "../vpatterndb/variables/vmeasurement.h"
|
||||
#include "../vpatterndb/vcontainer.h"
|
||||
#include "../vpatterndb/vpassmark.h"
|
||||
#include "../vpatterndb/vpiecenode.h"
|
||||
#include "../vgeometry/vpointf.h"
|
||||
#include "../vgeometry/vplacelabelitem.h"
|
||||
#include "vlayoutpiece_p.h"
|
||||
#include "vtextmanager.h"
|
||||
#include "qline.h"
|
||||
#include "qpainterpath.h"
|
||||
#include "vgobject.h"
|
||||
#include "vgraphicsfillitem.h"
|
||||
#include "../vgeometry/vlayoutplacelabel.h"
|
||||
#include "vlayoutpiece_p.h"
|
||||
#include "vpiecegrainline.h"
|
||||
#include "vtextmanager.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -751,6 +755,19 @@ auto VLayoutPiece::Map<VLayoutPoint>(QVector<VLayoutPoint> points) const -> QVec
|
|||
return points;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::Map(const GrainlineShape &shape) const -> GrainlineShape
|
||||
{
|
||||
GrainlineShape mappedShape;
|
||||
mappedShape.reserve(shape.size());
|
||||
|
||||
for (auto subShape : shape)
|
||||
{
|
||||
mappedShape.append(Map(subShape));
|
||||
}
|
||||
return mappedShape;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// cppcheck-suppress unusedFunction
|
||||
auto VLayoutPiece::GetMappedContourPoints() const -> QVector<VLayoutPoint>
|
||||
|
@ -977,77 +994,59 @@ void VLayoutPiece::SetPatternLabelData(const VTextManager &data)
|
|||
d->m_tmPattern = data;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::SetGrainline(const VPieceGrainline &grainline)
|
||||
{
|
||||
d->m_grainline = grainline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::SetGrainline(const VGrainlineData& geom, const VContainer* pattern)
|
||||
{
|
||||
qreal dAng = 0;
|
||||
|
||||
QScopedPointer<QGraphicsItem> item(GetMainPathItem());
|
||||
const QVector<QPointF> v = GrainlinePoints(geom, pattern, item->boundingRect(), dAng);
|
||||
|
||||
if (v.isEmpty())
|
||||
QLineF mainLine = GrainlineMainLine(geom, pattern, item->boundingRect());
|
||||
if (mainLine.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_grainlineEnabled = true;
|
||||
d->m_grainlineArrowType = geom.GetArrowType();
|
||||
d->m_grainlineAngle = qRadiansToDegrees(dAng);
|
||||
d->m_grainlinePoints = v;
|
||||
d->m_grainline = VPieceGrainline(mainLine, geom.GetArrowType());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GetMappedGrainline() const -> QVector<QPointF>
|
||||
auto VLayoutPiece::GetGrainline() const -> VPieceGrainline
|
||||
{
|
||||
return Map(d->m_grainlinePoints);
|
||||
return d->m_grainline;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GetGrainline() const -> QVector<QPointF>
|
||||
auto VLayoutPiece::GetMappedGrainlineShape() const -> GrainlineShape
|
||||
{
|
||||
return d->m_grainlinePoints;
|
||||
return Map(d->m_grainline.Shape());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GetGrainlineShape() const -> GrainlineShape
|
||||
{
|
||||
return d->m_grainline.Shape();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GetMappedGrainlineMainLine() const -> QLineF
|
||||
{
|
||||
return d->m_matrix.map(d->m_grainline.GetMainLine());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GetGrainlineMainLine() const -> QLineF
|
||||
{
|
||||
return d->m_grainline.GetMainLine();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::IsGrainlineEnabled() const -> bool
|
||||
{
|
||||
return d->m_grainlineEnabled;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::SetGrainlineEnabled(bool enabled)
|
||||
{
|
||||
d->m_grainlineEnabled = enabled;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::SetGrainlineAngle(qreal angle)
|
||||
{
|
||||
d->m_grainlineAngle = angle;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::SetGrainlineArrowType(GrainlineArrowDirection type)
|
||||
{
|
||||
d->m_grainlineArrowType = type;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::SetGrainlinePoints(const QVector<QPointF> &points)
|
||||
{
|
||||
d->m_grainlinePoints = points;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GrainlineAngle() const -> qreal
|
||||
{
|
||||
return d->m_grainlineAngle;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GrainlineArrowType() const -> GrainlineArrowDirection
|
||||
{
|
||||
return d->m_grainlineArrowType;
|
||||
return d->m_grainline.IsEnabled();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1451,17 +1450,7 @@ void VLayoutPiece::DrawMiniature(QPainter &painter) const
|
|||
painter.drawPath(LabelShapePath(label));
|
||||
}
|
||||
|
||||
QVector<QPointF> gPoints = GetGrainline();
|
||||
if (not gPoints.isEmpty())
|
||||
{
|
||||
QPainterPath path;
|
||||
path.moveTo(gPoints.at(0));
|
||||
for (auto p : qAsConst(gPoints))
|
||||
{
|
||||
path.lineTo(p);
|
||||
}
|
||||
painter.drawPath(path);
|
||||
}
|
||||
painter.drawPath(VLayoutPiece::GrainlinePath(GetGrainlineShape()));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1547,6 +1536,23 @@ auto VLayoutPiece::BoundingRect(QVector<QPointF> points) -> QRectF
|
|||
return QPolygonF(points).boundingRect();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VLayoutPiece::GrainlinePath(const GrainlineShape &shape) -> QPainterPath
|
||||
{
|
||||
QPainterPath shapePath;
|
||||
for (auto subShape : shape)
|
||||
{
|
||||
QPainterPath path;
|
||||
path.moveTo(subShape.at(0));
|
||||
for (auto p : qAsConst(subShape))
|
||||
{
|
||||
path.lineTo(p);
|
||||
}
|
||||
shapePath.addPath(path);
|
||||
}
|
||||
return shapePath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VLayoutPiece::CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape,
|
||||
const VTextManager &tm, bool textAsPaths) const
|
||||
|
@ -1650,22 +1656,13 @@ void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const
|
|||
{
|
||||
SCASSERT(parent != nullptr)
|
||||
|
||||
if (not d->m_grainlineEnabled || d->m_grainlinePoints.count() < 2)
|
||||
if (not d->m_grainline.IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto* item = new VGraphicsFillItem(parent);
|
||||
|
||||
auto *item = new VGraphicsFillItem(VLayoutPiece::GrainlinePath(GetMappedGrainlineShape()), parent);
|
||||
item->SetWidth(VAbstractApplication::VApp()->Settings()->WidthHairLine());
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
QVector<QPointF> gPoints = GetMappedGrainline();
|
||||
path.moveTo(gPoints.at(0));
|
||||
for (auto p : qAsConst(gPoints))
|
||||
{
|
||||
path.lineTo(p);
|
||||
}
|
||||
item->setPath(path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -41,9 +41,11 @@
|
|||
#include <QtGlobal>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "vabstractpiece.h"
|
||||
#include "../vmisc/typedef.h"
|
||||
#include "../vpatterndb/floatItemData/floatitemdef.h"
|
||||
#include "../vwidgets/vpiecegrainline.h"
|
||||
#include "qpainterpath.h"
|
||||
#include "vabstractpiece.h"
|
||||
|
||||
#if __cplusplus >= 201703L // C++17
|
||||
#include <optional>
|
||||
|
@ -124,11 +126,12 @@ public:
|
|||
const VContainer *pattern);
|
||||
|
||||
void SetGrainline(const VGrainlineData& geom, const VContainer *pattern);
|
||||
auto GetMappedGrainline() const -> QVector<QPointF>;
|
||||
auto GetGrainline() const -> QVector<QPointF>;
|
||||
auto GetGrainline() const -> VPieceGrainline;
|
||||
auto GetMappedGrainlineShape() const -> GrainlineShape;
|
||||
auto GetGrainlineShape() const -> GrainlineShape;
|
||||
auto GetMappedGrainlineMainLine() const -> QLineF;
|
||||
auto GetGrainlineMainLine() const -> QLineF;
|
||||
auto IsGrainlineEnabled() const -> bool;
|
||||
auto GrainlineAngle() const -> qreal;
|
||||
auto GrainlineArrowType() const -> GrainlineArrowDirection;
|
||||
|
||||
auto GetMatrix() const -> QTransform;
|
||||
void SetMatrix(const QTransform &matrix);
|
||||
|
@ -174,6 +177,8 @@ public:
|
|||
|
||||
static auto BoundingRect(QVector<QPointF> points) -> QRectF;
|
||||
|
||||
static auto GrainlinePath(const GrainlineShape &shape) -> QPainterPath;
|
||||
|
||||
auto isNull() const -> bool;
|
||||
auto Square() const -> qint64;
|
||||
|
||||
|
@ -195,10 +200,7 @@ public:
|
|||
auto MapPlaceLabelShape(PlaceLabelImg shape) const -> PlaceLabelImg;
|
||||
|
||||
protected:
|
||||
void SetGrainlineEnabled(bool enabled);
|
||||
void SetGrainlineAngle(qreal angle);
|
||||
void SetGrainlineArrowType(GrainlineArrowDirection type);
|
||||
void SetGrainlinePoints(const QVector<QPointF> &points);
|
||||
void SetGrainline(const VPieceGrainline &grainline);
|
||||
|
||||
auto GetPieceLabelRect() const -> QVector<QPointF>;
|
||||
void SetPieceLabelRect(const QVector<QPointF> &rect);
|
||||
|
@ -226,6 +228,7 @@ private:
|
|||
|
||||
template <class T>
|
||||
auto Map(QVector<T> points) const -> QVector<T>;
|
||||
auto Map(const GrainlineShape &shape) const -> GrainlineShape;
|
||||
|
||||
auto Edge(const QVector<QPointF> &path, int i) const -> QLineF;
|
||||
auto EdgeByPoint(const QVector<QPointF> &path, const QPointF &p1) const -> EdgeIndex;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include <QTransform>
|
||||
|
||||
#include "../vpatterndb/floatItemData/floatitemdef.h"
|
||||
#include "../vwidgets/vpiecegrainline.h"
|
||||
#include "compatibility.h"
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
|
||||
#include "../vmisc/diagnostic.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
|
||||
|
@ -92,12 +94,7 @@ public:
|
|||
/** @brief patternInfo pattern info rectangle */
|
||||
QVector<QPointF> m_patternInfo{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
/** @brief grainlineInfo line */
|
||||
QVector<QPointF> m_grainlinePoints{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
GrainlineArrowDirection m_grainlineArrowType{GrainlineArrowDirection::atFront}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal m_grainlineAngle{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
bool m_grainlineEnabled{false}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
VPieceGrainline m_grainline{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
/** @brief m_tmDetail text manager for laying out detail info */
|
||||
VTextManager m_tmDetail{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
@ -124,7 +121,7 @@ private:
|
|||
Q_DISABLE_ASSIGN_MOVE(VLayoutPieceData) // NOLINT
|
||||
|
||||
static constexpr quint32 streamHeader{0x80D7D009}; // CRC-32Q string "VLayoutPieceData"
|
||||
static constexpr quint16 classVersion{4};
|
||||
static constexpr quint16 classVersion{5};
|
||||
};
|
||||
|
||||
QT_WARNING_POP
|
||||
|
@ -141,7 +138,6 @@ inline auto operator<<(QDataStream &dataStream, const VLayoutPieceData &piece) -
|
|||
{
|
||||
dataStream << VLayoutPieceData::streamHeader << VLayoutPieceData::classVersion;
|
||||
|
||||
// Added in classVersion = 1
|
||||
dataStream << piece.m_contour;
|
||||
dataStream << piece.m_seamAllowance;
|
||||
dataStream << piece.m_layoutAllowance;
|
||||
|
@ -152,23 +148,16 @@ inline auto operator<<(QDataStream &dataStream, const VLayoutPieceData &piece) -
|
|||
dataStream << piece.m_mirror;
|
||||
dataStream << piece.m_detailLabel;
|
||||
dataStream << piece.m_patternInfo;
|
||||
dataStream << piece.m_grainlinePoints;
|
||||
dataStream << piece.m_grainlineArrowType;
|
||||
dataStream << piece.m_grainlineAngle;
|
||||
dataStream << piece.m_grainlineEnabled;
|
||||
dataStream << piece.m_placeLabels;
|
||||
dataStream << piece.m_square;
|
||||
|
||||
// Added in classVersion = 2
|
||||
dataStream << piece.m_quantity;
|
||||
dataStream << piece.m_id;
|
||||
|
||||
// Added in classVersion = 3
|
||||
dataStream << piece.m_tmDetail;
|
||||
dataStream << piece.m_tmPattern;
|
||||
dataStream << piece.m_gradationId;
|
||||
dataStream << piece.m_xScale;
|
||||
dataStream << piece.m_yScale;
|
||||
dataStream << piece.m_grainline;
|
||||
|
||||
return dataStream;
|
||||
}
|
||||
|
@ -181,7 +170,7 @@ inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDat
|
|||
|
||||
if (actualStreamHeader != VLayoutPieceData::streamHeader)
|
||||
{
|
||||
QString message = QCoreApplication::tr("VRawLayoutData prefix mismatch error: actualStreamHeader = 0x%1 and "
|
||||
QString message = QCoreApplication::tr("VLayoutPieceData prefix mismatch error: actualStreamHeader = 0x%1 and "
|
||||
"streamHeader = 0x%2")
|
||||
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
|
||||
.arg(VLayoutPieceData::streamHeader, 8, 0x10, QChar('0'));
|
||||
|
@ -193,7 +182,7 @@ inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDat
|
|||
|
||||
if (actualClassVersion > VLayoutPieceData::classVersion)
|
||||
{
|
||||
QString message = QCoreApplication::tr("VRawLayoutData compatibility error: actualClassVersion = %1 and "
|
||||
QString message = QCoreApplication::tr("VLayoutPieceData compatibility error: actualClassVersion = %1 and "
|
||||
"classVersion = %2")
|
||||
.arg(actualClassVersion).arg(VLayoutPieceData::classVersion);
|
||||
throw VException(message);
|
||||
|
@ -218,6 +207,7 @@ inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDat
|
|||
dataStream >> piece.m_contour;
|
||||
dataStream >> piece.m_seamAllowance;
|
||||
}
|
||||
|
||||
dataStream >> piece.m_layoutAllowance;
|
||||
dataStream >> piece.m_passmarks;
|
||||
dataStream >> piece.m_internalPaths;
|
||||
|
@ -226,10 +216,23 @@ inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDat
|
|||
dataStream >> piece.m_mirror;
|
||||
dataStream >> piece.m_detailLabel;
|
||||
dataStream >> piece.m_patternInfo;
|
||||
dataStream >> piece.m_grainlinePoints;
|
||||
dataStream >> piece.m_grainlineArrowType;
|
||||
dataStream >> piece.m_grainlineAngle;
|
||||
dataStream >> piece.m_grainlineEnabled;
|
||||
|
||||
QVector<QPointF> shape;
|
||||
GrainlineArrowDirection arrowType = GrainlineArrowDirection::oneWayUp;
|
||||
bool grainlineEnabled = false;
|
||||
|
||||
if (actualClassVersion < 5)
|
||||
{
|
||||
dataStream >> shape;
|
||||
|
||||
dataStream >> arrowType;
|
||||
|
||||
qreal grainlineAngle;
|
||||
dataStream >> grainlineAngle;
|
||||
|
||||
dataStream >> grainlineEnabled;
|
||||
}
|
||||
|
||||
dataStream >> piece.m_placeLabels;
|
||||
dataStream >> piece.m_square;
|
||||
|
||||
|
@ -248,6 +251,25 @@ inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDat
|
|||
dataStream >> piece.m_yScale;
|
||||
}
|
||||
|
||||
if (actualClassVersion >= 5)
|
||||
{
|
||||
dataStream >> piece.m_grainline;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shape.size() >= 2)
|
||||
{
|
||||
piece.m_grainline = VPieceGrainline(QLineF(ConstFirst(shape), ConstLast(shape)), arrowType);
|
||||
piece.m_grainline.SetEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
piece.m_grainline = VPieceGrainline();
|
||||
piece.m_grainline.SetArrowType(arrowType);
|
||||
piece.m_grainline.SetEnabled(grainlineEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,11 @@
|
|||
#include <Qt>
|
||||
#include <functional>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "../ifc/exception/vexception.h"
|
||||
#include "../vpatterndb/floatItemData/floatitemdef.h"
|
||||
#include "../vlayout/vlayoutpoint.h"
|
||||
#include "../vmisc/def.h"
|
||||
#include "../vpatterndb/floatItemData/floatitemdef.h"
|
||||
#include "vpiecegrainline.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -557,8 +558,9 @@ void VPosition::FollowGrainline()
|
|||
return;
|
||||
}
|
||||
|
||||
VPieceGrainline pieceGrainline = m_data.detail.GetGrainline();
|
||||
QLineF detailGrainline(10, 10, 100, 10);
|
||||
detailGrainline.setAngle(m_data.detail.GrainlineAngle());
|
||||
detailGrainline.setAngle(pieceGrainline.GetMainLine().angle());
|
||||
|
||||
if (m_data.detail.IsForceFlipping())
|
||||
{
|
||||
|
@ -574,8 +576,7 @@ void VPosition::FollowGrainline()
|
|||
|
||||
const qreal angle = detailGrainline.angleTo(FabricGrainline());
|
||||
|
||||
if (m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atBoth ||
|
||||
m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atFront)
|
||||
if (pieceGrainline.IsArrowUpEnabled())
|
||||
{
|
||||
RotateOnAngle(angle);
|
||||
}
|
||||
|
@ -585,8 +586,7 @@ void VPosition::FollowGrainline()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atBoth ||
|
||||
m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atRear)
|
||||
if (pieceGrainline.IsArrowDownEnabled())
|
||||
{
|
||||
RotateOnAngle(angle + 180);
|
||||
}
|
||||
|
@ -596,15 +596,18 @@ void VPosition::FollowGrainline()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_data.detail.GrainlineArrowType() == GrainlineArrowDirection::atFourWay)
|
||||
if (pieceGrainline.IsArrowLeftEnabled())
|
||||
{
|
||||
RotateOnAngle(angle + 90);
|
||||
}
|
||||
|
||||
if (stop->load())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pieceGrainline.IsArrowRightEnabled())
|
||||
{
|
||||
RotateOnAngle(angle - 90);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,16 +29,23 @@
|
|||
#ifndef FLOATITEMDEF_H
|
||||
#define FLOATITEMDEF_H
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QtTypes>
|
||||
|
||||
// denotes the type of arrow for the grainline
|
||||
enum class GrainlineArrowDirection : qint8
|
||||
{
|
||||
atBoth,
|
||||
atFront,
|
||||
atRear,
|
||||
atFourWay
|
||||
twoWaysUpDown = 0,
|
||||
oneWayUp = 1,
|
||||
oneWayDown = 2,
|
||||
fourWays = 3,
|
||||
twoWaysUpLeft = 4,
|
||||
twoWaysUpRight = 5,
|
||||
twoWaysDownLeft = 6,
|
||||
twoWaysDownRight = 7,
|
||||
threeWaysUpDownLeft = 8,
|
||||
threeWaysUpDownRight = 9,
|
||||
threeWaysUpLeftRight = 10,
|
||||
threeWaysDownLeftRight = 11
|
||||
};
|
||||
|
||||
#endif // FLOATITEMDEF_H
|
||||
|
|
|
@ -379,7 +379,12 @@ void DialogSeamAllowance::SetPiece(const VPiece &piece)
|
|||
|
||||
uiTabLabels->groupBoxDetailLabel->setEnabled(not m_templateLines.isEmpty());
|
||||
|
||||
uiTabGrainline->comboBoxArrow->setCurrentIndex(int(piece.GetGrainlineGeometry().GetArrowType()));
|
||||
int index = uiTabGrainline->comboBoxArrow->findData(static_cast<int>(piece.GetGrainlineGeometry().GetArrowType()));
|
||||
if (index == -1)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
uiTabGrainline->comboBoxArrow->setCurrentIndex(index);
|
||||
|
||||
uiTabLabels->groupBoxDetailLabel->setChecked(ppData.IsVisible());
|
||||
ChangeCurrentData(uiTabLabels->comboBoxDLCenterPin, ppData.CenterPin());
|
||||
|
@ -2656,7 +2661,7 @@ VPiece DialogSeamAllowance::CreatePiece() const
|
|||
|
||||
piece.GetGrainlineGeometry().SetVisible(uiTabGrainline->groupBoxGrainline->isChecked());
|
||||
piece.GetGrainlineGeometry().SetArrowType(
|
||||
static_cast<GrainlineArrowDirection>(uiTabGrainline->comboBoxArrow->currentIndex()));
|
||||
static_cast<GrainlineArrowDirection>(uiTabGrainline->comboBoxArrow->currentData().toInt()));
|
||||
|
||||
if (not flagGPin)
|
||||
{
|
||||
|
@ -3380,10 +3385,30 @@ void DialogSeamAllowance::InitGrainlineTab()
|
|||
|
||||
EnabledGrainline();
|
||||
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Both"));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Just front"));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Just rear"));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Four way"));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Two ways (Up/Down)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::twoWaysUpDown));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("One way (Up)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::oneWayUp));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("One way (Down)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::oneWayDown));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Four ways", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::fourWays));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Two ways (Up/Left)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::twoWaysUpLeft));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Two ways (Up/Right)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::twoWaysUpRight));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Two ways (Down/Right)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::twoWaysDownLeft));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Two ways (Down/Right)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::twoWaysDownRight));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Three ways (Up/Down/Left)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::threeWaysUpDownLeft));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Three ways (Up/Down/Right)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::threeWaysUpDownRight));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Three ways (Up/Left/Right)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::threeWaysUpLeftRight));
|
||||
uiTabGrainline->comboBoxArrow->addItem(tr("Three ways (Down/Left/Right)", "grainline direction"),
|
||||
static_cast<int>(GrainlineArrowDirection::threeWaysDownLeftRight));
|
||||
|
||||
m_iRotBaseHeight = uiTabGrainline->lineEditRotFormula->height();
|
||||
m_iLenBaseHeight = uiTabGrainline->lineEditLenFormula->height();
|
||||
|
|
|
@ -27,31 +27,32 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vtoolseamallowance.h"
|
||||
#include "../dialogs/tools/piece/dialogseamallowance.h"
|
||||
#include "../dialogs/tools/piece/dialogduplicatedetail.h"
|
||||
#include "../vpatterndb/vpiecenode.h"
|
||||
#include "../vpatterndb/vpiecepath.h"
|
||||
#include "../vpatterndb/calculator.h"
|
||||
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
|
||||
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
|
||||
#include "../vpatterndb/variables/vincrement.h"
|
||||
#include "../vgeometry/varc.h"
|
||||
#include "../vgeometry/vpointf.h"
|
||||
#include "../vgeometry/vplacelabelitem.h"
|
||||
#include "../vgeometry/vellipticalarc.h"
|
||||
#include "../ifc/xml/vpatternconverter.h"
|
||||
#include "../dialogs/tools/piece/dialogseamallowance.h"
|
||||
#include "../ifc/exception/vexceptionwrongid.h"
|
||||
#include "../ifc/xml/vlabeltemplateconverter.h"
|
||||
#include "../ifc/xml/vpatternconverter.h"
|
||||
#include "../qmuparser/qmutokenparser.h"
|
||||
#include "../undocommands/addpiece.h"
|
||||
#include "../undocommands/deletepiece.h"
|
||||
#include "../undocommands/movepiece.h"
|
||||
#include "../undocommands/savepieceoptions.h"
|
||||
#include "../undocommands/togglepiecestate.h"
|
||||
#include "../vgeometry/varc.h"
|
||||
#include "../vgeometry/vellipticalarc.h"
|
||||
#include "../vgeometry/vplacelabelitem.h"
|
||||
#include "../vgeometry/vpointf.h"
|
||||
#include "../vpatterndb/calculator.h"
|
||||
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
|
||||
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
|
||||
#include "../vpatterndb/variables/vincrement.h"
|
||||
#include "../vpatterndb/vpiecenode.h"
|
||||
#include "../vpatterndb/vpiecepath.h"
|
||||
#include "../vwidgets/global.h"
|
||||
#include "../vwidgets/vabstractmainwindow.h"
|
||||
#include "../vwidgets/vmaingraphicsview.h"
|
||||
#include "../vwidgets/vnobrushscalepathitem.h"
|
||||
#include "../vwidgets/vabstractmainwindow.h"
|
||||
#include "../vwidgets/global.h"
|
||||
#include "../qmuparser/qmutokenparser.h"
|
||||
#include "../vwidgets/vpiecegrainline.h"
|
||||
#include "toolsdef.h"
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
|
@ -2158,32 +2159,14 @@ auto VToolSeamAllowance::SelectedTools() const -> QList<VToolSeamAllowance *>
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VToolSeamAllowance::IsGrainlinePositionValid() const -> bool
|
||||
{
|
||||
QVector<QLineF> grainLine = m_grainLine->Grainline();
|
||||
VPieceGrainline grainLine = m_grainLine->Grainline();
|
||||
const VPiece detail = VAbstractTool::data.GetPiece(m_id);
|
||||
QVector<QPointF> contourPoints;
|
||||
detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()
|
||||
? CastTo(detail.SeamAllowancePoints(getData()), contourPoints)
|
||||
: CastTo(detail.MainPathPoints(getData()), contourPoints);
|
||||
|
||||
for (auto line : grainLine)
|
||||
{
|
||||
QVector<QPointF> points = VAbstractCurve::CurveIntersectLine(contourPoints, line);
|
||||
for (auto &point : points)
|
||||
{
|
||||
if (not VFuzzyComparePoints(line.p1(), point) && not VFuzzyComparePoints(line.p2(), point))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPainterPath grainLinePath;
|
||||
for (auto line : grainLine)
|
||||
{
|
||||
grainLinePath.addPath(VGObject::PainterPath(QVector<QPointF>{line.p1(), line.p2()}));
|
||||
}
|
||||
const QPainterPath contourPath = VGObject::PainterPath(contourPoints);
|
||||
return contourPath.contains(grainLinePath);
|
||||
return grainLine.IsPositionValid(contourPoints);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
**
|
||||
*************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
|
@ -36,20 +36,17 @@
|
|||
#include <QGraphicsView>
|
||||
|
||||
#include "../vmisc/def.h"
|
||||
#include "../vmisc/vmath.h"
|
||||
#include "../vmisc/vabstractvalapplication.h"
|
||||
#include "../vmisc/vabstractapplication.h"
|
||||
#include "../vmisc/literals.h"
|
||||
#include "global.h"
|
||||
#include "vpiecegrainline.h"
|
||||
|
||||
#include "vgrainlineitem.h"
|
||||
|
||||
#define ARROW_ANGLE M_PI/9
|
||||
#define ARROW_LENGTH 15
|
||||
#define RECT_WIDTH 30
|
||||
#define RESIZE_RECT_SIZE 10
|
||||
#define ROTATE_CIRC_R 7
|
||||
#define ACTIVE_Z 10
|
||||
#define LINE_PEN_WIDTH 3
|
||||
constexpr int rectWidth = 30;
|
||||
constexpr int resizeRectSize = 10;
|
||||
constexpr int rotateCircR = 7;
|
||||
constexpr int activeZ = 10;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
|
@ -58,19 +55,6 @@
|
|||
*/
|
||||
VGrainlineItem::VGrainlineItem(QGraphicsItem* pParent)
|
||||
: VPieceItem(pParent),
|
||||
m_dRotation(0),
|
||||
m_dStartRotation(0),
|
||||
m_dLength(0),
|
||||
m_polyBound(),
|
||||
m_ptStartPos(),
|
||||
m_ptStartMove(),
|
||||
m_polyResize(),
|
||||
m_dStartLength(0),
|
||||
m_ptStart(),
|
||||
m_ptFinish(),
|
||||
m_ptCenter(),
|
||||
m_dAngle(0),
|
||||
m_eArrowType(GrainlineArrowDirection::atBoth),
|
||||
m_penWidth(VAbstractApplication::VApp()->Settings()->WidthMainLine())
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
|
@ -80,18 +64,16 @@ VGrainlineItem::VGrainlineItem(QGraphicsItem* pParent)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VGrainlineItem::shape() const
|
||||
auto VGrainlineItem::shape() const -> QPainterPath
|
||||
{
|
||||
if (m_eMode == mNormal)
|
||||
{
|
||||
return MainShape();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QPainterPath path;
|
||||
path.addPolygon(m_polyBound);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -110,37 +92,39 @@ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption
|
|||
|
||||
const qreal width = ScaleWidth(VAbstractApplication::VApp()->Settings()->WidthHairLine(), SceneScale(scene()));
|
||||
pP->setPen(QPen(clr, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
|
||||
pP->setRenderHints(QPainter::Antialiasing);
|
||||
// line
|
||||
const QLineF mainLine = MainLine();
|
||||
|
||||
VPieceGrainline grainline(QPointF(), m_dLength, m_dRotation, m_eArrowType);
|
||||
// main line
|
||||
const QLineF mainLine = grainline.GetMainLine();
|
||||
pP->drawLine(mainLine.p1(), mainLine.p2());
|
||||
|
||||
pP->setBrush(clr);
|
||||
|
||||
qreal dArrLen = ARROW_LENGTH;
|
||||
if (m_eArrowType != GrainlineArrowDirection::atRear)
|
||||
if (grainline.IsArrowUpEnabled())
|
||||
{
|
||||
// first arrow
|
||||
pP->drawPolygon(FirstArrow(MainLine().p2(), dArrLen));
|
||||
pP->drawPolygon(grainline.ArrowUp());
|
||||
}
|
||||
|
||||
if (m_eArrowType == GrainlineArrowDirection::atFourWay)
|
||||
{ // first double arrow
|
||||
QLineF line = MainLine();
|
||||
line.setLength(line.length() - dArrLen - dArrLen*0.5);
|
||||
pP->drawPolygon(FirstArrow(line.p2(), dArrLen));
|
||||
}
|
||||
}
|
||||
if (m_eArrowType != GrainlineArrowDirection::atFront)
|
||||
if (grainline.IsArrowDownEnabled())
|
||||
{
|
||||
// second arrow
|
||||
pP->drawPolygon(SecondArrow(MainLine().p1(), dArrLen));
|
||||
pP->drawPolygon(grainline.ArrowDown());
|
||||
}
|
||||
|
||||
if (m_eArrowType == GrainlineArrowDirection::atFourWay)
|
||||
{ // second double arrow
|
||||
QLineF line(MainLine().p2(), MainLine().p1());
|
||||
line.setLength(line.length() - dArrLen - dArrLen*0.5);
|
||||
pP->drawPolygon(SecondArrow(line.p2(), dArrLen));
|
||||
if (grainline.IsFourWays())
|
||||
{
|
||||
// secondary line
|
||||
const QLineF secondaryLine = grainline.SecondaryLine();
|
||||
pP->drawLine(secondaryLine.p1(), secondaryLine.p2());
|
||||
|
||||
if (grainline.IsArrowLeftEnabled())
|
||||
{
|
||||
pP->drawPolygon(grainline.ArrowLeft());
|
||||
}
|
||||
|
||||
if (grainline.IsArrowRightEnabled())
|
||||
{
|
||||
pP->drawPolygon(grainline.ArrowRight());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +154,7 @@ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption
|
|||
if (m_eMode == mRotate)
|
||||
{
|
||||
QPointF ptC = (m_polyBound.at(0) + m_polyBound.at(2))/2;
|
||||
qreal dRad = ROTATE_CIRC_R;
|
||||
qreal dRad = rotateCircR;
|
||||
pP->setBrush(clr);
|
||||
pP->drawEllipse(ptC, dRad, dRad);
|
||||
|
||||
|
@ -178,9 +162,9 @@ void VGrainlineItem::paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption
|
|||
pP->save();
|
||||
pP->translate(ptC);
|
||||
pP->rotate(qRadiansToDegrees(-m_dRotation));
|
||||
int iX = int(qRound(m_dLength/2 - 0.5*dRad));
|
||||
int iY = int(qRound(RECT_WIDTH - 0.5*dRad));
|
||||
int iR = int(qRound(dRad*3));
|
||||
int iX = qRound(m_dLength/2 - 0.5*dRad);
|
||||
int iY = grainline.IsFourWays() ? qRound((m_dLength/2) - 0.8*dRad) : qRound(rectWidth - 0.5*dRad);
|
||||
int iR = qRound(dRad*3);
|
||||
pP->drawArc(iX - iR, iY - iR, iR, iR, 0*16, -90*16);
|
||||
pP->drawArc(-iX, iY - iR, iR, iR, 270*16, -90*16);
|
||||
pP->drawArc(-iX, -iY, iR, iR, 180*16, -90*16);
|
||||
|
@ -202,89 +186,27 @@ void VGrainlineItem::UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal
|
|||
{
|
||||
m_dRotation = qDegreesToRadians(dRotation);
|
||||
m_dLength = dLength;
|
||||
m_eArrowType = eAT;
|
||||
|
||||
VPieceGrainline grainline(ptPos, m_dLength, m_dRotation, m_eArrowType);
|
||||
qreal dX;
|
||||
qreal dY;
|
||||
QPointF pt = ptPos;
|
||||
if (not IsContained(pt, m_dRotation, dX, dY))
|
||||
if (not grainline.IsContained(parentItem()->boundingRect(), dX, dY))
|
||||
{
|
||||
pt.setX(pt.x() + dX);
|
||||
pt.setY(pt.y() + dY);
|
||||
}
|
||||
setPos(pt);
|
||||
m_eArrowType = eAT;
|
||||
|
||||
UpdateRectangle();
|
||||
Update();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief VGrainlineItem::IsContained checks, if both ends of the grainline, starting at pt, are contained in
|
||||
* parent widget.
|
||||
* @param pt starting point of the grainline.
|
||||
* @param dRot rotation of the grainline in [rad]
|
||||
* @param dX horizontal translation needed to put the arrow inside parent item
|
||||
* @param dY vertical translation needed to put the arrow inside parent item
|
||||
* @return true, if both ends of the grainline, starting at pt, are contained in the parent widget and
|
||||
* false otherwise.
|
||||
*/
|
||||
bool VGrainlineItem::IsContained(const QPointF& pt, qreal dRot, qreal &dX, qreal &dY) const
|
||||
auto VGrainlineItem::Grainline() const -> VPieceGrainline
|
||||
{
|
||||
dX = 0;
|
||||
dY = 0;
|
||||
QPointF apt[2];
|
||||
apt[0] = pt;
|
||||
apt[1].setX(pt.x() + m_dLength * cos(dRot));
|
||||
apt[1].setY(pt.y() - m_dLength * sin(dRot));
|
||||
// single point differences
|
||||
qreal dPtX;
|
||||
qreal dPtY;
|
||||
bool bInside = true;
|
||||
|
||||
QRectF rectParent = parentItem()->boundingRect();
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
dPtX = 0;
|
||||
dPtY = 0;
|
||||
if (rectParent.contains(apt[i]) == false)
|
||||
{
|
||||
if (apt[i].x() < rectParent.left())
|
||||
{
|
||||
dPtX = rectParent.left() - apt[i].x();
|
||||
}
|
||||
else if (apt[i].x() > rectParent.right())
|
||||
{
|
||||
dPtX = rectParent.right() - apt[i].x();
|
||||
}
|
||||
if (apt[i].y() < rectParent.top())
|
||||
{
|
||||
dPtY = rectParent.top() - apt[i].y();
|
||||
}
|
||||
else if (apt[i].y() > rectParent.bottom())
|
||||
{
|
||||
dPtY = rectParent.bottom() - apt[i].y();
|
||||
}
|
||||
|
||||
if (fabs(dPtX) > fabs(dX))
|
||||
{
|
||||
dX = dPtX;
|
||||
}
|
||||
if (fabs(dPtY) > fabs(dY))
|
||||
{
|
||||
dY = dPtY;
|
||||
}
|
||||
|
||||
bInside = false;
|
||||
}
|
||||
}
|
||||
return bInside;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QLineF VGrainlineItem::Grainline() const
|
||||
{
|
||||
return {m_ptStart, m_ptFinish};
|
||||
return {QLineF(m_ptStart, m_ptFinish), m_eArrowType};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -315,7 +237,7 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME)
|
|||
if ((m_moveType & AllModifications ) == AllModifications)
|
||||
{
|
||||
AllUserModifications(pME->pos());
|
||||
setZValue(ACTIVE_Z);
|
||||
setZValue(activeZ);
|
||||
Update();
|
||||
}
|
||||
else if (m_moveType & IsRotatable)
|
||||
|
@ -333,7 +255,7 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME)
|
|||
m_eMode = mRotate;
|
||||
SetItemOverrideCursor(this, cursorArrowCloseHand, 1, 1);
|
||||
}
|
||||
setZValue(ACTIVE_Z);
|
||||
setZValue(activeZ);
|
||||
Update();
|
||||
}
|
||||
else if (m_moveType & IsResizable)
|
||||
|
@ -346,7 +268,7 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME)
|
|||
{
|
||||
UserMoveAndResize(pME->pos());
|
||||
}
|
||||
setZValue(ACTIVE_Z);
|
||||
setZValue(activeZ);
|
||||
Update();
|
||||
}
|
||||
else if (m_moveType & IsMovable)
|
||||
|
@ -365,7 +287,7 @@ void VGrainlineItem::mousePressEvent(QGraphicsSceneMouseEvent* pME)
|
|||
SetItemOverrideCursor(this, cursorArrowCloseHand, 1, 1);
|
||||
}
|
||||
|
||||
setZValue(ACTIVE_Z);
|
||||
setZValue(activeZ);
|
||||
Update();
|
||||
}
|
||||
else
|
||||
|
@ -388,7 +310,8 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME)
|
|||
if (m_eMode == mMove && m_moveType & IsMovable)
|
||||
{
|
||||
QPointF pt = m_ptStartPos + ptDiff;
|
||||
if (IsContained(pt, m_dRotation, dX, dY) == false)
|
||||
VPieceGrainline grainline(pt, m_dLength, m_dRotation, m_eArrowType);
|
||||
if (not grainline.IsContained(parentItem()->boundingRect(), dX, dY))
|
||||
{
|
||||
pt.setX(pt.x() + dX);
|
||||
pt.setY(pt.y() + dY);
|
||||
|
@ -440,7 +363,8 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME)
|
|||
|
||||
qreal dX;
|
||||
qreal dY;
|
||||
if (IsContained(pos, m_dRotation, dX, dY) == false)
|
||||
VPieceGrainline grainline(pos, m_dLength, m_dRotation, m_eArrowType);
|
||||
if (not grainline.IsContained(parentItem()->boundingRect(), dX, dY))
|
||||
{
|
||||
m_dLength = dPrevLen;
|
||||
}
|
||||
|
@ -469,7 +393,8 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME)
|
|||
|
||||
qreal dAng = GetAngle(mapToParent(pME->pos())) - m_dAngle;
|
||||
QPointF ptNewPos = Rotate(m_ptStartPos, m_ptRotCenter, dAng);
|
||||
if (IsContained(ptNewPos, m_dStartRotation + dAng, dX, dY) == true)
|
||||
VPieceGrainline grainline(ptNewPos, m_dLength, m_dStartRotation + dAng, m_eArrowType);
|
||||
if (grainline.IsContained(parentItem()->boundingRect(), dX, dY))
|
||||
{
|
||||
setPos(ptNewPos);
|
||||
m_dRotation = m_dStartRotation + dAng;
|
||||
|
@ -487,8 +412,12 @@ void VGrainlineItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME)
|
|||
*/
|
||||
void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME)
|
||||
{
|
||||
if (pME->button() == Qt::LeftButton)
|
||||
if (pME->button() != Qt::LeftButton)
|
||||
{
|
||||
VPieceItem::mouseReleaseEvent(pME);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_eMode == mMove || m_eMode == mRotate || m_eMode == mResize) && (flags() & QGraphicsItem::ItemIsMovable))
|
||||
{
|
||||
SetItemOverrideCursor(this, cursorArrowOpenHand, 1, 1);
|
||||
|
@ -500,9 +429,9 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME)
|
|||
|
||||
if (m_eMode == mMove || m_eMode == mResize)
|
||||
{
|
||||
if (bShort == true)
|
||||
if (bShort)
|
||||
{
|
||||
if (m_bReleased == true && m_moveType & IsRotatable)
|
||||
if (m_bReleased && m_moveType & IsRotatable)
|
||||
{
|
||||
m_eMode = mRotate;
|
||||
Update();
|
||||
|
@ -523,7 +452,7 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (bShort == true)
|
||||
if (bShort)
|
||||
{
|
||||
m_eMode = mMove;
|
||||
}
|
||||
|
@ -534,7 +463,6 @@ void VGrainlineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME)
|
|||
Update();
|
||||
}
|
||||
m_bReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -574,22 +502,41 @@ void VGrainlineItem::Update()
|
|||
*/
|
||||
void VGrainlineItem::UpdateRectangle()
|
||||
{
|
||||
QPointF pt1(0, 0);
|
||||
QPointF pt2(pt1.x() + m_dLength * cos(m_dRotation), pt1.y() - m_dLength * sin(m_dRotation));
|
||||
VPieceGrainline grainline(QPointF(), m_dLength, m_dRotation, m_eArrowType);
|
||||
const QLineF mainLine = grainline.GetMainLine();
|
||||
|
||||
m_ptStart = mapToParent(pt1);
|
||||
m_ptFinish = mapToParent(pt2);
|
||||
m_ptStart = mapToParent(mainLine.p1());
|
||||
m_ptFinish = mapToParent(mainLine.p2());
|
||||
m_ptCenter = (m_ptStart + m_ptFinish)/2;
|
||||
|
||||
m_polyBound.clear();
|
||||
m_polyBound << QPointF(pt1.x() + RECT_WIDTH*cos(m_dRotation + M_PI/2),
|
||||
pt1.y() - RECT_WIDTH*sin(m_dRotation + M_PI/2));
|
||||
m_polyBound << QPointF(pt1.x() + RECT_WIDTH*cos(m_dRotation - M_PI/2),
|
||||
pt1.y() - RECT_WIDTH*sin(m_dRotation - M_PI/2));
|
||||
m_polyBound << QPointF(pt2.x() + RECT_WIDTH*cos(m_dRotation - M_PI/2),
|
||||
pt2.y() - RECT_WIDTH*sin(m_dRotation - M_PI/2));
|
||||
m_polyBound << QPointF(pt2.x() + RECT_WIDTH*cos(m_dRotation + M_PI/2),
|
||||
pt2.y() - RECT_WIDTH*sin(m_dRotation + M_PI/2));
|
||||
|
||||
if (grainline.IsFourWays())
|
||||
{
|
||||
m_polyBound << QPointF(mainLine.p1().x() + (m_dLength/2)*cos(m_dRotation + M_PI/2),
|
||||
mainLine.p1().y() - (m_dLength/2)*sin(m_dRotation + M_PI/2));
|
||||
m_polyBound << QPointF(mainLine.p1().x() + (m_dLength/2)*cos(m_dRotation - M_PI/2),
|
||||
mainLine.p1().y() - (m_dLength/2)*sin(m_dRotation - M_PI/2));
|
||||
m_polyBound << QPointF(mainLine.p2().x() + (m_dLength/2)*cos(m_dRotation - M_PI/2),
|
||||
mainLine.p2().y() - (m_dLength/2)*sin(m_dRotation - M_PI/2));
|
||||
m_polyBound << QPointF(mainLine.p2().x() + (m_dLength/2)*cos(m_dRotation + M_PI/2),
|
||||
mainLine.p2().y() - (m_dLength/2)*sin(m_dRotation + M_PI/2));
|
||||
|
||||
const QLineF secondaryLine = grainline.SecondaryLine();
|
||||
m_ptSecondaryStart = mapToParent(secondaryLine.p1());
|
||||
m_ptSecondaryFinish = mapToParent(secondaryLine.p2());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_polyBound << QPointF(mainLine.p1().x() + rectWidth*cos(m_dRotation + M_PI/2),
|
||||
mainLine.p1().y() - rectWidth*sin(m_dRotation + M_PI/2));
|
||||
m_polyBound << QPointF(mainLine.p1().x() + rectWidth*cos(m_dRotation - M_PI/2),
|
||||
mainLine.p1().y() - rectWidth*sin(m_dRotation - M_PI/2));
|
||||
m_polyBound << QPointF(mainLine.p2().x() + rectWidth*cos(m_dRotation - M_PI/2),
|
||||
mainLine.p2().y() - rectWidth*sin(m_dRotation - M_PI/2));
|
||||
m_polyBound << QPointF(mainLine.p2().x() + rectWidth*cos(m_dRotation + M_PI/2),
|
||||
mainLine.p2().y() - rectWidth*sin(m_dRotation + M_PI/2));
|
||||
}
|
||||
m_rectBoundingBox = m_polyBound.boundingRect().adjusted(-2, -2, 2, 2);
|
||||
setTransformOriginPoint(m_rectBoundingBox.center());
|
||||
|
||||
|
@ -598,7 +545,7 @@ void VGrainlineItem::UpdateRectangle()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
double VGrainlineItem::GetAngle(const QPointF &pt) const
|
||||
auto VGrainlineItem::GetAngle(const QPointF &pt) const -> double
|
||||
{
|
||||
return -VPieceItem::GetAngle(pt);
|
||||
}
|
||||
|
@ -612,7 +559,7 @@ double VGrainlineItem::GetAngle(const QPointF &pt) const
|
|||
* @param dAng angle of rotation
|
||||
* @return point, which is a result of rotating pt around ptCenter by angle dAng
|
||||
*/
|
||||
QPointF VGrainlineItem::Rotate(const QPointF& pt, const QPointF& ptCenter, qreal dAng) const
|
||||
auto VGrainlineItem::Rotate(const QPointF& pt, const QPointF& ptCenter, qreal dAng) -> QPointF
|
||||
{
|
||||
QPointF ptRel = pt - ptCenter;
|
||||
QPointF ptFinal;
|
||||
|
@ -630,7 +577,7 @@ QPointF VGrainlineItem::Rotate(const QPointF& pt, const QPointF& ptCenter, qreal
|
|||
* @param dDist distance
|
||||
* @return resulting point
|
||||
*/
|
||||
QPointF VGrainlineItem::GetInsideCorner(int i, qreal dDist) const
|
||||
auto VGrainlineItem::GetInsideCorner(int i, qreal dDist) const -> QPointF
|
||||
{
|
||||
QPointF pt1 = m_polyBound.at((i + 1) % m_polyBound.count()) - m_polyBound.at(i);
|
||||
QPointF pt2 = m_polyBound.at((i + m_polyBound.count() - 1) % m_polyBound.count()) - m_polyBound.at(i);
|
||||
|
@ -642,42 +589,10 @@ QPointF VGrainlineItem::GetInsideCorner(int i, qreal dDist) const
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QLineF VGrainlineItem::MainLine() const
|
||||
auto VGrainlineItem::MainShape() const -> QPainterPath
|
||||
{
|
||||
QPointF pt1;
|
||||
QPointF pt2(pt1.x() + m_dLength * cos(m_dRotation), pt1.y() - m_dLength * sin(m_dRotation));
|
||||
return QLineF(pt1, pt2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPolygonF VGrainlineItem::FirstArrow(const QPointF &pt, qreal dArrLen) const
|
||||
{
|
||||
QPolygonF poly;
|
||||
poly << pt;
|
||||
poly << QPointF(pt.x() + dArrLen*cos(M_PI + m_dRotation + ARROW_ANGLE),
|
||||
pt.y() - dArrLen*sin(M_PI + m_dRotation + ARROW_ANGLE));
|
||||
poly << QPointF(pt.x() + dArrLen*cos(M_PI + m_dRotation - ARROW_ANGLE),
|
||||
pt.y() - dArrLen*sin(M_PI + m_dRotation - ARROW_ANGLE));
|
||||
return poly;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPolygonF VGrainlineItem::SecondArrow(const QPointF &pt, qreal dArrLen) const
|
||||
{
|
||||
QPolygonF poly;
|
||||
poly << pt;
|
||||
poly << QPointF(pt.x() + dArrLen*cos(m_dRotation + ARROW_ANGLE),
|
||||
pt.y() - dArrLen*sin(m_dRotation + ARROW_ANGLE));
|
||||
poly << QPointF(pt.x() + dArrLen*cos(m_dRotation - ARROW_ANGLE),
|
||||
pt.y() - dArrLen*sin(m_dRotation - ARROW_ANGLE));
|
||||
return poly;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QPainterPath VGrainlineItem::MainShape() const
|
||||
{
|
||||
QPainterPath path;
|
||||
const QLineF mainLine = MainLine();
|
||||
VPieceGrainline grainline(QPointF(), m_dLength, m_dRotation, m_eArrowType);
|
||||
const QLineF mainLine = grainline.GetMainLine();
|
||||
QPainterPath linePath;
|
||||
linePath.moveTo(mainLine.p1());
|
||||
linePath.lineTo(mainLine.p2());
|
||||
|
@ -685,43 +600,57 @@ QPainterPath VGrainlineItem::MainShape() const
|
|||
|
||||
QPainterPathStroker stroker;
|
||||
stroker.setWidth(m_penWidth);
|
||||
QPainterPath path;
|
||||
path.addPath((stroker.createStroke(linePath) + linePath).simplified());
|
||||
path.closeSubpath();
|
||||
|
||||
const qreal dArrLen = ARROW_LENGTH;
|
||||
if (m_eArrowType != GrainlineArrowDirection::atRear)
|
||||
if (grainline.IsArrowUpEnabled())
|
||||
{
|
||||
// first arrow
|
||||
QPainterPath polyPath;
|
||||
polyPath.addPolygon(FirstArrow(MainLine().p2(), dArrLen));
|
||||
|
||||
if (m_eArrowType == GrainlineArrowDirection::atFourWay)
|
||||
{ // first double arrow
|
||||
QLineF line = MainLine();
|
||||
line.setLength(line.length() - dArrLen - 0.5);
|
||||
polyPath.addPolygon(FirstArrow(line.p2(), dArrLen));
|
||||
}
|
||||
polyPath.addPolygon(grainline.ArrowUp());
|
||||
|
||||
path.addPath((stroker.createStroke(polyPath) + polyPath).simplified());
|
||||
path.closeSubpath();
|
||||
}
|
||||
|
||||
if (m_eArrowType != GrainlineArrowDirection::atFront)
|
||||
if (grainline.IsArrowDownEnabled())
|
||||
{
|
||||
// second arrow
|
||||
QPainterPath polyPath;
|
||||
polyPath.addPolygon(SecondArrow(MainLine().p1(), dArrLen));
|
||||
|
||||
if (m_eArrowType == GrainlineArrowDirection::atFourWay)
|
||||
{ // second double arrow
|
||||
QLineF line(MainLine().p2(), MainLine().p1());
|
||||
line.setLength(line.length() - dArrLen - 0.5);
|
||||
polyPath.addPolygon(SecondArrow(line.p2(), dArrLen));
|
||||
}
|
||||
polyPath.addPolygon(grainline.ArrowDown());
|
||||
|
||||
path.addPath((stroker.createStroke(polyPath) + polyPath).simplified());
|
||||
path.closeSubpath();
|
||||
}
|
||||
|
||||
if (grainline.IsFourWays())
|
||||
{
|
||||
const QLineF secondaryLine = grainline.SecondaryLine();
|
||||
QPainterPath secondaryLinePath;
|
||||
secondaryLinePath.moveTo(secondaryLine.p1());
|
||||
secondaryLinePath.lineTo(secondaryLine.p2());
|
||||
secondaryLinePath.closeSubpath();
|
||||
|
||||
path.addPath((stroker.createStroke(secondaryLinePath) + secondaryLinePath).simplified());
|
||||
path.closeSubpath();
|
||||
|
||||
if (grainline.IsArrowLeftEnabled())
|
||||
{
|
||||
QPainterPath polyPath;
|
||||
polyPath.addPolygon(grainline.ArrowLeft());
|
||||
|
||||
path.addPath((stroker.createStroke(polyPath) + polyPath).simplified());
|
||||
path.closeSubpath();
|
||||
}
|
||||
|
||||
if (grainline.IsArrowRightEnabled())
|
||||
{
|
||||
QPainterPath polyPath;
|
||||
polyPath.addPolygon(grainline.ArrowRight());
|
||||
|
||||
path.addPath((stroker.createStroke(polyPath) + polyPath).simplified());
|
||||
path.closeSubpath();
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -751,7 +680,7 @@ void VGrainlineItem::UserRotateAndMove()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VGrainlineItem::UserMoveAndResize(const QPointF &pos)
|
||||
{
|
||||
if (m_polyResize.containsPoint(pos, Qt::OddEvenFill) == true)
|
||||
if (m_polyResize.containsPoint(pos, Qt::OddEvenFill))
|
||||
{
|
||||
m_eMode = mResize;
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
|
@ -769,7 +698,7 @@ void VGrainlineItem::UpdatePolyResize()
|
|||
m_polyResize.clear();
|
||||
QPointF ptA = m_polyBound.at(1);
|
||||
m_polyResize << ptA;
|
||||
const double dSize = RESIZE_RECT_SIZE;
|
||||
const double dSize = resizeRectSize;
|
||||
|
||||
ptA.setX(ptA.x() - dSize*cos(m_dRotation - M_PI/2));
|
||||
ptA.setY(ptA.y() + dSize*sin(m_dRotation - M_PI/2));
|
||||
|
|
|
@ -30,68 +30,66 @@
|
|||
#define VGRAINLINEITEM_H
|
||||
|
||||
#include "vpieceitem.h"
|
||||
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
|
||||
#include "../vpatterndb/floatItemData/floatitemdef.h"
|
||||
#include "../vmisc/def.h"
|
||||
|
||||
class VPieceGrainline;
|
||||
|
||||
class VGrainlineItem final : public VPieceItem
|
||||
{
|
||||
Q_OBJECT // NOLINT
|
||||
public:
|
||||
explicit VGrainlineItem(QGraphicsItem* pParent = nullptr);
|
||||
virtual ~VGrainlineItem() = default;
|
||||
~VGrainlineItem() override = default;
|
||||
|
||||
virtual QPainterPath shape() const override;
|
||||
auto shape() const -> QPainterPath override;
|
||||
|
||||
virtual void paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget) override;
|
||||
void paint(QPainter* pP, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget) override;
|
||||
void UpdateGeometry(const QPointF& ptPos, qreal dRotation, qreal dLength, GrainlineArrowDirection eAT);
|
||||
|
||||
virtual int type() const override {return Type;}
|
||||
auto type() const -> int override {return Type;}
|
||||
enum { Type = UserType + static_cast<int>(Vis::GrainlineItem)};
|
||||
|
||||
bool IsContained(const QPointF &pt, qreal dRot, qreal &dX, qreal &dY) const;
|
||||
|
||||
QLineF Grainline() const;
|
||||
auto Grainline() const -> VPieceGrainline;
|
||||
|
||||
signals:
|
||||
void SignalResized(qreal dLength);
|
||||
void SignalRotated(qreal dRot, const QPointF& ptNewPos);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent* pME) override;
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* pME) override;
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) override;
|
||||
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* pME) override;
|
||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* pME) override;
|
||||
virtual void Update() override;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* pME) override;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent* pME) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) override;
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent* pME) override;
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent* pME) override;
|
||||
void Update() override;
|
||||
void UpdateRectangle();
|
||||
|
||||
virtual double GetAngle(const QPointF &pt) const override;
|
||||
auto GetAngle(const QPointF &pt) const -> double override;
|
||||
|
||||
QPointF Rotate(const QPointF& pt, const QPointF& ptCenter, qreal dAng) const;
|
||||
QPointF GetInsideCorner(int i, qreal dDist) const;
|
||||
static auto Rotate(const QPointF& pt, const QPointF& ptCenter, qreal dAng) -> QPointF;
|
||||
auto GetInsideCorner(int i, qreal dDist) const -> QPointF;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(VGrainlineItem) // NOLINT
|
||||
qreal m_dRotation;
|
||||
qreal m_dStartRotation;
|
||||
qreal m_dLength;
|
||||
QPolygonF m_polyBound;
|
||||
QPointF m_ptStartPos;
|
||||
QPointF m_ptStartMove;
|
||||
QPolygonF m_polyResize;
|
||||
qreal m_dStartLength;
|
||||
QPointF m_ptStart;
|
||||
QPointF m_ptFinish;
|
||||
QPointF m_ptCenter;
|
||||
qreal m_dAngle;
|
||||
GrainlineArrowDirection m_eArrowType;
|
||||
qreal m_dRotation{0};
|
||||
qreal m_dStartRotation{0};
|
||||
qreal m_dLength{0};
|
||||
QPolygonF m_polyBound{};
|
||||
QPointF m_ptStartPos{};
|
||||
QPointF m_ptStartMove{};
|
||||
QPolygonF m_polyResize{};
|
||||
qreal m_dStartLength{0};
|
||||
QPointF m_ptStart{};
|
||||
QPointF m_ptFinish{};
|
||||
QPointF m_ptSecondaryStart{};
|
||||
QPointF m_ptSecondaryFinish{};
|
||||
QPointF m_ptCenter{};
|
||||
qreal m_dAngle{0};
|
||||
GrainlineArrowDirection m_eArrowType{GrainlineArrowDirection::twoWaysUpDown};
|
||||
double m_penWidth{1};
|
||||
|
||||
QLineF MainLine() const;
|
||||
QPolygonF FirstArrow(const QPointF &pt, qreal dArrLen) const;
|
||||
QPolygonF SecondArrow(const QPointF &pt, qreal dArrLen) const;
|
||||
|
||||
QPainterPath MainShape() const;
|
||||
auto MainShape() const -> QPainterPath;
|
||||
|
||||
void AllUserModifications(const QPointF &pos);
|
||||
void UserRotateAndMove();
|
||||
|
|
449
src/libs/vwidgets/vpiecegrainline.cpp
Normal file
449
src/libs/vwidgets/vpiecegrainline.cpp
Normal file
|
@ -0,0 +1,449 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vgrainline.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 27 4, 2023
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2023 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#include "vpiecegrainline.h"
|
||||
#include "../vgeometry/vabstractcurve.h"
|
||||
#include "qmath.h"
|
||||
#include "vpiecegrainline_p.h"
|
||||
|
||||
#include <QTransform>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr qreal arrowAngle = M_PI/9;
|
||||
constexpr int arrowLength = 15;
|
||||
}
|
||||
|
||||
// VPieceGrainlinePrivate
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainlinePrivate::MainLine(const QPointF &p1, qreal length, qreal angle) -> QLineF
|
||||
{
|
||||
QPointF pt2(p1.x() + length * cos(angle), p1.y() - length * sin(angle));
|
||||
return {p1, pt2};
|
||||
}
|
||||
|
||||
// VPieceGrainline
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceGrainline::VPieceGrainline()
|
||||
:d(new VPieceGrainlinePrivate)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceGrainline::~VPieceGrainline() //NOLINT(modernize-use-equals-default)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceGrainline::VPieceGrainline(const QLineF &mainLine, GrainlineArrowDirection arrowType)
|
||||
:d (new VPieceGrainlinePrivate(mainLine, arrowType))
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceGrainline::VPieceGrainline(const QPointF &p1, qreal length, qreal angle, GrainlineArrowDirection arrowType)
|
||||
:d (new VPieceGrainlinePrivate(VPieceGrainlinePrivate::MainLine(p1, length, angle), arrowType))
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceGrainline::VPieceGrainline(const VPieceGrainline &other) //NOLINT(modernize-use-equals-default)
|
||||
:d (other.d)
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::operator=(const VPieceGrainline &grainline) -> VPieceGrainline &
|
||||
{
|
||||
if ( &grainline == this )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
d = grainline.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPieceGrainline::VPieceGrainline(VPieceGrainline &&grainline) Q_DECL_NOTHROW
|
||||
: d(std::move(grainline.d))
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::operator=(VPieceGrainline &&grainline) Q_DECL_NOTHROW -> VPieceGrainline &
|
||||
{
|
||||
std::swap(d, grainline.d);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::GetMainLine() const -> QLineF
|
||||
{
|
||||
return d->m_mainLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceGrainline::SetMainLine(const QLineF &mainLine)
|
||||
{
|
||||
d->m_mainLine = mainLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::GetArrowType() const -> GrainlineArrowDirection
|
||||
{
|
||||
return d->m_arrowType;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceGrainline::SetArrowType(GrainlineArrowDirection arrowType)
|
||||
{
|
||||
d->m_arrowType = arrowType;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsEnabled() const -> bool
|
||||
{
|
||||
return d->m_enabled;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPieceGrainline::SetEnabled(bool enabled)
|
||||
{
|
||||
d->m_enabled = enabled;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::SecondaryLine() const -> QLineF
|
||||
{
|
||||
QLineF mainLine = GetMainLine();
|
||||
QLineF secondaryLine = mainLine;
|
||||
QTransform t;
|
||||
t.translate(mainLine.center().x(), mainLine.center().y());
|
||||
t.rotate(90);
|
||||
t.translate(-mainLine.center().x(), -mainLine.center().y());
|
||||
secondaryLine = t.map(secondaryLine);
|
||||
return secondaryLine;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsFourWays() const -> bool
|
||||
{
|
||||
return d->m_arrowType == GrainlineArrowDirection::fourWays ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpLeftRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysDownLeftRight;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsArrowUpEnabled() const -> bool
|
||||
{
|
||||
return d->m_arrowType == GrainlineArrowDirection::oneWayUp ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpDown ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpLeftRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::fourWays;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsArrowDownEnabled() const -> bool
|
||||
{
|
||||
return d->m_arrowType == GrainlineArrowDirection::oneWayDown ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpDown ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysDownLeftRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::fourWays;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsArrowLeftEnabled() const -> bool
|
||||
{
|
||||
return d->m_arrowType == GrainlineArrowDirection::fourWays ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownLeft ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpLeftRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysDownLeftRight;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsArrowRightEnabled() const -> bool
|
||||
{
|
||||
return d->m_arrowType == GrainlineArrowDirection::fourWays ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysUpRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::twoWaysDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpDownRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysUpLeftRight ||
|
||||
d->m_arrowType == GrainlineArrowDirection::threeWaysDownLeftRight;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::ArrowUp() const -> QPolygonF
|
||||
{
|
||||
const QLineF mainLine = GetMainLine();
|
||||
const qreal rotation = M_PI + qDegreesToRadians(mainLine.angle());
|
||||
const QPointF pt = mainLine.p2();
|
||||
|
||||
return {
|
||||
pt,
|
||||
QPointF(pt.x() + arrowLength * cos(rotation + arrowAngle), pt.y() - arrowLength * sin(rotation + arrowAngle)),
|
||||
QPointF(pt.x() + arrowLength * cos(rotation - arrowAngle), pt.y() - arrowLength * sin(rotation - arrowAngle)),
|
||||
pt};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::ArrowDown() const -> QPolygonF
|
||||
{
|
||||
const QLineF mainLine = GetMainLine();
|
||||
const qreal rotation = qDegreesToRadians(mainLine.angle());
|
||||
const QPointF pt = mainLine.p1();
|
||||
|
||||
return {
|
||||
pt,
|
||||
QPointF(pt.x() + arrowLength * cos(rotation + arrowAngle), pt.y() - arrowLength * sin(rotation + arrowAngle)),
|
||||
QPointF(pt.x() + arrowLength * cos(rotation - arrowAngle), pt.y() - arrowLength * sin(rotation - arrowAngle)),
|
||||
pt};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::ArrowLeft() const -> QPolygonF
|
||||
{
|
||||
const qreal rotation = 3 * M_PI / 2 + qDegreesToRadians(GetMainLine().angle());
|
||||
const QPointF pt = SecondaryLine().p1();
|
||||
|
||||
return {
|
||||
pt,
|
||||
QPointF(pt.x() + arrowLength * cos(rotation - arrowAngle), pt.y() - arrowLength * sin(rotation - arrowAngle)),
|
||||
QPointF(pt.x() + arrowLength * cos(rotation + arrowAngle), pt.y() - arrowLength * sin(rotation + arrowAngle)),
|
||||
pt};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::ArrowRight() const -> QPolygonF
|
||||
{
|
||||
const qreal rotation = M_PI / 2 + qDegreesToRadians(GetMainLine().angle());
|
||||
const QPointF pt = SecondaryLine().p2();
|
||||
|
||||
return {
|
||||
pt,
|
||||
QPointF(pt.x() + arrowLength * cos(rotation + arrowAngle), pt.y() - arrowLength * sin(rotation + arrowAngle)),
|
||||
QPointF(pt.x() + arrowLength * cos(rotation - arrowAngle), pt.y() - arrowLength * sin(rotation - arrowAngle)),
|
||||
pt};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::Shape() const -> GrainlineShape
|
||||
{
|
||||
const QLineF mainLine = GetMainLine();
|
||||
if (mainLine.isNull())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// main arrow
|
||||
QVector<QPointF> arrow1;
|
||||
|
||||
if (IsArrowDownEnabled())
|
||||
{
|
||||
arrow1 << ArrowDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
arrow1 << mainLine.p1();
|
||||
}
|
||||
|
||||
if (IsArrowUpEnabled())
|
||||
{
|
||||
arrow1 << ArrowUp();
|
||||
}
|
||||
else
|
||||
{
|
||||
arrow1 << mainLine.p2();
|
||||
}
|
||||
|
||||
if (IsFourWays())
|
||||
{
|
||||
// secondary arrow
|
||||
QVector<QPointF> arrow2;
|
||||
const QLineF secondaryLine = SecondaryLine();
|
||||
|
||||
if (IsArrowLeftEnabled())
|
||||
{
|
||||
arrow2 << ArrowLeft();
|
||||
}
|
||||
else
|
||||
{
|
||||
arrow2 << secondaryLine.p1();
|
||||
}
|
||||
|
||||
if (IsArrowRightEnabled())
|
||||
{
|
||||
arrow2 << ArrowRight();
|
||||
}
|
||||
else
|
||||
{
|
||||
arrow2 << secondaryLine.p2();
|
||||
}
|
||||
|
||||
return {arrow1, arrow2};
|
||||
}
|
||||
|
||||
return {arrow1};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief VPieceGrainline::IsContained checks, if all ends of the grainline, starting at pt, are contained in
|
||||
* parent widget.
|
||||
* @param boundingRect bounding rect of piece
|
||||
* @param dX horizontal translation needed to put the arrow inside parent item
|
||||
* @param dY vertical translation needed to put the arrow inside parent item
|
||||
* @return true, if all ends of the grainline, starting at pt, are contained in the bounding rect of piece and
|
||||
* false otherwise.
|
||||
*/
|
||||
auto VPieceGrainline::IsContained(const QRectF &boundingRect, qreal &dX, qreal &dY) const -> bool
|
||||
{
|
||||
dX = 0;
|
||||
dY = 0;
|
||||
|
||||
const QLineF mainLine = GetMainLine();
|
||||
QVector<QPointF> apt = {mainLine.p1(), mainLine.p2()};
|
||||
if (IsFourWays())
|
||||
{
|
||||
const QLineF secondaryLine = SecondaryLine();
|
||||
apt.append(secondaryLine.p1());
|
||||
apt.append(secondaryLine.p2());
|
||||
}
|
||||
|
||||
// single point differences
|
||||
qreal dPtX;
|
||||
qreal dPtY;
|
||||
bool bInside = true;
|
||||
|
||||
for (auto item : apt)
|
||||
{
|
||||
dPtX = 0;
|
||||
dPtY = 0;
|
||||
if (boundingRect.contains(item))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.x() < boundingRect.left())
|
||||
{
|
||||
dPtX = boundingRect.left() - item.x();
|
||||
}
|
||||
else if (item.x() > boundingRect.right())
|
||||
{
|
||||
dPtX = boundingRect.right() - item.x();
|
||||
}
|
||||
if (item.y() < boundingRect.top())
|
||||
{
|
||||
dPtY = boundingRect.top() - item.y();
|
||||
}
|
||||
else if (item.y() > boundingRect.bottom())
|
||||
{
|
||||
dPtY = boundingRect.bottom() - item.y();
|
||||
}
|
||||
|
||||
if (fabs(dPtX) > fabs(dX))
|
||||
{
|
||||
dX = dPtX;
|
||||
}
|
||||
if (fabs(dPtY) > fabs(dY))
|
||||
{
|
||||
dY = dPtY;
|
||||
}
|
||||
|
||||
bInside = false;
|
||||
}
|
||||
return bInside;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsPositionValid(const QVector<QPointF> &contourPoints) const -> bool
|
||||
{
|
||||
QVector<QLineF> grainLine;
|
||||
QLineF mainLine = GetMainLine();
|
||||
if (IsFourWays ())
|
||||
{
|
||||
grainLine = {mainLine, SecondaryLine()};
|
||||
}
|
||||
|
||||
grainLine = {mainLine};
|
||||
|
||||
for (auto line : grainLine)
|
||||
{
|
||||
QVector<QPointF> points = VAbstractCurve::CurveIntersectLine(contourPoints, line);
|
||||
for (auto &point : points)
|
||||
{
|
||||
if (not VFuzzyComparePoints (line.p1 (), point) && not VFuzzyComparePoints (line.p2 (), point))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPainterPath grainLinePath;
|
||||
for (auto line : grainLine)
|
||||
{
|
||||
grainLinePath.addPath(VGObject::PainterPath(QVector<QPointF>{line.p1(), line.p2()}));
|
||||
}
|
||||
const QPainterPath contourPath = VGObject::PainterPath(contourPoints);
|
||||
return contourPath.contains(grainLinePath);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPieceGrainline::IsShapeValid() const -> bool
|
||||
{
|
||||
GrainlineShape shape = Shape();
|
||||
return std::ranges::all_of(shape, [](const auto& subShape)
|
||||
{
|
||||
return not subShape.isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
// Friend functions
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto operator<<(QDataStream &dataStream, const VPieceGrainline &grainline) -> QDataStream &
|
||||
{
|
||||
dataStream << *grainline.d;
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto operator>>(QDataStream &dataStream, VPieceGrainline &grainline) -> QDataStream &
|
||||
{
|
||||
dataStream >> *grainline.d;
|
||||
return dataStream;
|
||||
}
|
98
src/libs/vwidgets/vpiecegrainline.h
Normal file
98
src/libs/vwidgets/vpiecegrainline.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiecegrainline.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 27 4, 2023
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2023 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef VPIECEGRAINLINE_H
|
||||
#define VPIECEGRAINLINE_H
|
||||
|
||||
#include <QSharedDataPointer>
|
||||
#include <QMetaType>
|
||||
#include "../vpatterndb/floatItemData/floatitemdef.h"
|
||||
|
||||
class QPointF;
|
||||
class VPieceGrainlinePrivate;
|
||||
class QLineF;
|
||||
class QPolygonF;
|
||||
class QRectF;
|
||||
|
||||
using GrainlineShape = QVector<QVector<QPointF>>;
|
||||
|
||||
class VPieceGrainline
|
||||
{
|
||||
public:
|
||||
VPieceGrainline();
|
||||
VPieceGrainline(const QLineF &mainLine, GrainlineArrowDirection arrowType);
|
||||
VPieceGrainline(const QPointF &p1, qreal length, qreal angle, GrainlineArrowDirection arrowType);
|
||||
VPieceGrainline(const VPieceGrainline &other);
|
||||
|
||||
~VPieceGrainline();
|
||||
|
||||
auto operator=(const VPieceGrainline &grainline) -> VPieceGrainline &;
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
VPieceGrainline(VPieceGrainline &&grainline) Q_DECL_NOTHROW;
|
||||
auto operator=(VPieceGrainline &&grainline) Q_DECL_NOTHROW -> VPieceGrainline &;
|
||||
#endif
|
||||
|
||||
auto GetMainLine() const -> QLineF;
|
||||
void SetMainLine(const QLineF &mainLine);
|
||||
|
||||
auto GetArrowType() const -> GrainlineArrowDirection;
|
||||
void SetArrowType(GrainlineArrowDirection arrowType);
|
||||
|
||||
auto IsEnabled() const -> bool;
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
auto SecondaryLine() const -> QLineF;
|
||||
|
||||
auto IsFourWays() const -> bool;
|
||||
|
||||
auto IsArrowUpEnabled() const -> bool;
|
||||
auto IsArrowDownEnabled() const -> bool;
|
||||
auto IsArrowLeftEnabled() const -> bool;
|
||||
auto IsArrowRightEnabled() const -> bool;
|
||||
|
||||
auto ArrowUp() const -> QPolygonF;
|
||||
auto ArrowDown() const -> QPolygonF;
|
||||
auto ArrowLeft() const -> QPolygonF;
|
||||
auto ArrowRight() const -> QPolygonF;
|
||||
|
||||
auto Shape() const -> GrainlineShape;
|
||||
|
||||
auto IsContained(const QRectF &boundingRect, qreal &dX, qreal &dY) const -> bool;
|
||||
auto IsPositionValid(const QVector<QPointF> &contourPoints) const -> bool;
|
||||
|
||||
auto IsShapeValid() const -> bool;
|
||||
|
||||
friend auto operator<< (QDataStream& dataStream, const VPieceGrainline& grainline) -> QDataStream&;
|
||||
friend auto operator>> (QDataStream& dataStream, VPieceGrainline& grainline) -> QDataStream&;
|
||||
private:
|
||||
QSharedDataPointer<VPieceGrainlinePrivate> d;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(VPieceGrainline)
|
||||
Q_DECLARE_TYPEINFO(VPieceGrainline, Q_MOVABLE_TYPE); // NOLINT
|
||||
|
||||
#endif // VPIECEGRAINLINE_H
|
125
src/libs/vwidgets/vpiecegrainline_p.h
Normal file
125
src/libs/vwidgets/vpiecegrainline_p.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vpiecegrainline_p.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 27 4, 2023
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2023 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> 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 <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef VPIECEGRAINLINE_P_H
|
||||
#define VPIECEGRAINLINE_P_H
|
||||
|
||||
#include <QLineF>
|
||||
#include <QSharedData>
|
||||
#include "../vmisc/defglobal.h"
|
||||
#include "../ifc/exception/vexception.h"
|
||||
#include "vpatterndb/floatItemData/floatitemdef.h"
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_GCC("-Weffc++")
|
||||
QT_WARNING_DISABLE_GCC("-Wnon-virtual-dtor")
|
||||
|
||||
class VPieceGrainlinePrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
VPieceGrainlinePrivate(){} // NOLINT(modernize-use-equals-default)
|
||||
VPieceGrainlinePrivate(const QLineF &mainLine, GrainlineArrowDirection arrowType)
|
||||
: m_mainLine(mainLine),
|
||||
m_arrowType(arrowType),
|
||||
m_enabled(true)
|
||||
{}
|
||||
|
||||
VPieceGrainlinePrivate(const VPieceGrainlinePrivate &data) = default;
|
||||
~VPieceGrainlinePrivate() = default;
|
||||
|
||||
static auto MainLine(const QPointF &p1, qreal length, qreal angle) -> QLineF;
|
||||
|
||||
friend auto operator<<(QDataStream& dataStream, const VPieceGrainlinePrivate& data) -> QDataStream&;
|
||||
friend auto operator>>(QDataStream& dataStream, VPieceGrainlinePrivate& data) -> QDataStream&;
|
||||
|
||||
QLineF m_mainLine{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
GrainlineArrowDirection m_arrowType{GrainlineArrowDirection::oneWayUp}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
bool m_enabled{false}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
|
||||
private:
|
||||
Q_DISABLE_ASSIGN_MOVE(VPieceGrainlinePrivate) // NOLINT
|
||||
|
||||
static constexpr quint32 streamHeader{0x5C5D5B3B}; // CRC-32Q string "VGrainlineData"
|
||||
static constexpr quint16 classVersion{1};
|
||||
};
|
||||
|
||||
QT_WARNING_POP
|
||||
|
||||
// See https://stackoverflow.com/a/46719572/3045403
|
||||
#if __cplusplus < 201703L // C++17
|
||||
constexpr quint32 VPieceGrainlinePrivate::streamHeader; // NOLINT(readability-redundant-declaration)
|
||||
constexpr quint16 VPieceGrainlinePrivate::classVersion; // NOLINT(readability-redundant-declaration)
|
||||
#endif
|
||||
|
||||
// Friend functions
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto operator<<(QDataStream &dataStream, const VPieceGrainlinePrivate &data) -> QDataStream &
|
||||
{
|
||||
dataStream << VPieceGrainlinePrivate::streamHeader << VPieceGrainlinePrivate::classVersion;
|
||||
|
||||
// Added in classVersion = 1
|
||||
dataStream << data.m_enabled;
|
||||
dataStream << data.m_arrowType;
|
||||
dataStream << data.m_mainLine;
|
||||
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto operator>>(QDataStream &dataStream, VPieceGrainlinePrivate &data) -> QDataStream &
|
||||
{
|
||||
quint32 actualStreamHeader = 0;
|
||||
dataStream >> actualStreamHeader;
|
||||
|
||||
if (actualStreamHeader != VPieceGrainlinePrivate::streamHeader)
|
||||
{
|
||||
QString message = QCoreApplication::tr("VPieceGrainlinePrivate prefix mismatch error: actualStreamHeader = "
|
||||
"0x%1 and streamHeader = 0x%2")
|
||||
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
|
||||
.arg(VPieceGrainlinePrivate::streamHeader, 8, 0x10, QChar('0'));
|
||||
throw VException(message);
|
||||
}
|
||||
|
||||
quint16 actualClassVersion = 0;
|
||||
dataStream >> actualClassVersion;
|
||||
|
||||
if (actualClassVersion > VPieceGrainlinePrivate::classVersion)
|
||||
{
|
||||
QString message = QCoreApplication::tr("VPieceGrainlinePrivate compatibility error: actualClassVersion = %1 "
|
||||
"and classVersion = %2")
|
||||
.arg(actualClassVersion).arg(VPieceGrainlinePrivate::classVersion);
|
||||
throw VException(message);
|
||||
}
|
||||
|
||||
dataStream >> data.m_enabled;
|
||||
dataStream >> data.m_arrowType;
|
||||
dataStream >> data.m_mainLine;
|
||||
|
||||
return dataStream;
|
||||
}
|
||||
|
||||
#endif // VPIECEGRAINLINE_P_H
|
|
@ -28,7 +28,8 @@ SOURCES += \
|
|||
$$PWD/scalesceneitems.cpp \
|
||||
$$PWD/vlineedit.cpp \
|
||||
$$PWD/vplaintextedit.cpp \
|
||||
$$PWD/vhighlighter.cpp
|
||||
$$PWD/vhighlighter.cpp \
|
||||
$$PWD/vpiecegrainline.cpp
|
||||
|
||||
*msvc*:SOURCES += $$PWD/stable.cpp
|
||||
|
||||
|
@ -60,4 +61,6 @@ HEADERS += \
|
|||
$$PWD/scalesceneitems.h \
|
||||
$$PWD/vlineedit.h \
|
||||
$$PWD/vplaintextedit.h \
|
||||
$$PWD/vhighlighter.h
|
||||
$$PWD/vhighlighter.h \
|
||||
$$PWD/vpiecegrainline.h \
|
||||
$$PWD/vpiecegrainline_p.h
|
||||
|
|
|
@ -4,6 +4,7 @@ VLib {
|
|||
Depends { name: "Qt"; submodules: ["core", "widgets"] }
|
||||
Depends { name: "VMiscLib" }
|
||||
Depends { name: "VPropertyExplorerLib" }
|
||||
Depends { name: "VPatternDBLib" }
|
||||
|
||||
Depends {
|
||||
name: "Qt.openglwidgets";
|
||||
|
@ -65,7 +66,10 @@ VLib {
|
|||
"scalesceneitems.h",
|
||||
"vlineedit.h",
|
||||
"vplaintextedit.h",
|
||||
"vhighlighter.h"
|
||||
"vhighlighter.h",
|
||||
"vpiecegrainline.h",
|
||||
"vpiecegrainline.cpp",
|
||||
"vpiecegrainline_p.h"
|
||||
]
|
||||
|
||||
Export {
|
||||
|
|
Loading…
Reference in New Issue
Block a user