diff --git a/src/Mod/TechDraw/App/DrawLeaderLine.cpp b/src/Mod/TechDraw/App/DrawLeaderLine.cpp index 0e1f8c2dce..99b8213825 100644 --- a/src/Mod/TechDraw/App/DrawLeaderLine.cpp +++ b/src/Mod/TechDraw/App/DrawLeaderLine.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "DrawViewPart.h" #include "DrawPage.h" @@ -96,7 +97,6 @@ DrawLeaderLine::DrawLeaderLine() ADD_PROPERTY_TYPE(RotatesWithParent ,(true), group, App::Prop_None, "If true, leader rotates around parent. If false, only first segment of leader changes with parent rotation."); - //hide the DrawView properties that don't apply to Leader ScaleType.setStatus(App::Property::ReadOnly, true); ScaleType.setStatus(App::Property::Hidden, true); @@ -110,11 +110,6 @@ DrawLeaderLine::DrawLeaderLine() LockPosition.setStatus(App::Property::Hidden, true); } -void DrawLeaderLine::onChanged(const App::Property* prop) -{ - DrawView::onChanged(prop); -} - short DrawLeaderLine::mustExecute() const { if (!isRestoring() && LeaderParent.isTouched()) { @@ -140,8 +135,6 @@ App::DocumentObjectExecReturn *DrawLeaderLine::execute() return App::DocumentObject::StdReturn; } - // is horizLastSegment something that should be done only at draw time? - horizLastSegment(); overrideKeepUpdated(false); return DrawView::execute(); } @@ -202,35 +195,39 @@ Base::Vector3d DrawLeaderLine::getAttachPoint() //! unit agnostic conversion of last segment to horizontal. need to do this at drawing time otherwise //! we just realign the canonical form. -void DrawLeaderLine::horizLastSegment() +std::vector DrawLeaderLine::horizLastSegment(const std::vector& inDeltas, double rotationDeg) { - // Base::Console().Message("DLL::horizLastSegment() - auto: %d\n", AutoHorizontal.getValue()); - bool adjust = AutoHorizontal.getValue(); - if (!adjust) { - return; - } - auto temp = horizLastSegment(WayPoints.getValues()); - WayPoints.setValues(temp); -} - -std::vector DrawLeaderLine::horizLastSegment(const std::vector& inDeltas) -{ - // Base::Console().Message("DLL::horizLastSegment(in: %d)\n", inDeltas.size()); + Base::Vector3d stdX{1, 0, 0}; std::vector wp = inDeltas; - if (wp.size() > 1) { + if (wp.size() > 1) { size_t iLast = wp.size() - 1; size_t iPen = wp.size() - 2; Base::Vector3d last = wp.at(iLast); Base::Vector3d penUlt = wp.at(iPen); - last.y = penUlt.y; - wp.at(iLast) = last; + + auto lastSeg = DU::invertY(last - penUlt); + auto lastSegLong = lastSeg.Length(); + auto lastSegRotated = lastSeg; + lastSegRotated.RotateZ(Base::toRadians(rotationDeg)); + auto lastSegRotatedUnit = lastSegRotated; + lastSegRotatedUnit.Normalize(); + auto dot = lastSegRotatedUnit.Dot(stdX); + + auto newLast = penUlt + stdX * lastSegLong; + if (dot < 0) { + newLast = penUlt - stdX * lastSegLong; + } + + wp.at(iLast) = newLast; } return wp; } + //! returns the mid point of last segment. used by leader decorators like weld symbol. +//! the returned point is unscaled and unrotated. Base::Vector3d DrawLeaderLine::getTileOrigin() const { std::vector wp = WayPoints.getValues(); @@ -273,7 +270,7 @@ Base::Vector3d DrawLeaderLine::getTailPoint() const //! pagePoints are in mm from bottom left of page. DrawLeaderLine* DrawLeaderLine::makeLeader(DrawViewPart* parent, std::vector pagePoints, int iStartSymbol, int iEndSymbol) { - // Base::Console().Message("DLL::makeLeader(%s, %d, %d, %d)\n", parent->getNameInDocument(), pagePoints.size(), iStartSymbol, iEndSymbol); + Base::Console().Message("DLL::makeLeader(%s, %d, %d, %d)\n", parent->getNameInDocument(), pagePoints.size(), iStartSymbol, iEndSymbol); if (pagePoints.size() < 2) { Base::Console().Message("DLL::makeLeader - not enough pagePoints\n"); return {}; @@ -338,7 +335,6 @@ DrawLeaderLine* DrawLeaderLine::makeLeader(DrawViewPart* parent, std::vector DrawLeaderLine::getScaledAndRotatedPoints(bool doScale, bool doRotate) const { - // Base::Console().Message("DLL::getScaledAndRotatedPoints(%d, %d)\n", doScale, doRotate); auto dvp = getBaseView(); if (!dvp) { // document is restoring? @@ -378,7 +374,6 @@ DrawLeaderLine::makeCanonicalPoints(const std::vector& inPoints, bool doScale, bool doRotate) const { - // Base::Console().Message("DLL::makeCanonicalPoints(%d, %d, %d)\n", inPoints.size(), doScale, doRotate); auto dvp = getBaseView(); double scale{1.0}; @@ -414,12 +409,15 @@ DrawLeaderLine::makeCanonicalPointsInverted(const std::vector& i for (auto& point : inPoints) { conventionalPoints.push_back(DU::invertY(point)); } - auto conventionalCanon = makeCanonicalPoints(inPoints, doScale, doRotate); + + auto conventionalCanon = makeCanonicalPoints(conventionalPoints, doScale, doRotate); + std::vector invertedPoints; invertedPoints.reserve(inPoints.size()); for (auto& point : conventionalCanon) { invertedPoints.push_back(DU::invertY(point)); } + return invertedPoints; } @@ -442,6 +440,14 @@ bool DrawLeaderLine::getDefAuto() const return Preferences::getPreferenceGroup("LeaderLine")->GetBool("AutoHorizontal", true); } +void DrawLeaderLine::dumpWaypoints(const std::vector &points, const std::string &label) +{ + Base::Console().Message("DLL::dumpWaypoints - %s\n", label.c_str()); + for (auto& p : points) { + Base::Console().Message(">>>> a point: %s\n", DU::formatVector(p).c_str()); + } +} + PyObject *DrawLeaderLine::getPyObject() { diff --git a/src/Mod/TechDraw/App/DrawLeaderLine.h b/src/Mod/TechDraw/App/DrawLeaderLine.h index 82c7b8e5bf..427e07c759 100644 --- a/src/Mod/TechDraw/App/DrawLeaderLine.h +++ b/src/Mod/TechDraw/App/DrawLeaderLine.h @@ -69,8 +69,7 @@ public: bool keepUpdated() override; double getScale() const override; double getBaseScale() const; - void horizLastSegment(); - static std::vector horizLastSegment(const std::vector& inDeltas); + static std::vector horizLastSegment(const std::vector& inDeltas, double rotationDeg); bool getDefAuto() const; Base::Vector3d getTileOrigin() const; @@ -88,8 +87,7 @@ public: bool isParentReady() const; -protected: - void onChanged(const App::Property* prop) override; + void dumpWaypoints(const std::vector& points, const std::string& label); private: diff --git a/src/Mod/TechDraw/Gui/QGIDecoration.cpp b/src/Mod/TechDraw/Gui/QGIDecoration.cpp index 8461d40539..f1c456a65d 100644 --- a/src/Mod/TechDraw/Gui/QGIDecoration.cpp +++ b/src/Mod/TechDraw/Gui/QGIDecoration.cpp @@ -60,6 +60,9 @@ void QGIDecoration::paint ( QPainter * painter, const QStyleOptionGraphicsItem * QStyleOptionGraphicsItem myOption(*option); myOption.state &= ~QStyle::State_Selected; + painter->setPen(Qt::green); + painter->drawRect(boundingRect()); //good for debugging + QGraphicsItemGroup::paint (painter, &myOption, widget); } diff --git a/src/Mod/TechDraw/Gui/QGILeaderLine.cpp b/src/Mod/TechDraw/Gui/QGILeaderLine.cpp index 2b31f9b361..e7c4ce2fb5 100644 --- a/src/Mod/TechDraw/Gui/QGILeaderLine.cpp +++ b/src/Mod/TechDraw/Gui/QGILeaderLine.cpp @@ -143,21 +143,18 @@ QVariant QGILeaderLine::itemChange(GraphicsItemChange change, const QVariant& va //QGILL isn't draggable so skip QGIV::mousePress have event void QGILeaderLine::mousePressEvent(QGraphicsSceneMouseEvent* event) { - // Base::Console().Message("QGILL::mousePressEvent() - %s\n", getViewName()); QGraphicsItem::mousePressEvent(event); } -//QGILL isn't draggable so skip QGIV::mouseRelease +//QGILL isn't draggable so skip QGIV::Release void QGILeaderLine::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { - // Base::Console().Message("QGILL::mouseReleaseEvent() - %s\n", getViewName()); QGraphicsItem::mouseReleaseEvent(event); } //! start editor on double click void QGILeaderLine::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) { - // Base::Console().Message("QGILL::mouseDoubleClickEvent() - %s\n", getViewName()); auto ViewProvider = dynamic_cast(getViewProvider(getLeaderFeature())); if (!ViewProvider) { qWarning() << "QGILeaderLine::mouseDoubleClickEvent: No valid view provider"; @@ -419,7 +416,6 @@ void QGILeaderLine::draw() QPainterPath QGILeaderLine::makeLeaderPath(std::vector qPoints) { - // Base::Console().Message("QGILeaderLine::makeLeaderPath()\n"); QPainterPath result; DrawLeaderLine* featLeader = getLeaderFeature(); if (!featLeader) { @@ -469,7 +465,6 @@ QPainterPath QGILeaderLine::makeLeaderPath(std::vector qPoints) //! result is is not inverted (Y grows upwards). QPointF QGILeaderLine::getAttachFromFeature() { - // Base::Console().Message("QGILL::getAttachFromFeature()\n"); TechDraw::DrawLeaderLine* featLeader = getLeaderFeature(); if (!featLeader) { // Base::Console().Message("QGIL::getAttachFromLeader - no feature\n"); @@ -483,7 +478,6 @@ QPointF QGILeaderLine::getAttachFromFeature() std::vector QGILeaderLine::getWayPointsFromFeature() { - // Base::Console().Message("QGILL::getWayPointsFromFeature()\n"); DrawLeaderLine* featLeader = getLeaderFeature(); if (!featLeader) { // Base::Console().Message("QGILL::getWayPointsFromFeature - featLeader is nullptr\n"); @@ -494,6 +488,9 @@ std::vector QGILeaderLine::getWayPointsFromFeature() auto doScale = featLeader->Scalable.getValue(); auto doRotate = featLeader->RotatesWithParent.getValue(); auto vPoints = featLeader->getScaledAndRotatedPoints(doScale, doRotate); + if (featLeader->AutoHorizontal.getValue()) { + vPoints = DrawLeaderLine::horizLastSegment(vPoints, featLeader->getBaseView()->Rotation.getValue()); + } std::vector qPoints; qPoints.reserve(vPoints.size()); @@ -504,20 +501,19 @@ std::vector QGILeaderLine::getWayPointsFromFeature() qPoints.push_back(DU::toQPointF(entry)); } else { // use points as saved in >= v0.22 - qPoints.push_back(DU::toQPointF(DGU::toSceneCoords(entry, false))); + qPoints.push_back(DU::toQPointF(Rez::guiX(entry))); } } if (qPoints.empty()) { Base::Console().Warning("QGILeaderLine::getWayPointsFromFeature - no points\n"); } - + return qPoints; } void QGILeaderLine::setArrows(std::vector pathPoints) { - // Base::Console().Message("QGILL::setArrows()\n"); Base::Vector3d stdX(1.0, 0.0, 0.0); TechDraw::DrawLeaderLine* featLeader = getLeaderFeature(); @@ -628,8 +624,8 @@ void QGILeaderLine::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt QStyleOptionGraphicsItem myOption(*option); myOption.state &= ~QStyle::State_Selected; - // painter->setPen(Qt::blue); - // painter->drawRect(boundingRect()); //good for debugging + painter->setPen(Qt::blue); + painter->drawRect(boundingRect()); //good for debugging QGIView::paint(painter, &myOption, widget); } diff --git a/src/Mod/TechDraw/Gui/QGIWeldSymbol.cpp b/src/Mod/TechDraw/Gui/QGIWeldSymbol.cpp index 7d61d7f39d..929af6dd22 100644 --- a/src/Mod/TechDraw/Gui/QGIWeldSymbol.cpp +++ b/src/Mod/TechDraw/Gui/QGIWeldSymbol.cpp @@ -21,6 +21,7 @@ ***************************************************************************/ #include "PreCompiled.h" +#include #ifndef _PreComp_ # include # include @@ -546,8 +547,8 @@ void QGIWeldSymbol::paint ( QPainter * painter, const QStyleOptionGraphicsItem * QStyleOptionGraphicsItem myOption(*option); myOption.state &= ~QStyle::State_Selected; -// painter->setPen(Qt::red); -// painter->drawRect(boundingRect()); //good for debugging + painter->setPen(Qt::red); + painter->drawRect(boundingRect()); //good for debugging QGIView::paint (painter, &myOption, widget); } diff --git a/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp b/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp index 9926606c1e..d864feb4d2 100644 --- a/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp +++ b/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp @@ -215,7 +215,6 @@ void TaskLeaderLine::changeEvent(QEvent *event) void TaskLeaderLine::setUiPrimary() { -// Base::Console().Message("TTL::setUiPrimary()\n"); enableVPUi(true); setWindowTitle(QObject::tr("New Leader Line")); @@ -258,7 +257,6 @@ void TaskLeaderLine::enableVPUi(bool enable) void TaskLeaderLine::setUiEdit() { -// Base::Console().Message("TTL::setUiEdit()\n"); enableVPUi(true); setWindowTitle(QObject::tr("Edit Leader Line")); @@ -380,16 +378,14 @@ void TaskLeaderLine::createLeaderFeature(std::vector sceneDeltas std::vector pageDeltas; // convert deltas to mm. leader points are stored inverted, so we do not convert to conventional Y axis for (auto& delta : sceneDeltas) { - Base::Vector3d deltaInPageCoords = DGU::fromSceneCoords(delta, false); + Base::Vector3d deltaInPageCoords = Rez::appX(delta); pageDeltas.push_back(deltaInPageCoords); } -// should just do this in place. - if (m_lineFeat->AutoHorizontal.getValue()) { - pageDeltas = DrawLeaderLine::horizLastSegment(pageDeltas); - } - // convert to unscaled, unrotated but inverted - auto temp = m_lineFeat->makeCanonicalPointsInverted(pageDeltas); + // already unrotated, now convert to unscaled, but inverted + bool doScale{true}; + bool doRotate{false}; + auto temp = m_lineFeat->makeCanonicalPointsInverted(pageDeltas, doScale, doRotate); m_lineFeat->WayPoints.setValues(temp); } commonFeatureUpdate(); @@ -491,8 +487,6 @@ void TaskLeaderLine::removeFeature() void TaskLeaderLine::onTrackerClicked(bool clicked) { Q_UNUSED(clicked); -// Base::Console().Message("TTL::onTrackerClicked() m_pbTrackerState: %d\n", -// m_pbTrackerState); if (!m_vpp->getMDIViewPage()) { Base::Console().Message("TLL::onTrackerClicked - no Mdi, no Tracker!\n"); return; @@ -714,7 +708,7 @@ QGIView* TaskLeaderLine::findParentQGIV() return vpdv->getQView();; } -void TaskLeaderLine::setEditCursor(QCursor cursor) +void TaskLeaderLine::setEditCursor(const QCursor &cursor) { if (!m_vpp->getQGSPage()) { return; @@ -725,15 +719,29 @@ void TaskLeaderLine::setEditCursor(QCursor cursor) } } -//from scene QPointF to zero origin (delta from p0) Vector3d points +// from scene QPointF to zero origin (delta from p0) Vector3d points std::vector TaskLeaderLine::scenePointsToDeltas(std::vector scenePoints) { -// Base::Console().Message("TTL::scenePointsToDeltas(%d)\n", pts.size()); + if (scenePoints.empty()) { + return {}; + } + std::vector result; + auto frontPoint = DU::toVector3d(m_qgParent->mapFromScene(scenePoints.front())); result.reserve(scenePoints.size()); for (auto& point: scenePoints) { - QPointF delta = point - scenePoints.front(); - result.push_back(DU::toVector3d(delta)); + auto viewPoint = m_qgParent->mapFromScene(point); + auto vPoint = DU::toVector3d(viewPoint); + auto delta = vPoint - frontPoint; + auto rotationDeg = m_baseFeat->Rotation.getValue(); + auto deltaUnrotated{delta}; + if (rotationDeg != 0) { + deltaUnrotated = DU::invertY(deltaUnrotated); + deltaUnrotated.RotateZ(-Base::toRadians(rotationDeg)); + deltaUnrotated = DU::invertY(deltaUnrotated); + } + + result.push_back(deltaUnrotated); } return result; } diff --git a/src/Mod/TechDraw/Gui/TaskLeaderLine.h b/src/Mod/TechDraw/Gui/TaskLeaderLine.h index 156a563697..d5b4122465 100644 --- a/src/Mod/TechDraw/Gui/TaskLeaderLine.h +++ b/src/Mod/TechDraw/Gui/TaskLeaderLine.h @@ -91,7 +91,7 @@ protected: void setUiPrimary(); void setUiEdit(); void enableVPUi(bool enable); - void setEditCursor(QCursor cursor); + void setEditCursor(const QCursor& cursor); QGIView* findParentQGIV();