From 169c38622c1f6358e4f8303a5b8a569fbd0d3faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20B=C3=A4hr?= Date: Wed, 24 Nov 2021 22:29:36 +0100 Subject: [PATCH] [PD] Helix: Offer profile's normal as axis Previously, only the vertical and horizontal axis of the profile was selectable in the task panel of the additive/subtractive helix. Now the profile's normal axis can be selected, too. This now allows to create helical extrusions or "twisted pockets". The order of the GUI entries was chosen to be in line with the order of axis selection of the multi-transform parameters. The actual feature's implementation needed adaption for this special case as in some places a unit vector (`gp_Dir`) was derived from the cross- product of axis and profile normal -- a null-vector when the axis *is* the normal. This caused the gp_Dir's ctor to throw. --- src/Mod/PartDesign/App/FeatureHelix.cpp | 23 ++++++++++++++++--- .../PartDesign/Gui/TaskHelixParameters.cpp | 1 + src/Mod/PartDesign/Gui/TaskHelixParameters.ui | 5 ++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureHelix.cpp b/src/Mod/PartDesign/App/FeatureHelix.cpp index a6fdedac22..5d6b6c8c54 100644 --- a/src/Mod/PartDesign/App/FeatureHelix.cpp +++ b/src/Mod/PartDesign/App/FeatureHelix.cpp @@ -371,6 +371,20 @@ TopoDS_Shape Helix::generateHelixPath(void) Base::Vector3d normal = getProfileNormal(); Base::Vector3d start = v.Cross(normal); // pointing towards the desired helix start point. + + // if our axis is (nearly) aligned with the profile's normal, we're only interested in the "twist" + // of the helix. The actual starting point, and thus the radius, isn't important as long as it's + // somewhere in the profile's plane: an arbitrary vector perpendicular to the normal. + if (start.IsNull()) { + auto hopefullyNotParallel = Base::Vector3d(1.0, 2.0, 3.0); + start = normal.Cross(hopefullyNotParallel); + if (start.IsNull()) { + // bad luck + hopefullyNotParallel = Base::Vector3d(3.0, 2.0, 1.0); + start = normal.Cross(hopefullyNotParallel); + } + } + gp_Dir dir_start(start.x, start.y, start.z); // Find out in what quadrant relative to the axis the profile is located, and the exact position. @@ -447,6 +461,12 @@ TopoDS_Shape Helix::generateHelixPath(void) // this function calculates self intersection safe pitch based on the profile bounding box. double Helix::safePitch() { + Base::Vector3d v = Axis.getValue(); + Base::Vector3d n = getProfileNormal(); + Base::Vector3d s = v.Cross(n); // pointing towards the desired helix start point. + if (s.IsNull()) + return Precision::Confusion(); // if the axis orthogonal to the profile, any pitch >0 is safe + // Below is an approximation. It is possible to do the general way by solving for the pitch // where the helix is self intersecting. @@ -461,14 +481,11 @@ double Helix::safePitch() double X = Xmax - Xmin, Y = Ymax - Ymin, Z = Zmax - Zmin; - Base::Vector3d v = Axis.getValue(); gp_Dir dir(v.x,v.y,v.z); gp_Vec bbvec(X, Y, Z); double p0 = bbvec*dir; // safe pitch if angle=0 - Base::Vector3d n = getProfileNormal(); - Base::Vector3d s = v.Cross(n); // pointing towards the desired helix start point. gp_Dir dir_s(s.x, s.y, s.z); if (tan(abs(angle))*p0 > abs(bbvec*dir_s)) diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp index 029a63c661..85df9c4c39 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.cpp @@ -202,6 +202,7 @@ void TaskHelixParameters::fillAxisCombo(bool forceRefill) PartDesign::ProfileBased* pcFeat = static_cast(vp->getObject()); Part::Part2DObject* pcSketch = dynamic_cast(pcFeat->Profile.getValue()); if (pcSketch){ + addAxisToCombo(pcSketch,"N_Axis",QObject::tr("Normal sketch axis")); addAxisToCombo(pcSketch,"V_Axis",QObject::tr("Vertical sketch axis")); addAxisToCombo(pcSketch,"H_Axis",QObject::tr("Horizontal sketch axis")); for (int i=0; i < pcSketch->getAxisCount(); i++) { diff --git a/src/Mod/PartDesign/Gui/TaskHelixParameters.ui b/src/Mod/PartDesign/Gui/TaskHelixParameters.ui index 6d57f9d6a4..ae8efc5c19 100644 --- a/src/Mod/PartDesign/Gui/TaskHelixParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHelixParameters.ui @@ -70,6 +70,11 @@ Vertical sketch axis + + + Normal sketch axis + + Select reference...