* [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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -138,6 +138,9 @@ public:
|
||||
|
||||
static bool useCameraDirection();
|
||||
static bool alwaysShowLabel();
|
||||
|
||||
static bool SnapViews();
|
||||
static double SnapLimitFactor();
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user