Follow grainline.

This commit is contained in:
Roman Telezhynskyi 2021-08-26 19:04:24 +03:00
parent acfbc5478e
commit 877fe380e3
22 changed files with 310 additions and 57 deletions

View file

@ -55,6 +55,21 @@ struct VPTransformationOrigon
{
QPointF origin{};
bool custom{false};
bool operator==(const VPTransformationOrigon &origin) const;
bool operator!=(const VPTransformationOrigon &origin) const;
};
//---------------------------------------------------------------------------------------------------------------------
inline bool VPTransformationOrigon::operator==(const VPTransformationOrigon &origin) const
{
return this->origin == origin.origin && custom == origin.custom;
}
//---------------------------------------------------------------------------------------------------------------------
inline bool VPTransformationOrigon::operator!=(const VPTransformationOrigon &origin) const
{
return !VPTransformationOrigon::operator==(origin);
}
#endif // LAYOUTDEF_H

View file

@ -108,6 +108,23 @@ auto VPLayout::GetPieces() const -> QList<VPPiecePtr>
return m_pieces.values();
}
//---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetPlacedPieces() const -> QList<VPPiecePtr>
{
QList<VPPiecePtr> pieces;
pieces.reserve(m_pieces.size());
for (const auto& piece : m_pieces)
{
if (not piece->isNull() && piece->Sheet() != VPSheetPtr() && piece->Sheet() != m_trashSheet)
{
pieces.append(piece);
}
}
return pieces;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPLayout::GetUnplacedPieces() const -> QList<VPPiecePtr>
{

View file

@ -49,6 +49,7 @@ public:
static void AddPiece(const VPLayoutPtr &layout, const VPPiecePtr &piece);
auto GetPieces() const -> QList<VPPiecePtr>;
auto GetPlacedPieces() const -> QList<VPPiecePtr>;
auto GetUnplacedPieces() const -> QList<VPPiecePtr>;
auto GetTrashedPieces() const -> QList<VPPiecePtr>;

View file

@ -76,7 +76,7 @@ auto VPPiece::GetPosition() -> QPointF
}
//---------------------------------------------------------------------------------------------------------------------
void VPPiece::RotateToGrainline()
void VPPiece::RotateToGrainline(const VPTransformationOrigon &origin)
{
VPSheetPtr sheet = Sheet();
if (not IsGrainlineEnabled() || sheet.isNull())
@ -105,7 +105,8 @@ void VPPiece::RotateToGrainline()
atFront.setAngle(90);
}
return grainline.angleTo(atFront);
qreal angleTo = grainline.angleTo(atFront);
return angleTo;
};
auto DegreesAtRear = [grainline, canonical, grainlineType]()
@ -113,7 +114,8 @@ void VPPiece::RotateToGrainline()
QLineF atRear = canonical;
atRear.setAngle(grainlineType == GrainlineType::Vertical ? 270 : 180);
return grainline.angleTo(atRear);
qreal angleTo = grainline.angleTo(atRear);
return angleTo;
};
GrainlineArrowDirection type = GrainlineArrowType();
@ -129,10 +131,25 @@ void VPPiece::RotateToGrainline()
}
else
{
degrees = qMin(DegreesAtFront(), DegreesAtRear());
const qreal atFront = DegreesAtFront();
if (atFront <= 90 || atFront >= 270)
{
degrees = atFront;
}
else
{
degrees = DegreesAtRear();
}
}
Rotate(MappedDetailBoundingRect().center(), degrees);
if (origin.custom)
{
Rotate(MappedDetailBoundingRect().center(), degrees);
}
else
{
Rotate(origin.origin, degrees);
}
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -64,7 +64,7 @@ public:
/**
* @brief RotateToGrainline rotates the piece to follow the grainline
*/
void RotateToGrainline();
void RotateToGrainline(const VPTransformationOrigon &origin);
/**
* @brief SetSelected Sets wether the piece is selected

View file

@ -71,17 +71,20 @@ enum class HandleCorner : int
BottomLeft = 4
};
auto TransformationOrigin(const VPLayoutPtr &layout, const QRectF &boundingRect) -> QPointF
auto TransformationOrigin(const VPLayoutPtr &layout, const QRectF &boundingRect) -> VPTransformationOrigon
{
SCASSERT(layout != nullptr)
VPSheetPtr sheet = layout->GetFocusedSheet();
if (not sheet.isNull())
{
VPTransformationOrigon origin = sheet->TransformationOrigin();
return origin.origin;
return sheet->TransformationOrigin();
}
return boundingRect.center();
VPTransformationOrigon origin;
origin.origin = boundingRect.center();
origin.custom = false;
return origin;
}
} // namespace
@ -233,8 +236,8 @@ auto VPGraphicsTransformationOrigin::RotationCenter(QPainter *painter) const ->
const qreal scale = SceneScale(scene());
qreal radius = centerRadius1/scale;
QPointF transformationOrigin = TransformationOrigin(m_layout, QRectF());
QRectF rect(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
VPTransformationOrigon transformationOrigin = TransformationOrigin(m_layout, QRectF());
QRectF rect(transformationOrigin.origin.x()-radius, transformationOrigin.origin.y()-radius, radius*2., radius*2.);
QPainterPath center1;
center1.addEllipse(rect);
@ -249,7 +252,7 @@ auto VPGraphicsTransformationOrigin::RotationCenter(QPainter *painter) const ->
path.addPath(center1);
radius = centerRadius2/scale;
rect = QRectF(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
rect = QRectF(transformationOrigin.origin.x()-radius, transformationOrigin.origin.y()-radius, radius*2., radius*2.);
QPainterPath center2;
center2.addEllipse(rect);
@ -271,8 +274,8 @@ auto VPGraphicsTransformationOrigin::Center1() const -> QPainterPath
{
const qreal scale = SceneScale(scene());
qreal radius = centerRadius1/scale;
QPointF transformationOrigin = TransformationOrigin(m_layout, QRectF());
QRectF rect(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
VPTransformationOrigon transformationOrigin = TransformationOrigin(m_layout, QRectF());
QRectF rect(transformationOrigin.origin.x()-radius, transformationOrigin.origin.y()-radius, radius*2., radius*2.);
QPainterPath center1;
center1.addEllipse(rect);
@ -285,8 +288,9 @@ auto VPGraphicsTransformationOrigin::Center2() const -> QPainterPath
{
const qreal scale = SceneScale(scene());
qreal radius = centerRadius2/scale;
QPointF transformationOrigin = TransformationOrigin(m_layout, QRectF());
QRectF rect = QRectF(transformationOrigin.x()-radius, transformationOrigin.y()-radius, radius*2., radius*2.);
VPTransformationOrigon transformationOrigin = TransformationOrigin(m_layout, QRectF());
QRectF rect = QRectF(transformationOrigin.origin.x()-radius, transformationOrigin.origin.y()-radius, radius*2.,
radius*2.);
QPainterPath center2;
center2.addEllipse(rect);
@ -389,6 +393,7 @@ void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
if(event->button() == Qt::LeftButton)
{
m_rotationStartPoint = event->scenePos();
m_rotationSum = 0;
m_controlsVisible = false;
m_handleCorner = HandleCorner(event->scenePos());
m_ignorePieceTransformation = true;
@ -470,13 +475,18 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QPointF rotationNewPoint = event->scenePos();
// get the angle from the center to the initial click point
QPointF rotationOrigin = TransformationOrigin(m_layout, m_pieceRect);
QLineF initPosition(rotationOrigin, m_rotationStartPoint);
QLineF initRotationPosition(rotationOrigin, rotationNewPoint);
VPTransformationOrigon rotationOrigin = TransformationOrigin(m_layout, m_pieceRect);
QLineF initPosition(rotationOrigin.origin, m_rotationStartPoint);
QLineF initRotationPosition(rotationOrigin.origin, rotationNewPoint);
qreal angle = initPosition.angleTo(initRotationPosition);
qreal rotateOn = initPosition.angleTo(initRotationPosition);
if (not qFuzzyIsNull(angle))
if (rotateOn > 180)
{
rotateOn = rotateOn - 360.;
}
if (not qFuzzyIsNull(rotateOn))
{
auto PreparePieces = [this]()
{
@ -499,14 +509,32 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
VPLayoutPtr layout = m_layout.toStrongRef();
if (not layout.isNull())
{
if (layout->LayoutSettings().GetFollowGrainline() && not rotationOrigin.custom)
{
if (m_rotationSum > 90 || m_rotationSum < -90)
{
m_rotationSum = rotateOn;
}
else
{
m_rotationSum += rotateOn;
}
}
else
{
m_rotationSum = rotateOn;
}
if (pieces.size() == 1)
{
auto *command = new VPUndoPieceRotate(pieces.first(), rotationOrigin, angle, allowChangeMerge);
auto *command = new VPUndoPieceRotate(pieces.first(), rotationOrigin, rotateOn, m_rotationSum,
allowChangeMerge);
layout->UndoStack()->push(command);
}
else if (pieces.size() > 1)
{
auto *command = new VPUndoPiecesRotate(pieces, rotationOrigin, angle, allowChangeMerge);
auto *command = new VPUndoPiecesRotate(pieces, rotationOrigin, rotateOn, m_rotationSum,
allowChangeMerge);
layout->UndoStack()->push(command);
}
}
@ -514,8 +542,8 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (m_originSaved && m_savedOrigin.custom)
{
QLineF line(rotationOrigin, m_savedOrigin.origin);
line.setAngle(line.angle()+angle);
QLineF line(rotationOrigin.origin, m_savedOrigin.origin);
line.setAngle(line.angle()+rotateOn);
m_savedOrigin.origin = line.p2();
}

View file

@ -108,6 +108,7 @@ private:
Q_DISABLE_COPY(VPGraphicsPieceControls)
QRectF m_pieceRect{};
QPointF m_rotationStartPoint{};
qreal m_rotationSum{0};
bool m_controlsVisible{true};
VPLayoutWeakPtr m_layout{};
int m_handleCorner{0};

View file

@ -371,6 +371,7 @@ void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event)
m_rotationControls->SetIgnorePieceTransformation(false);
m_rotationControls->on_UpdateControls();
m_rotationControls->on_HideHandles(false);
m_rotationSum = 0;
}
}
VMainGraphicsView::keyReleaseEvent(event);
@ -558,16 +559,32 @@ void VPMainGraphicsView::RotatePiecesByAngle(qreal angle)
return pieces;
};
if (layout->LayoutSettings().GetFollowGrainline() && not origin.custom)
{
if (m_rotationSum > 90 || m_rotationSum < -90)
{
m_rotationSum = angle;
}
else
{
m_rotationSum += angle;
}
}
else
{
m_rotationSum = angle;
}
QList<VPPiecePtr> pieces = PreparePieces();
if (pieces.size() == 1)
{
auto *command = new VPUndoPieceRotate(pieces.first(), origin.origin, angle, m_allowChangeMerge);
auto *command = new VPUndoPieceRotate(pieces.first(), origin, angle, m_rotationSum, m_allowChangeMerge);
layout->UndoStack()->push(command);
}
else if (pieces.size() > 1)
{
auto *command = new VPUndoPiecesRotate(pieces, origin.origin, angle, m_allowChangeMerge);
auto *command = new VPUndoPiecesRotate(pieces, origin, angle, m_rotationSum, m_allowChangeMerge);
layout->UndoStack()->push(command);
}

View file

@ -124,6 +124,8 @@ private:
bool m_showGridTmp{false};
bool m_allowChangeMerge{false};
qreal m_rotationSum{0};
void ConnectPiece(VPGraphicsPiece *piece);
void RotatePiecesByAngle(qreal angle);

View file

@ -41,6 +41,12 @@ VPUndoMovePieceOnSheet::VPUndoMovePieceOnSheet(const VPSheetPtr &sheet, const VP
m_oldSheet = piece->Sheet();
VPLayoutPtr layout = piece->Layout();
if (not layout.isNull())
{
m_followGrainline = layout->LayoutSettings().GetFollowGrainline();
}
setText(tr("move piece on sheet"));
}
@ -105,6 +111,14 @@ void VPUndoMovePieceOnSheet::redo()
{
piece->SetSheet(sourceSheet);
if (m_followGrainline)
{
VPTransformationOrigon origin;
origin.custom = true;
piece->RotateToGrainline(origin);
}
if (not layout.isNull())
{
emit layout->PieceSheetChanged(piece);

View file

@ -48,6 +48,7 @@ private:
VPSheetWeakPtr m_oldSheet{};
VPSheetWeakPtr m_sheet;
VPPieceWeakPtr m_piece;
bool m_followGrainline{false};
};
#endif // VPUNDOMOVEPIECEONSHEET_H

View file

@ -29,18 +29,35 @@
#include "../layout/vppiece.h"
#include "../layout/vplayout.h"
namespace
{
auto RoundAngle(qreal angle) -> qreal
{
QLineF l(10, 10, 100, 10);
l.setAngle(angle);
return l.angle();
}
}
//---------------------------------------------------------------------------------------------------------------------
VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge,
QUndoCommand *parent)
VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const VPTransformationOrigon &origin, qreal angle,
qreal angleSum, bool allowMerge, QUndoCommand *parent)
: VPUndoCommand(allowMerge, parent),
m_piece(piece),
m_origin(origin),
m_angle(angle)
m_angle(angle),
m_angleSum(angleSum)
{
SCASSERT(not piece.isNull())
m_oldTransform = piece->GetMatrix();
VPLayoutPtr layout = piece->Layout();
if (not layout.isNull())
{
m_followGrainline = layout->LayoutSettings().GetFollowGrainline();
}
setText(tr("rotate piece"));
}
@ -88,8 +105,33 @@ void VPUndoPieceRotate::redo()
layout->SetFocusedSheet(piece->Sheet());
}
piece->Rotate(m_origin, m_angle);
if (m_firstCall)
{
if (m_followGrainline && piece->IsGrainlineEnabled())
{
piece->Rotate(m_origin.origin, m_angleSum);
}
else
{
piece->Rotate(m_origin.origin, m_angle);
}
}
else
{
piece->Rotate(m_origin.origin, m_angle);
}
if (m_followGrainline)
{
piece->RotateToGrainline(m_origin);
}
emit layout->PieceTransformationChanged(piece);
if (m_firstCall)
{
m_firstCall = false;
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -105,12 +147,14 @@ auto VPUndoPieceRotate::mergeWith(const QUndoCommand *command) -> bool
VPPiecePtr piece = Piece();
if (not moveCommand->AllowMerge() || (moveCommand->Piece().isNull() || piece.isNull()) ||
moveCommand->Piece() != piece || moveCommand->Origin() != m_origin)
moveCommand->Piece() != piece || moveCommand->Origin() != m_origin ||
moveCommand->FollowGrainline() != m_followGrainline)
{
return false;
}
m_angle += moveCommand->Angle();
m_angle = RoundAngle(m_angle);
return true;
}
@ -122,11 +166,12 @@ auto VPUndoPieceRotate::id() const -> int
// rotate pieces
//---------------------------------------------------------------------------------------------------------------------
VPUndoPiecesRotate::VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const QPointF &origin, qreal angle,
bool allowMerge, QUndoCommand *parent)
VPUndoPiecesRotate::VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const VPTransformationOrigon &origin,
qreal angle, qreal angleSum, bool allowMerge, QUndoCommand *parent)
: VPUndoCommand(allowMerge, parent),
m_origin(origin),
m_angle(angle)
m_angle(angle),
m_angleSum(angleSum)
{
setText(QObject::tr("rotate pieces"));
@ -138,6 +183,12 @@ VPUndoPiecesRotate::VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const QP
m_oldTransforms.insert(piece->GetUniqueID(), piece->GetMatrix());
}
}
VPLayoutPtr layout = Layout();
if (not layout.isNull())
{
m_followGrainline = layout->LayoutSettings().GetFollowGrainline();
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -199,10 +250,35 @@ void VPUndoPiecesRotate::redo()
VPPiecePtr p = piece.toStrongRef();
if (not p.isNull())
{
p->Rotate(m_origin, m_angle);
if (m_firstCall)
{
if (m_followGrainline && p->IsGrainlineEnabled())
{
p->Rotate(m_origin.origin, m_angleSum);
}
else
{
p->Rotate(m_origin.origin, m_angle);
}
}
else
{
p->Rotate(m_origin.origin, m_angle);
}
if (m_followGrainline)
{
p->RotateToGrainline(m_origin);
}
emit layout->PieceTransformationChanged(p);
}
}
if (m_firstCall)
{
m_firstCall = false;
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -216,12 +292,14 @@ auto VPUndoPiecesRotate::mergeWith(const QUndoCommand *command) -> bool
const auto *moveCommand = dynamic_cast<const VPUndoPiecesRotate *>(command);
SCASSERT(moveCommand != nullptr)
if (not moveCommand->AllowMerge() || moveCommand->PieceIds() != PieceIds() || moveCommand->Origin() != m_origin)
if (not moveCommand->AllowMerge() || moveCommand->PieceIds() != PieceIds() || moveCommand->Origin() != m_origin ||
moveCommand->FollowGrainline() != m_followGrainline)
{
return false;
}
m_angle += moveCommand->Angle();
m_angle = RoundAngle(m_angle);
return true;
}

View file

@ -38,8 +38,8 @@ class VPUndoPieceRotate : public VPUndoCommand
{
Q_OBJECT
public:
VPUndoPieceRotate(const VPPiecePtr &piece, const QPointF &origin, qreal angle, bool allowMerge = false,
QUndoCommand *parent = nullptr);
VPUndoPieceRotate(const VPPiecePtr &piece, const VPTransformationOrigon &origin, qreal angle, qreal angleSum,
bool allowMerge = false, QUndoCommand *parent = nullptr);
virtual ~VPUndoPieceRotate()=default;
@ -50,16 +50,21 @@ public:
virtual auto id() const -> int override ;
auto Piece() const -> VPPiecePtr;
auto Origin() const -> QPointF;
auto Origin() const -> VPTransformationOrigon;
auto Angle() const -> qreal;
bool FollowGrainline() const;
private:
Q_DISABLE_COPY(VPUndoPieceRotate)
bool m_firstCall{true};
VPPieceWeakPtr m_piece;
QTransform m_oldTransform{};
QPointF m_origin;
VPTransformationOrigon m_origin;
qreal m_angle;
qreal m_angleSum;
bool m_followGrainline{false};
};
//---------------------------------------------------------------------------------------------------------------------
@ -69,7 +74,7 @@ inline auto VPUndoPieceRotate::Piece() const -> VPPiecePtr
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::Origin() const -> QPointF
inline auto VPUndoPieceRotate::Origin() const -> VPTransformationOrigon
{
return m_origin;
}
@ -80,13 +85,19 @@ inline auto VPUndoPieceRotate::Angle() const -> qreal
return m_angle;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPieceRotate::FollowGrainline() const -> bool
{
return m_followGrainline;
}
// Rotate pieces
class VPUndoPiecesRotate : public VPUndoCommand
{
Q_OBJECT
public:
explicit VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const QPointF &origin, qreal angle,
bool allowMerge = false, QUndoCommand *parent = nullptr);
explicit VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const VPTransformationOrigon &origin, qreal angle,
qreal angleSum, bool allowMerge = false, QUndoCommand *parent = nullptr);
virtual ~VPUndoPiecesRotate()=default;
virtual void undo() override;
@ -96,23 +107,27 @@ public:
virtual auto id() const -> int override ;
auto PieceIds() const -> QSet<QString>;
auto Origin() const -> QPointF;
auto Origin() const -> VPTransformationOrigon;
auto Angle() const -> qreal;
auto FollowGrainline() const -> bool;
private:
Q_DISABLE_COPY(VPUndoPiecesRotate)
bool m_firstCall{true};
QVector<VPPieceWeakPtr> m_pieces{};
QMap<QString, QTransform> m_oldTransforms{};
QPointF m_origin;
VPTransformationOrigon m_origin;
qreal m_angle;
qreal m_angleSum;
bool m_followGrainline{false};
auto Layout() const -> VPLayoutPtr;
auto Sheet() const -> VPSheetPtr;
};
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesRotate::Origin() const -> QPointF
inline auto VPUndoPiecesRotate::Origin() const -> VPTransformationOrigon
{
return m_origin;
}
@ -123,4 +138,10 @@ inline auto VPUndoPiecesRotate::Angle() const -> qreal
return m_angle;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VPUndoPiecesRotate::FollowGrainline() const -> bool
{
return m_followGrainline;
}
#endif // VPUNDOPIECEROTATE_H

View file

@ -862,8 +862,13 @@ void VPMainWindow::InitPropertyTabLayout()
if (not m_layout.isNull())
{
m_layout->LayoutSettings().SetFollowGrainline(checked);
if (checked)
{
RotatePiecesToGrainline();
}
LayoutWasSaved(false);
// TODO update the QGraphicView
}
});
@ -1742,6 +1747,11 @@ void VPMainWindow::SheetPaperSizeChanged()
ui->toolButtonSheetLandscapeOrientation->blockSignals(true);
ui->toolButtonSheetLandscapeOrientation->setChecked(not portrait);
ui->toolButtonSheetLandscapeOrientation->blockSignals(false);
if (not m_layout.isNull() && m_layout->LayoutSettings().GetFollowGrainline())
{
RotatePiecesToGrainline();
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -1862,6 +1872,29 @@ void VPMainWindow::CorrectMaxMargins()
CorrectTileMaxMargins();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::RotatePiecesToGrainline()
{
QList<VPSheetPtr> sheets = m_layout->GetSheets();
for(const auto& sheet : sheets)
{
if (not sheet.isNull())
{
QList<VPPiecePtr> pieces = sheet->GetPieces();
for(const auto& piece : pieces)
{
if (not piece.isNull() && piece->IsGrainlineEnabled())
{
VPTransformationOrigon origin;
origin.custom = true;
piece->RotateToGrainline(origin);
emit m_layout->PieceTransformationChanged(piece);
}
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionNew_triggered()
{
@ -2513,7 +2546,12 @@ void VPMainWindow::on_ApplyPieceTransformation()
if (not piece.isNull())
{
const QRectF rect = piece->MappedDetailBoundingRect();
auto *command = new VPUndoPieceRotate(piece, rect.center(), angle);
VPTransformationOrigon origin;
origin.origin = rect.center();
origin.custom = true;
auto *command = new VPUndoPieceRotate(piece, origin, angle, angle);
m_layout->UndoStack()->push(command);
}
}
@ -2528,7 +2566,7 @@ void VPMainWindow::on_ApplyPieceTransformation()
}
VPTransformationOrigon origin = sheet->TransformationOrigin();
auto *command = new VPUndoPiecesRotate(selectedPieces, origin.origin, angle);
auto *command = new VPUndoPiecesRotate(selectedPieces, origin, angle, angle);
m_layout->UndoStack()->push(command);
}
}

View file

@ -454,6 +454,8 @@ private:
void CorrectTileMaxMargins();
void CorrectSheetMaxMargins();
void CorrectMaxMargins();
void RotatePiecesToGrainline();
};
#endif // VPMAINWINDOW_H

View file

@ -189,7 +189,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<property name="iconSize">
<size>

View file

@ -298,7 +298,7 @@ void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout)
layout->LayoutSettings().SetWarningPiecesOutOfBound(ReadAttributeBool(attribs, ML::AttrWarningOutOfBound, trueStr));
layout->LayoutSettings().SetStickyEdges(ReadAttributeBool(attribs, ML::AttrStickyEdges, trueStr));
layout->LayoutSettings().SetPiecesGap(ReadAttributeDouble(attribs, ML::AttrPiecesGap, QChar('0')));
// layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainLine, trueStr));
layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr));
readElementText();
}

View file

@ -176,7 +176,7 @@ void VPLayoutFileWriter::WriteProperties(const VPLayoutPtr &layout)
SetAttribute(ML::AttrWarningOutOfBound, layout->LayoutSettings().GetWarningPiecesOutOfBound());
SetAttribute(ML::AttrStickyEdges, layout->LayoutSettings().GetStickyEdges());
SetAttribute(ML::AttrPiecesGap, layout->LayoutSettings().GetPiecesGap());
// SetAttribute(ML::AttrFollowGrainLine, layout->LayoutSettings().GetFollowGrainline());
SetAttribute(ML::AttrFollowGrainline, layout->LayoutSettings().GetFollowGrainline());
writeEndElement(); // control
WriteTiles(layout);

View file

@ -73,7 +73,7 @@ const QString AttrRight = QStringLiteral("right");
const QString AttrBottom = QStringLiteral("bottom");
const QString AttrWidth = QStringLiteral("width");
const QString AttrLength = QStringLiteral("length");
const QString AttrFollowGrainLine = QStringLiteral("followGrainLine");
const QString AttrFollowGrainline = QStringLiteral("followGrainline");
const QString AttrID = QStringLiteral("id");
const QString AttrMirrored = QStringLiteral("mirrored");
const QString AttrTransform = QStringLiteral("transform");

View file

@ -78,7 +78,7 @@ extern const QString AttrRight;
extern const QString AttrBottom;
extern const QString AttrWidth;
extern const QString AttrLength;
extern const QString AttrFollowGrainLine;
extern const QString AttrFollowGrainline;
extern const QString AttrID;
extern const QString AttrMirrored;
extern const QString AttrTransform;

View file

@ -27,6 +27,7 @@
<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>

View file

@ -117,7 +117,7 @@ public:
/** @brief grainlineInfo line */
QVector<QPointF> grainlinePoints{};
GrainlineArrowDirection grainlineArrowType{GrainlineArrowDirection::atFront};
GrainlineArrowDirection grainlineArrowType{GrainlineArrowDirection::atFront};
qreal grainlineAngle{0};
bool grainlineEnabled{false};