Improve visualization for tool Segmenting a simple curve.

This commit is contained in:
Roman Telezhynskyi 2022-08-20 17:32:24 +03:00
parent b1d7177952
commit 63cd0e7b5d
9 changed files with 124 additions and 13 deletions

View File

@ -401,7 +401,6 @@ auto VAbstractCubicBezier::CutSpline(qreal length, QPointF &spl1p2, QPointF &spl
QPointF &spl2p3, const QString &pointName) const -> QPointF QPointF &spl2p3, const QString &pointName) const -> QPointF
{ {
//Always need return two splines, so we must correct wrong length. //Always need return two splines, so we must correct wrong length.
const qreal minLength = ToPixel(1, Unit::Mm);
const qreal fullLength = GetLength(); const qreal fullLength = GetLength();
if (fullLength <= minLength) if (fullLength <= minLength)

View File

@ -171,7 +171,6 @@ auto VAbstractCubicBezierPath::CutSplinePath(qreal length, qint32 &p1, qint32 &p
} }
//Always need return two spline paths, so we must correct wrong length. //Always need return two spline paths, so we must correct wrong length.
const qreal minLength = ToPixel(1, Unit::Mm);
qreal fullLength = GetLength(); qreal fullLength = GetLength();
if (fullLength <= minLength) if (fullLength <= minLength)

View File

@ -228,6 +228,50 @@ auto VAbstractCurve::ToEnd(const QVector<QPointF> &points, const QPointF &end, b
return Reverse(reversed); return Reverse(reversed);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractCurve::ClosestPoint(QPointF scenePoint) const -> QPointF
{
const QVector<QPointF> points = GetPoints();
if (points.count() < 2)
{
return {};
}
if (VFuzzyComparePoints(ConstFirst(points), scenePoint))
{
return ConstFirst(points);
}
QPointF candidatePoint;
qreal bestDistance = INT_MAX;
bool found = false;
for (qint32 i = 0; i < points.count()-1; ++i)
{
const QPointF cPoint = VGObject::ClosestPoint(QLineF(points.at(i), points.at(i+1)), scenePoint);
if (IsPointOnLineSegment(cPoint, points.at(i), points.at(i+1)))
{
const qreal length = QLineF(scenePoint, cPoint).length();
if (length < bestDistance)
{
candidatePoint = cPoint;
bestDistance = length;
found = true;
}
}
}
if (found)
{
return candidatePoint;
}
else
{
return {};
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractCurve::GetPath() const -> QPainterPath auto VAbstractCurve::GetPath() const -> QPainterPath
{ {

View File

@ -81,6 +81,8 @@ public:
static auto SubdividePath(const QVector<QPointF> &points, QPointF p, QVector<QPointF> &sub1, static auto SubdividePath(const QVector<QPointF> &points, QPointF p, QVector<QPointF> &sub1,
QVector<QPointF> &sub2) -> bool; QVector<QPointF> &sub2) -> bool;
auto ClosestPoint(QPointF scenePoint) const -> QPointF;
virtual auto GetStartAngle () const -> qreal=0; virtual auto GetStartAngle () const -> qreal=0;
virtual auto GetEndAngle () const -> qreal=0; virtual auto GetEndAngle () const -> qreal=0;
@ -109,6 +111,8 @@ public:
static auto LengthCurveDirectionArrow() -> qreal; static auto LengthCurveDirectionArrow() -> qreal;
void SetAliasSuffix(const QString &aliasSuffix) override; void SetAliasSuffix(const QString &aliasSuffix) override;
static constexpr qreal minLength = ToPixel(1, Unit::Mm);
protected: protected:
virtual void CreateName() =0; virtual void CreateName() =0;
virtual void CreateAlias() =0; virtual void CreateAlias() =0;

View File

@ -460,8 +460,7 @@ auto VArc::CutPoint(qreal length, qreal fullLength, const QString &pointName) co
length = fullLength + length; length = fullLength + length;
} }
const qreal minLength = ToPixel(1, Unit::Mm); const qreal maxLength = fullLength - minLength;
const qreal maxLength = fullLength - ToPixel(1, Unit::Mm);
if (length < minLength) if (length < minLength)
{ {
@ -512,10 +511,10 @@ auto VArc::CutPointFlipped(qreal length, qreal fullLength, const QString &pointN
length = fullLength + length; length = fullLength + length;
} }
const qreal minLength = fullLength + ToPixel(1, Unit::Mm); const qreal minLengthFlipped = fullLength + minLength;
const qreal maxLength = ToPixel(-1, Unit::Mm); const qreal maxLengthFlipped = -minLength;
if (length < minLength) if (length < minLengthFlipped)
{ {
QString errorMsg; QString errorMsg;
if (not pointName.isEmpty()) if (not pointName.isEmpty())
@ -531,7 +530,7 @@ auto VArc::CutPointFlipped(qreal length, qreal fullLength, const QString &pointN
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) : VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
else if (length > maxLength) else if (length > maxLengthFlipped)
{ {
QString errorMsg; QString errorMsg;
if (not pointName.isEmpty()) if (not pointName.isEmpty())
@ -548,7 +547,7 @@ auto VArc::CutPointFlipped(qreal length, qreal fullLength, const QString &pointN
qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
length = qBound(minLength, length, maxLength); length = qBound(minLengthFlipped, length, maxLengthFlipped);
QLineF line(static_cast<QPointF>(GetCenter()), GetP1()); QLineF line(static_cast<QPointF>(GetCenter()), GetP1());
line.setAngle(line.angle() - qRadiansToDegrees(qAbs(length)/d->radius)); line.setAngle(line.angle() - qRadiansToDegrees(qAbs(length)/d->radius));

View File

@ -353,7 +353,6 @@ auto VEllipticalArc::CutArc(const qreal &length, VEllipticalArc &arc1, VElliptic
{ {
//Always need return two arcs, so we must correct wrong length. //Always need return two arcs, so we must correct wrong length.
qreal len = 0; qreal len = 0;
const qreal minLength = ToPixel(1, Unit::Mm);
const qreal fullLength = GetLength(); const qreal fullLength = GetLength();
if (fullLength <= minLength) if (fullLength <= minLength)

View File

@ -47,6 +47,7 @@
#include "ui_dialogcutspline.h" #include "ui_dialogcutspline.h"
#include "../vgeometry/vspline.h" #include "../vgeometry/vspline.h"
#include "../qmuparser/qmudef.h" #include "../qmuparser/qmudef.h"
#include "../vwidgets/vabstractmainwindow.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
@ -180,8 +181,10 @@ void DialogCutSpline::ChosenObject(quint32 id, const SceneObject &type)
vis->VisualMode(id); vis->VisualMode(id);
} }
prepare = true; prepare = true;
this->setModal(true);
this->show(); auto *window = qobject_cast<VAbstractMainWindow *>(VAbstractValApplication::VApp()->getMainWindow());
SCASSERT(window != nullptr)
connect(vis, &Visualization::ToolTip, window, &VAbstractMainWindow::ShowToolTip);
} }
} }
} }
@ -310,7 +313,7 @@ auto DialogCutSpline::GetFormula() const -> QString
* @brief getSplineId return id base point of line * @brief getSplineId return id base point of line
* @return id * @return id
*/ */
quint32 DialogCutSpline::getSplineId() const auto DialogCutSpline::getSplineId() const -> quint32
{ {
return getCurrentObjectId(ui->comboBoxSpline); return getCurrentObjectId(ui->comboBoxSpline);
} }
@ -354,3 +357,49 @@ auto DialogCutSpline::GetAliasSuffix2() const -> QString
{ {
return ui->lineEditAlias2->text(); return ui->lineEditAlias2->text();
} }
//---------------------------------------------------------------------------------------------------------------------
void DialogCutSpline::ShowDialog(bool click)
{
if (not prepare)
{
return;
}
auto FinishCreating = [this]()
{
vis->SetMode(Mode::Show);
vis->RefreshGeometry();
emit ToolTip(QString());
setModal(true);
show();
};
if (click)
{
// The check need to ignore first release of mouse button.
// User can select point by clicking on a label.
if (not m_firstRelease)
{
m_firstRelease = true;
return;
}
auto *scene = qobject_cast<VMainGraphicsScene *>(VAbstractValApplication::VApp()->getCurrentScene());
SCASSERT(scene != nullptr)
const QSharedPointer<VAbstractCubicBezier> spl = data->GeometricObject<VAbstractCubicBezier>(getSplineId());
QPointF p = spl->ClosestPoint(scene->getScenePos());
qreal len = spl->GetLengthByPoint(p);
if (len > 0)
{
SetFormula(QString::number(FromPixel(len, *data->GetPatternUnit())));
}
FinishCreating();
}
FinishCreating();
}

View File

@ -70,6 +70,8 @@ public:
void SetAliasSuffix2(const QString &alias); void SetAliasSuffix2(const QString &alias);
auto GetAliasSuffix2() const -> QString; auto GetAliasSuffix2() const -> QString;
void ShowDialog(bool click) override;
public slots: public slots:
void ChosenObject(quint32 id, const SceneObject &type) override; void ChosenObject(quint32 id, const SceneObject &type) override;
/** /**
@ -112,6 +114,8 @@ private:
QString m_originAliasSuffix1{}; QString m_originAliasSuffix1{};
QString m_originAliasSuffix2{}; QString m_originAliasSuffix2{};
bool m_firstRelease{false};
}; };
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -44,6 +44,7 @@
#include "../visualization.h" #include "../visualization.h"
#include "vispath.h" #include "vispath.h"
#include "../vwidgets/scalesceneitems.h" #include "../vwidgets/scalesceneitems.h"
#include "../vmisc/vmodifierkey.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VisToolCutSpline::VisToolCutSpline(const VContainer *data, QGraphicsItem *parent) VisToolCutSpline::VisToolCutSpline(const VContainer *data, QGraphicsItem *parent)
@ -85,6 +86,19 @@ void VisToolCutSpline::RefreshGeometry()
DrawPath(m_spl1, sp1.GetPath(), sp1.DirectionArrows(), Qt::darkGreen, lineStyle, Qt::RoundCap); DrawPath(m_spl1, sp1.GetPath(), sp1.DirectionArrows(), Qt::darkGreen, lineStyle, Qt::RoundCap);
DrawPath(m_spl2, sp2.GetPath(), sp2.DirectionArrows(), Qt::darkRed, lineStyle, Qt::RoundCap); DrawPath(m_spl2, sp2.GetPath(), sp2.DirectionArrows(), Qt::darkRed, lineStyle, Qt::RoundCap);
} }
else if (mode == Mode::Creation)
{
QPointF p = spl->ClosestPoint(Visualization::scenePos);
qreal length = spl->GetLengthByPoint(p);
DrawPoint(m_point, p, mainColor);
const QString prefix = UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true);
Visualization::toolTip = tr("Length = %1%2; "
"<b>Mouse click</b> - finish selecting the length, "
"<b>%3</b> - skip")
.arg(NumberToUser(length), prefix, VModifierKey::EnterKey());
}
} }
} }