[TD]fix leader autohorizontal on rotated base view

This commit is contained in:
wandererfan
2024-11-19 18:59:39 -05:00
committed by Yorik van Havre
parent bc6183eb81
commit 0540b473ec
7 changed files with 75 additions and 63 deletions

View File

@@ -30,6 +30,7 @@
#include <App/Document.h>
#include <Base/Console.h>
#include <Base/Parameter.h>
#include <Base/Tools.h>
#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<Base::Vector3d> DrawLeaderLine::horizLastSegment(const std::vector<Base::Vector3d>& 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<Base::Vector3d> DrawLeaderLine::horizLastSegment(const std::vector<Base::Vector3d>& inDeltas)
{
// Base::Console().Message("DLL::horizLastSegment(in: %d)\n", inDeltas.size());
Base::Vector3d stdX{1, 0, 0};
std::vector<Base::Vector3d> 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<Base::Vector3d> 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<Base::Vector3d> 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<Bas
//! used by QGILL.
std::vector<Base::Vector3d> 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<Base::Vector3d>& 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<Base::Vector3d>& 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<Base::Vector3d> 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<Base::Vector3d> &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()
{