[TD]Fix section snapping (fix #15961) (#15450)

* [TD]Add view snapping preferences

* [TD]fix section snapping algo

- snap sections to section normal line.
- snap views to other views in X&Y

* [TD]fix snapping to ProjectionGroups
This commit is contained in:
WandererFan
2024-09-02 12:41:25 -04:00
committed by GitHub
parent 77539c1091
commit e852052df8
12 changed files with 404 additions and 119 deletions

View File

@@ -271,6 +271,37 @@ double DrawUtil::incidenceAngleAtVertex(TopoDS_Edge e, TopoDS_Vertex v, double t
return incidenceAngle;
}
//! true if actualAngle(degrees) is within allowableError [0,360] of
//! targetAngle (degrees)
bool DrawUtil::isWithinRange(double actualAngleIn, double targetAngleIn, double allowableError)
{
constexpr double DegreesPerRevolution{360};
constexpr double DegreesPerHalfRevolution{180};
// map both angles from [0, 360] to [-180, 180]. This solves the problem of
// comparing angles near 0, such as 5deg & 355deg where the desired answer is
// 10, not 350;
double actualAngleDeg = actualAngleIn;
if (actualAngleDeg < DegreesPerRevolution &&
actualAngleDeg > DegreesPerHalfRevolution) {
actualAngleDeg = actualAngleDeg - DegreesPerRevolution;
}
double targetAngleDeg = targetAngleIn;
if (targetAngleDeg < DegreesPerRevolution &&
targetAngleDeg > DegreesPerHalfRevolution) {
targetAngleDeg = targetAngleDeg - DegreesPerRevolution;
}
double actualError = fabs(targetAngleDeg - actualAngleDeg);
if (actualError <= allowableError) {
return true;
}
return false;
}
bool DrawUtil::isFirstVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance)
{
TopoDS_Vertex first = TopExp::FirstVertex(e);

View File

@@ -275,6 +275,9 @@ public:
static Base::Vector3d toAppSpace(const DrawViewPart& dvp, const Base::Vector3d& inPoint);
static Base::Vector3d toAppSpace(const DrawViewPart& dvp, const QPointF& inPoint);
static bool isWithinRange(double actualAngleIn, double targetAngleIn, double allowableError);
//debugging routines
static void dumpVertexes(const char* text, const TopoDS_Shape& s);
static void dumpEdge(const char* label, int i, TopoDS_Edge e);

View File

@@ -42,9 +42,10 @@
#include "DrawUtil.h"
#include "DrawViewClip.h"
#include "DrawViewCollection.h"
#include "DrawProjGroup.h"
#include "DrawProjGroupItem.h"
#include "Preferences.h"
using namespace TechDraw;
using DU = DrawUtil;
@@ -652,6 +653,22 @@ void DrawView::setScaleAttribute()
}
}
//! due to changes made for the "intelligent" view creation tool, testing for a view being an
//! instance of DrawProjGroupItem is no longer reliable, as views not in a group are sometimes
//! created as DrawProjGroupItem without belonging to a group. We now need to test for the existance
//! of the parent DrawProjGroup
bool DrawView::isProjGroupItem(DrawViewPart* item)
{
auto dpgi = dynamic_cast<DrawProjGroupItem*>(item);
if (!dpgi) {
return false;
}
auto group = dpgi->getPGroup();
if (!group) {
return false;
}
return true;
}
int DrawView::prefScaleType()
{
return Preferences::getPreferenceGroup("General")->GetInt("DefaultScaleType", 0);

View File

@@ -40,7 +40,7 @@ class DrawPage;
class DrawViewCollection;
class DrawViewClip;
class DrawLeaderLine;
/*class CosmeticVertex;*/
class DrawViewPart;
/** Base class of all View Features in the drawing module
*/
@@ -123,6 +123,8 @@ public:
virtual App::PropertyLink *getOwnerProperty() { return nullptr; }
static bool isProjGroupItem(DrawViewPart* item);
protected:
void onBeforeChange(const App::Property *prop) override;
void onChanged(const App::Property* prop) override;

View File

@@ -80,6 +80,7 @@
#include <Base/Console.h>
#include <Base/FileInfo.h>
#include <Base/Parameter.h>
#include <Base/Tools.h>
#include <Mod/Part/App/PartFeature.h>
@@ -1152,21 +1153,15 @@ gp_Ax2 DrawViewSection::getSectionCS() const
return sectionCS;
}
gp_Ax2 DrawViewSection::getProjectionCS(const Base::Vector3d pt) const
//! return the center of the shape resulting from the cut operation
Base::Vector3d DrawViewSection::getCutCentroid() const
{
Base::Vector3d vNormal = SectionNormal.getValue();
gp_Dir gNormal(vNormal.x, vNormal.y, vNormal.z);
Base::Vector3d vXDir = getXDirection();
gp_Dir gXDir(vXDir.x, vXDir.y, vXDir.z);
if (DrawUtil::fpCompare(fabs(gNormal.Dot(gXDir)), 1.0)) {
// can not build a gp_Ax2 from these values
throw Base::RuntimeError(
"DVS::getProjectionCS - SectionNormal and XDirection are parallel");
}
gp_Pnt gOrigin(pt.x, pt.y, pt.z);
return {gOrigin, gNormal, gXDir};
gp_Pnt inputCenter = ShapeUtils::findCentroid(m_cutPieces, getProjectionCS());
return Base::Vector3d(inputCenter.X(), inputCenter.Y(), inputCenter.Z());
}
std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
{
// Base::Console().Message("DVS::getDrawableLines(%d) - lineSets: %d\n", i, m_lineSets.size());

View File

@@ -134,7 +134,6 @@ public:
virtual TopoDS_Shape getShapeToPrepare() const { return m_cutPieces; }
//CS related methods
gp_Ax2 getProjectionCS(Base::Vector3d pt = Base::Vector3d(0.0, 0.0, 0.0)) const override;
void setCSFromBase(const std::string sectionName);
void setCSFromBase(Base::Vector3d localUnit);
void setCSFromLocalUnit(const Base::Vector3d localUnit);
@@ -172,6 +171,8 @@ public:
TopoDS_Shape makeFaceFromWires(std::vector<TopoDS_Wire> &inWires);
Base::Vector3d getCutCentroid() const;
public Q_SLOTS:
virtual void onSectionCutFinished(void);

View File

@@ -599,3 +599,16 @@ bool Preferences::alwaysShowLabel()
{
return getPreferenceGroup("General")->GetBool("AlwaysShowLabel", false);
}
bool Preferences::SnapViews()
{
return getPreferenceGroup("General")->GetBool("SnapViews", true);
}
//! percentage of view size to use in deciding to snap view or not
double Preferences::SnapLimitFactor()
{
return getPreferenceGroup("General")->GetFloat("SnapLimitFactor", 0.05);
}

View File

@@ -138,6 +138,9 @@ public:
static bool useCameraDirection();
static bool alwaysShowLabel();
static bool SnapViews();
static double SnapLimitFactor();
};