TechDraw: Enable snapping section views to their base views.
This commit is contained in:
committed by
WandererFan
parent
f0ebd62637
commit
127ee90cec
@@ -932,27 +932,29 @@ std::vector<TechDraw::FacePtr> DrawViewSection::makeTDSectionFaces(TopoDS_Compou
|
||||
std::pair<Base::Vector3d, Base::Vector3d> DrawViewSection::sectionLineEnds()
|
||||
{
|
||||
std::pair<Base::Vector3d, Base::Vector3d> result;
|
||||
Base::Vector3d stdZ(0.0, 0.0, 1.0);
|
||||
double baseRotation = getBaseDVP()->Rotation.getValue();// Qt degrees are clockwise
|
||||
Base::Rotation rotator(stdZ, baseRotation * M_PI / 180.0);
|
||||
Base::Rotation unrotator(stdZ, -baseRotation * M_PI / 180.0);
|
||||
|
||||
Base::Vector3d dir = getSectionDirectionOnBaseView();
|
||||
|
||||
Base::Vector3d sectionOrg = SectionOrigin.getValue() - getBaseDVP()->getOriginalCentroid();
|
||||
sectionOrg = getBaseDVP()->projectPoint(sectionOrg);// convert to base view CS
|
||||
double halfSize = (getBaseDVP()->getSizeAlongVector(dir) / 2.0) * SectionLineStretch.getValue();
|
||||
result.first = sectionOrg + dir * halfSize;
|
||||
result.second = sectionOrg - dir * halfSize;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// calculate the direction of the section in 2d on the base view.
|
||||
Base::Vector3d DrawViewSection::getSectionDirectionOnBaseView()
|
||||
{
|
||||
auto sNorm = SectionNormal.getValue();
|
||||
auto axis = getBaseDVP()->Direction.getValue();
|
||||
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
|
||||
Base::Vector3d sectionLineDir = -axis.Cross(sNorm);
|
||||
sectionLineDir.Normalize();
|
||||
sectionLineDir = getBaseDVP()->projectPoint(sectionLineDir);// convert to base view CS
|
||||
sectionLineDir.Normalize();
|
||||
|
||||
Base::Vector3d sectionOrg = SectionOrigin.getValue() - getBaseDVP()->getOriginalCentroid();
|
||||
sectionOrg = getBaseDVP()->projectPoint(sectionOrg);// convert to base view
|
||||
// CS
|
||||
double halfSize = (getBaseDVP()->getSizeAlongVector(sectionLineDir) / 2.0) * SectionLineStretch.getValue();
|
||||
result.first = sectionOrg + sectionLineDir * halfSize;
|
||||
result.second = sectionOrg - sectionLineDir * halfSize;
|
||||
|
||||
return result;
|
||||
return sectionLineDir;
|
||||
}
|
||||
|
||||
// find the points and directions to make the change point marks.
|
||||
|
||||
@@ -165,6 +165,7 @@ public:
|
||||
static const char* CutSurfaceEnums[];
|
||||
|
||||
virtual std::pair<Base::Vector3d, Base::Vector3d> sectionLineEnds();
|
||||
Base::Vector3d getSectionDirectionOnBaseView();
|
||||
virtual ChangePointVector getChangePointsFromSectionLine();
|
||||
|
||||
bool showSectionEdges(void);
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <Mod/TechDraw/App/DrawPage.h>
|
||||
#include <Mod/TechDraw/App/DrawProjGroup.h>
|
||||
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
|
||||
#include <Mod/TechDraw/App/DrawViewSection.h>
|
||||
#include <Mod/TechDraw/App/DrawViewPart.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
#include <Mod/TechDraw/App/DrawView.h>
|
||||
|
||||
@@ -71,7 +73,8 @@ QGIView::QGIView()
|
||||
:QGraphicsItemGroup(),
|
||||
viewObj(nullptr),
|
||||
m_innerView(false),
|
||||
m_multiselectActivated(false)
|
||||
m_multiselectActivated(false),
|
||||
snapping(false)
|
||||
{
|
||||
setCacheMode(QGraphicsItem::NoCache);
|
||||
setHandlesChildEvents(false);
|
||||
@@ -153,10 +156,9 @@ void QGIView::alignTo(QGraphicsItem*item, const QString &alignment)
|
||||
|
||||
QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
QPointF newPos(0.0, 0.0);
|
||||
// Base::Console().Message("QGIV::itemChange(%d)\n", change);
|
||||
if(change == ItemPositionChange && scene()) {
|
||||
newPos = value.toPointF(); //position within parent!
|
||||
QPointF newPos = value.toPointF(); //position within parent!
|
||||
|
||||
TechDraw::DrawView *viewObj = getViewObject();
|
||||
auto* dpgi = dynamic_cast<TechDraw::DrawProjGroupItem*>(viewObj);
|
||||
@@ -181,7 +183,9 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
// tell the feature that we have moved
|
||||
Gui::ViewProvider *vp = getViewProvider(viewObj);
|
||||
if (vp && !vp->isRestoring()) {
|
||||
snapping = true; // avoid triggering updateView by the VP updateData
|
||||
viewObj->setPosition(Rez::appX(newPos.x()), Rez::appX(-newPos.y()));
|
||||
snapping = false;
|
||||
}
|
||||
|
||||
return newPos;
|
||||
@@ -201,7 +205,7 @@ QVariant QGIView::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
return QGraphicsItemGroup::itemChange(change, value);
|
||||
}
|
||||
|
||||
void QGIView::snapPosition(QPointF& pos)
|
||||
void QGIView::snapPosition(QPointF& mPos)
|
||||
{
|
||||
// For general views we check if the view is close to aligned vertically or horizontally to another view.
|
||||
|
||||
@@ -220,20 +224,65 @@ void QGIView::snapPosition(QPointF& pos)
|
||||
}
|
||||
|
||||
std::vector<QGIView*> views = scenePage->getViews();
|
||||
|
||||
qreal snapPercent = 0.05;
|
||||
|
||||
auto* sectionView = dynamic_cast<TechDraw::DrawViewSection*>(getViewObject());
|
||||
if (sectionView) {
|
||||
auto* baseView = sectionView->getBaseDVP();
|
||||
if (!baseView) { return; }
|
||||
|
||||
Base::Vector3d dir3d = sectionView->getSectionDirectionOnBaseView();
|
||||
double bSize = Rez::guiX(baseView->getSizeAlongVector(dir3d));
|
||||
double sSize = Rez::guiX(sectionView->getSizeAlongVector(dir3d));
|
||||
|
||||
auto* vpdv = dynamic_cast<ViewProviderDrawingView*>(getViewProvider(baseView));
|
||||
if (!vpdv) { return; }
|
||||
auto* qgiv(dynamic_cast<QGIView*>(vpdv->getQView()));
|
||||
if (!qgiv) { return; }
|
||||
QPointF bvPos = qgiv->pos();
|
||||
Base::Vector2d bvPt(bvPos.x(), bvPos.y());
|
||||
Base::Vector2d mPt(mPos.x(), mPos.y());
|
||||
Base::Vector2d dir(dir3d.x, dir3d.y);
|
||||
if (dir.Length() < Precision::Confusion()) { return; }
|
||||
dir.Normalize();
|
||||
|
||||
double snapDist = bSize * snapPercent;
|
||||
|
||||
Base::Vector2d projPt;
|
||||
projPt.ProjectToLine(mPt - bvPt, dir);
|
||||
projPt = projPt + bvPt;
|
||||
|
||||
Base::Vector2d v = (projPt - bvPt) + 0.5 * (sSize - bSize) * dir;
|
||||
int sign = v * dir > 0 ? - 1 : 1;
|
||||
double dist = v.Length();
|
||||
if (dist < snapDist) {
|
||||
v = dist * dir;
|
||||
mPos = mPos + sign * QPointF(v.x, v.y);
|
||||
return;
|
||||
}
|
||||
|
||||
v = (projPt - bvPt) + 0.5 * (bSize - sSize) * dir;
|
||||
sign = v * dir > 0 ? - 1 : 1;
|
||||
dist = v.Length();
|
||||
if (dist < snapDist) {
|
||||
v = dist * dir;
|
||||
mPos = mPos + sign * QPointF(v.x, v.y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* view : views) {
|
||||
if (view == this) { continue; }
|
||||
|
||||
QPointF vPos = view->pos();
|
||||
qreal dx = view->boundingRect().width() * snapPercent;
|
||||
qreal dy = view->boundingRect().height() * snapPercent;
|
||||
if (fabs(pos.x() - vPos.x()) < dx) {
|
||||
pos.setX(vPos.x());
|
||||
if (fabs(mPos.x() - vPos.x()) < dx) {
|
||||
mPos.setX(vPos.x());
|
||||
break;
|
||||
}
|
||||
else if (fabs(pos.y() - vPos.y()) < dy) {
|
||||
pos.setY(vPos.y());
|
||||
else if (fabs(mPos.y() - vPos.y()) < dy) {
|
||||
mPos.setY(vPos.y());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ public:
|
||||
void isInnerView(bool state) { m_innerView = state; }
|
||||
QGIViewClip* getClipGroup();
|
||||
|
||||
bool isSnapping() { return snapping; }
|
||||
void snapPosition(QPointF& position);
|
||||
|
||||
void alignTo(QGraphicsItem*, const QString &alignment);
|
||||
@@ -182,6 +183,7 @@ private:
|
||||
QHash<QString, QGraphicsItem*> alignHash;
|
||||
bool m_innerView; //View is inside another View
|
||||
bool m_multiselectActivated;
|
||||
bool snapping;
|
||||
|
||||
QPen m_pen;
|
||||
QBrush m_brush;
|
||||
|
||||
@@ -227,7 +227,7 @@ void ViewProviderDrawingView::updateData(const App::Property* prop)
|
||||
if (prop == &obj->X
|
||||
|| prop == &obj->Y) {
|
||||
QGIView* qgiv = getQView();
|
||||
if (qgiv) {
|
||||
if (qgiv && !qgiv->isSnapping()) {
|
||||
qgiv->QGIView::updateView(true);
|
||||
|
||||
// Update also the owner/parent view, if there is any
|
||||
|
||||
Reference in New Issue
Block a user