Fix piece rotation with enabled Follow grainline.
This commit is contained in:
parent
e4481754f0
commit
7378cfbe95
|
@ -223,40 +223,62 @@ void VPPiece::RotateToGrainline(const VPTransformationOrigon &origin)
|
|||
}
|
||||
|
||||
QVector<qreal> angles;
|
||||
angles.reserve(4);
|
||||
angles.reserve(8);
|
||||
|
||||
const VPieceGrainline pieceGrainline = GetGrainline();
|
||||
|
||||
if (pieceGrainline.IsArrowUpEnabled())
|
||||
{
|
||||
angles.append(grainline.angleTo(fabricGrainline));
|
||||
qreal const angle = grainline.angleTo(fabricGrainline);
|
||||
angles.append(angle);
|
||||
angles.append(-(360. - angle));
|
||||
}
|
||||
|
||||
if (pieceGrainline.IsArrowDownEnabled())
|
||||
{
|
||||
QLineF arrow = grainline;
|
||||
arrow.setAngle(arrow.angle() + 180);
|
||||
angles.append(arrow.angleTo(fabricGrainline));
|
||||
|
||||
qreal const angle = arrow.angleTo(fabricGrainline);
|
||||
angles.append(angle);
|
||||
angles.append(-(360. - angle));
|
||||
}
|
||||
|
||||
if (pieceGrainline.IsArrowLeftEnabled())
|
||||
{
|
||||
QLineF arrow = grainline;
|
||||
arrow.setAngle(arrow.angle() + 90);
|
||||
angles.append(arrow.angleTo(fabricGrainline));
|
||||
|
||||
qreal const angle = arrow.angleTo(fabricGrainline);
|
||||
angles.append(angle);
|
||||
angles.append(-(360. - angle));
|
||||
}
|
||||
|
||||
if (pieceGrainline.IsArrowRightEnabled())
|
||||
{
|
||||
QLineF arrow = grainline;
|
||||
arrow.setAngle(arrow.angle() - 90);
|
||||
angles.append(arrow.angleTo(fabricGrainline));
|
||||
|
||||
qreal const angle = arrow.angleTo(fabricGrainline);
|
||||
angles.append(angle);
|
||||
angles.append(-(360. - angle));
|
||||
}
|
||||
|
||||
qreal degrees = 0;
|
||||
if (not angles.isEmpty())
|
||||
{
|
||||
degrees = *std::min_element(angles.constBegin(), angles.constEnd());
|
||||
qreal minAbsAngle = qAbs(angles.constFirst());
|
||||
degrees = angles.constFirst();
|
||||
|
||||
for (int i = 1; i < angles.size(); ++i)
|
||||
{
|
||||
qreal const absAngle = qAbs(angles.at(i));
|
||||
if (absAngle < minAbsAngle)
|
||||
{
|
||||
minAbsAngle = absAngle;
|
||||
degrees = angles.at(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rotate(origin.custom ? MappedDetailBoundingRect().center() : origin.origin, degrees);
|
||||
|
|
|
@ -109,6 +109,11 @@ void VPGraphicsTransformationOrigin::on_HideHandles(bool hide)
|
|||
void VPGraphicsTransformationOrigin::on_ShowOrigin(bool show)
|
||||
{
|
||||
setVisible(show);
|
||||
|
||||
if (not show)
|
||||
{
|
||||
m_hoverMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -404,7 +409,6 @@ void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
if (event->button() == Qt::LeftButton && event->type() != QEvent::GraphicsSceneMouseDoubleClick)
|
||||
{
|
||||
m_rotationStartPoint = event->scenePos();
|
||||
m_rotationSum = 0;
|
||||
m_controlsVisible = false;
|
||||
m_handleCorner = SelectedHandleCorner(event->pos());
|
||||
m_ignorePieceTransformation = true;
|
||||
|
@ -433,7 +437,7 @@ void VPGraphicsPieceControls::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
PrepareTransformationOrigin(event->modifiers() & Qt::ShiftModifier);
|
||||
PrepareTransformationOrigin(event->modifiers() & Qt::ShiftModifier); // NOLINT(readability-implicit-bool-conversion)
|
||||
|
||||
QPointF const rotationNewPoint = event->scenePos();
|
||||
|
||||
|
@ -451,24 +455,18 @@ void VPGraphicsPieceControls::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
||||
if (not qFuzzyIsNull(rotateOn))
|
||||
{
|
||||
QList<VPPiecePtr> const pieces = SelectedPieces();
|
||||
|
||||
VPLayoutPtr const layout = m_layout.toStrongRef();
|
||||
if (not layout.isNull())
|
||||
if (VPLayoutPtr const layout = m_layout.toStrongRef(); not layout.isNull())
|
||||
{
|
||||
CorrectRotationSum(layout, rotationOrigin, rotateOn);
|
||||
QList<VPPiecePtr> const pieces = SelectedPieces();
|
||||
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceRotate(pieces.constFirst(), rotationOrigin, rotateOn, m_rotationSum,
|
||||
allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
layout->UndoStack()->push(
|
||||
new VPUndoPieceRotate(pieces.constFirst(), rotationOrigin, rotateOn, allowChangeMerge));
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
auto *command =
|
||||
new VPUndoPiecesRotate(pieces, rotationOrigin, rotateOn, m_rotationSum, allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
layout->UndoStack()->push(new VPUndoPiecesRotate(pieces, rotationOrigin, rotateOn, allowChangeMerge));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -490,6 +488,19 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
VPLayoutPtr const layout = m_layout.toStrongRef();
|
||||
|
||||
if (not layout.isNull() && layout->LayoutSettings().GetFollowGrainline())
|
||||
{
|
||||
VPTransformationOrigon const rotationOrigin = TransformationOrigin(m_layout, m_pieceRect);
|
||||
QList<VPPiecePtr> const pieces = SelectedPieces();
|
||||
for (const auto &piece : qAsConst(pieces))
|
||||
{
|
||||
piece->RotateToGrainline(rotationOrigin);
|
||||
emit layout->PieceTransformationChanged(piece);
|
||||
}
|
||||
}
|
||||
|
||||
m_controlsVisible = true;
|
||||
m_ignorePieceTransformation = false;
|
||||
|
||||
|
@ -505,9 +516,7 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_originSaved)
|
||||
{
|
||||
if (VPLayoutPtr const layout = m_layout.toStrongRef(); not layout.isNull())
|
||||
if (m_originSaved && not layout.isNull())
|
||||
{
|
||||
if (VPSheetPtr const sheet = layout->GetFocusedSheet(); not sheet.isNull())
|
||||
{
|
||||
|
@ -521,7 +530,6 @@ void VPGraphicsPieceControls::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
}
|
||||
m_originSaved = false;
|
||||
}
|
||||
}
|
||||
|
||||
on_UpdateControls();
|
||||
allowChangeMerge = false;
|
||||
|
@ -853,32 +861,6 @@ void VPGraphicsPieceControls::PrepareTransformationOrigin(bool shiftPressed)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VPGraphicsPieceControls::CorrectRotationSum(const VPLayoutPtr &layout,
|
||||
const VPTransformationOrigon &rotationOrigin, qreal rotateOn)
|
||||
{
|
||||
if (layout.isNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VPGraphicsPieceControls::SelectedHandleCorner(const QPointF &pos) const -> VPHandleCorner
|
||||
{
|
||||
|
|
|
@ -143,7 +143,6 @@ private:
|
|||
|
||||
QRectF m_pieceRect{};
|
||||
QPointF m_rotationStartPoint{};
|
||||
qreal m_rotationSum{0};
|
||||
bool m_controlsVisible{false};
|
||||
VPLayoutWeakPtr m_layout{};
|
||||
VPHandleCorner m_handleCorner{VPHandleCorner::Invalid};
|
||||
|
@ -185,7 +184,6 @@ private:
|
|||
void UpdateCursor(VPHandleCorner corner);
|
||||
|
||||
void PrepareTransformationOrigin(bool shiftPressed);
|
||||
void CorrectRotationSum(const VPLayoutPtr &layout, const VPTransformationOrigon &rotationOrigin, qreal rotateOn);
|
||||
};
|
||||
|
||||
#endif // VPGRAPHICSPIECECONTROLS_H
|
||||
|
|
|
@ -320,8 +320,6 @@ void VPMainGraphicsView::keyReleaseEvent(QKeyEvent *event)
|
|||
sheet->SceneData()->RotationControls()->on_UpdateControls();
|
||||
sheet->SceneData()->RotationControls()->on_HideHandles(false);
|
||||
}
|
||||
|
||||
m_rotationSum = 0;
|
||||
}
|
||||
}
|
||||
VMainGraphicsView::keyReleaseEvent(event);
|
||||
|
@ -439,31 +437,34 @@ 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> const pieces = PreparePieces();
|
||||
|
||||
if (QList<VPPiecePtr> const pieces = PreparePieces(); pieces.size() == 1)
|
||||
if (pieces.size() == 1)
|
||||
{
|
||||
auto *command = new VPUndoPieceRotate(pieces.constFirst(), origin, angle, m_rotationSum, m_allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
layout->UndoStack()->push(new VPUndoPieceRotate(pieces.constFirst(), origin, angle, m_allowChangeMerge));
|
||||
}
|
||||
else if (pieces.size() > 1)
|
||||
{
|
||||
auto *command = new VPUndoPiecesRotate(pieces, origin, angle, m_rotationSum, m_allowChangeMerge);
|
||||
layout->UndoStack()->push(command);
|
||||
layout->UndoStack()->push(new VPUndoPiecesRotate(pieces, origin, angle, m_allowChangeMerge));
|
||||
}
|
||||
|
||||
QTime const dieTime = QTime::currentTime().addMSecs(150);
|
||||
while (QTime::currentTime() < dieTime)
|
||||
{
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
|
||||
}
|
||||
|
||||
for (const auto &piece : qAsConst(pieces))
|
||||
{
|
||||
if (not piece.isNull())
|
||||
{
|
||||
if (layout->LayoutSettings().GetFollowGrainline() || piece->IsFollowGrainline())
|
||||
{
|
||||
piece->RotateToGrainline(origin);
|
||||
}
|
||||
|
||||
emit layout->PieceTransformationChanged(piece);
|
||||
}
|
||||
}
|
||||
|
||||
m_allowChangeMerge = true;
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#ifndef VPMAINGRAPHICSVIEW_H
|
||||
#define VPMAINGRAPHICSVIEW_H
|
||||
|
||||
#include "../vwidgets/vmaingraphicsview.h"
|
||||
#include "../layout/layoutdef.h"
|
||||
#include "../vwidgets/vmaingraphicsview.h"
|
||||
|
||||
class VMainGraphicsScene;
|
||||
class VPGraphicsPieceControls;
|
||||
|
@ -45,6 +45,7 @@ class VPPiece;
|
|||
class VPMainGraphicsView : public VMainGraphicsView
|
||||
{
|
||||
Q_OBJECT // NOLINT
|
||||
|
||||
public:
|
||||
VPMainGraphicsView(const VPLayoutPtr &layout, QWidget *parent);
|
||||
~VPMainGraphicsView() override = default;
|
||||
|
@ -98,8 +99,6 @@ private:
|
|||
|
||||
bool m_allowChangeMerge{false};
|
||||
|
||||
qreal m_rotationSum{0};
|
||||
|
||||
bool m_hasStickyPosition{false};
|
||||
qreal m_stickyTranslateX{0};
|
||||
qreal m_stickyTranslateY{0};
|
||||
|
|
|
@ -41,12 +41,11 @@ auto RoundAngle(qreal angle) -> qreal
|
|||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPUndoPieceRotate::VPUndoPieceRotate(const VPPiecePtr &piece, const VPTransformationOrigon &origin, qreal angle,
|
||||
qreal angleSum, bool allowMerge, QUndoCommand *parent)
|
||||
bool allowMerge, QUndoCommand *parent)
|
||||
: VPUndoCommand(allowMerge, parent),
|
||||
m_piece(piece),
|
||||
m_origin(origin),
|
||||
m_angle(angle),
|
||||
m_angleSum(angleSum)
|
||||
m_angle(angle)
|
||||
{
|
||||
SCASSERT(not piece.isNull())
|
||||
|
||||
|
@ -81,6 +80,10 @@ void VPUndoPieceRotate::undo()
|
|||
}
|
||||
|
||||
piece->SetMatrix(m_oldTransform);
|
||||
if (m_followGrainline || piece->IsFollowGrainline())
|
||||
{
|
||||
piece->RotateToGrainline(m_origin);
|
||||
}
|
||||
emit layout->PieceTransformationChanged(piece);
|
||||
}
|
||||
|
||||
|
@ -104,23 +107,9 @@ void VPUndoPieceRotate::redo()
|
|||
layout->SetFocusedSheet(piece->Sheet());
|
||||
}
|
||||
|
||||
if (m_firstCall)
|
||||
{
|
||||
if ((m_followGrainline || piece->IsFollowGrainline()) && 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->IsFollowGrainline())
|
||||
if (!m_firstCall && (m_followGrainline || piece->IsFollowGrainline()))
|
||||
{
|
||||
piece->RotateToGrainline(m_origin);
|
||||
}
|
||||
|
@ -168,11 +157,10 @@ auto VPUndoPieceRotate::id() const -> int
|
|||
// rotate pieces
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VPUndoPiecesRotate::VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const VPTransformationOrigon &origin,
|
||||
qreal angle, qreal angleSum, bool allowMerge, QUndoCommand *parent)
|
||||
qreal angle, bool allowMerge, QUndoCommand *parent)
|
||||
: VPUndoCommand(allowMerge, parent),
|
||||
m_origin(origin),
|
||||
m_angle(angle),
|
||||
m_angleSum(angleSum)
|
||||
m_angle(angle)
|
||||
{
|
||||
setText(QObject::tr("rotate pieces"));
|
||||
|
||||
|
@ -219,6 +207,10 @@ void VPUndoPiecesRotate::undo()
|
|||
if (m_oldTransforms.contains(p->GetUniqueID()))
|
||||
{
|
||||
p->SetMatrix(m_oldTransforms.value(p->GetUniqueID()));
|
||||
if (m_followGrainline || p->IsFollowGrainline())
|
||||
{
|
||||
p->RotateToGrainline(m_origin);
|
||||
}
|
||||
emit layout->PieceTransformationChanged(p);
|
||||
}
|
||||
}
|
||||
|
@ -248,24 +240,10 @@ void VPUndoPiecesRotate::redo()
|
|||
{
|
||||
VPPiecePtr const p = piece.toStrongRef();
|
||||
if (not p.isNull())
|
||||
{
|
||||
if (m_firstCall)
|
||||
{
|
||||
if ((m_followGrainline || p->IsFollowGrainline()) && 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->IsFollowGrainline())
|
||||
if (!m_firstCall && (m_followGrainline || p->IsFollowGrainline()))
|
||||
{
|
||||
p->RotateToGrainline(m_origin);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,9 @@
|
|||
class VPUndoPieceRotate : public VPUndoCommand
|
||||
{
|
||||
Q_OBJECT // NOLINT
|
||||
|
||||
public:
|
||||
VPUndoPieceRotate(const VPPiecePtr &piece, const VPTransformationOrigon &origin, qreal angle, qreal angleSum,
|
||||
VPUndoPieceRotate(const VPPiecePtr &piece, const VPTransformationOrigon &origin, qreal angle,
|
||||
bool allowMerge = false, QUndoCommand *parent = nullptr);
|
||||
|
||||
~VPUndoPieceRotate() override = default;
|
||||
|
@ -63,7 +64,6 @@ private:
|
|||
QTransform m_oldTransform{};
|
||||
VPTransformationOrigon m_origin;
|
||||
qreal m_angle;
|
||||
qreal m_angleSum;
|
||||
bool m_followGrainline{false};
|
||||
};
|
||||
|
||||
|
@ -95,9 +95,10 @@ inline auto VPUndoPieceRotate::FollowGrainline() const -> bool
|
|||
class VPUndoPiecesRotate : public VPUndoCommand
|
||||
{
|
||||
Q_OBJECT // NOLINT
|
||||
|
||||
public:
|
||||
explicit VPUndoPiecesRotate(const QList<VPPiecePtr> &pieces, const VPTransformationOrigon &origin, qreal angle,
|
||||
qreal angleSum, bool allowMerge = false, QUndoCommand *parent = nullptr);
|
||||
bool allowMerge = false, QUndoCommand *parent = nullptr);
|
||||
~VPUndoPiecesRotate() override = default;
|
||||
|
||||
void undo() override;
|
||||
|
@ -119,7 +120,6 @@ private:
|
|||
QMap<QString, QTransform> m_oldTransforms{};
|
||||
VPTransformationOrigon m_origin;
|
||||
qreal m_angle;
|
||||
qreal m_angleSum;
|
||||
bool m_followGrainline{false};
|
||||
|
||||
auto Layout() const -> VPLayoutPtr;
|
||||
|
|
|
@ -3521,6 +3521,25 @@ void VPMainWindow::RotatePieces()
|
|||
return;
|
||||
}
|
||||
|
||||
auto StickyRotateToGrainline = [this](const VPPiecePtr &piece, const VPTransformationOrigon &origin)
|
||||
{
|
||||
QTime const dieTime = QTime::currentTime().addMSecs(150);
|
||||
while (QTime::currentTime() < dieTime)
|
||||
{
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
|
||||
}
|
||||
|
||||
if (not piece.isNull())
|
||||
{
|
||||
if (m_layout->LayoutSettings().GetFollowGrainline() || piece->IsFollowGrainline())
|
||||
{
|
||||
piece->RotateToGrainline(origin);
|
||||
}
|
||||
|
||||
emit m_layout->PieceTransformationChanged(piece);
|
||||
}
|
||||
};
|
||||
|
||||
if (ui->checkBoxTransformSeparately->isChecked())
|
||||
{
|
||||
m_layout->UndoStack()->beginMacro(tr("rotate pieces"));
|
||||
|
@ -3534,7 +3553,9 @@ void VPMainWindow::RotatePieces()
|
|||
origin.origin = rect.center();
|
||||
origin.custom = true;
|
||||
|
||||
m_layout->UndoStack()->push(new VPUndoPieceRotate(piece, origin, angle, angle));
|
||||
m_layout->UndoStack()->push(new VPUndoPieceRotate(piece, origin, angle));
|
||||
|
||||
StickyRotateToGrainline(piece, origin);
|
||||
}
|
||||
}
|
||||
m_layout->UndoStack()->endMacro();
|
||||
|
@ -3548,8 +3569,12 @@ void VPMainWindow::RotatePieces()
|
|||
}
|
||||
|
||||
VPTransformationOrigon const origin = sheet->TransformationOrigin();
|
||||
auto *command = new VPUndoPiecesRotate(selectedPieces, origin, angle, angle);
|
||||
m_layout->UndoStack()->push(command);
|
||||
m_layout->UndoStack()->push(new VPUndoPiecesRotate(selectedPieces, origin, angle));
|
||||
|
||||
for (const auto &piece : qAsConst(selectedPieces))
|
||||
{
|
||||
StickyRotateToGrainline(piece, origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2298,11 +2298,11 @@ auto VToolSeamAllowance::FindGrainlineGeometry(const VGrainlineData &geom, const
|
|||
const auto centerPinPoint = VAbstractTool::data.GeometricObject<VPointF>(centerPin);
|
||||
|
||||
const qreal cLength = ToPixel(length, *VDataTool::data.GetPatternUnit());
|
||||
QLineF grainline(centerPinPoint->x(), centerPinPoint->y(), centerPinPoint->x() + cLength / 2.0,
|
||||
QLineF grainline(centerPinPoint->x(), centerPinPoint->y(), centerPinPoint->x() - cLength / 2.0,
|
||||
centerPinPoint->y());
|
||||
|
||||
grainline.setAngle(rotationAngle);
|
||||
grainline = QLineF(grainline.p2(), grainline.p1());
|
||||
Swap(grainline);
|
||||
grainline.setLength(cLength);
|
||||
|
||||
pos = grainline.p2();
|
||||
|
|
Loading…
Reference in New Issue
Block a user