[PD] add tooltip for Hole feature
- tooltip makes clear what the depth means for countersinks - add comment why a calculation cannot be performed - shorten some long lines
This commit is contained in:
@@ -1654,7 +1654,6 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
{
|
||||
TopoDS_Shape profileshape;
|
||||
try {
|
||||
|
||||
profileshape = getVerifiedFace();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
@@ -1684,7 +1683,8 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
base.Move(invObjLoc);
|
||||
|
||||
if (profileshape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Hole error: Creating a face from sketch failed");
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"Hole error: Creating a face from sketch failed");
|
||||
profileshape.Move(invObjLoc);
|
||||
|
||||
/* Build the prototype hole */
|
||||
@@ -1708,7 +1708,8 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
length = getThroughAllLength();
|
||||
}
|
||||
else
|
||||
return new App::DocumentObjectExecReturn("Hole error: Unsupported length specification");
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"Hole error: Unsupported length specification");
|
||||
|
||||
if (length <= 0.0)
|
||||
return new App::DocumentObjectExecReturn("Hole error: Invalid hole depth");
|
||||
@@ -1722,7 +1723,8 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
isDynamicCounterbore(threadType, holeCutType));
|
||||
bool isCounterdrill = (holeCutType == "Counterdrill");
|
||||
|
||||
double TaperedAngleVal = Tapered.getValue() ? Base::toRadians(TaperedAngle.getValue()) : Base::toRadians(90.0);
|
||||
double TaperedAngleVal =
|
||||
Tapered.getValue() ? Base::toRadians(TaperedAngle.getValue()) : Base::toRadians(90.0);
|
||||
double radiusBottom = Diameter.getValue() / 2.0 - length / tan(TaperedAngleVal);
|
||||
|
||||
double radius = Diameter.getValue() / 2.0;
|
||||
@@ -1740,23 +1742,29 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
double holeCutDepth = HoleCutDepth.getValue();
|
||||
double countersinkAngle = Base::toRadians(HoleCutCountersinkAngle.getValue() / 2.0);
|
||||
|
||||
if ( isCounterbore) {
|
||||
// Counterbore is rendered the same way as a countersink, but with a hardcoded angle of 90deg
|
||||
if (isCounterbore) {
|
||||
// Counterbore is rendered the same way as a countersink, but with a hardcoded
|
||||
// angle of 90deg
|
||||
countersinkAngle = Base::toRadians(90.0);
|
||||
}
|
||||
|
||||
if ( isCountersink) {
|
||||
holeCutDepth = 0;
|
||||
if (isCountersink) {
|
||||
holeCutDepth = 0.0;
|
||||
// We cannot recalculate the HoleCutDiameter because the previous HoleCutDepth
|
||||
// is unknown. Therefore we cannot know with what HoleCutDepth the current
|
||||
// HoleCutDiameter was calculated.
|
||||
}
|
||||
|
||||
if (holeCutRadius < radius)
|
||||
return new App::DocumentObjectExecReturn("Hole error: Hole cut diameter too small");
|
||||
|
||||
if (holeCutDepth > length)
|
||||
return new App::DocumentObjectExecReturn("Hole error: Hole cut depth must be less than hole depth");
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"Hole error: Hole cut depth must be less than hole depth");
|
||||
|
||||
if (holeCutDepth < 0.0)
|
||||
return new App::DocumentObjectExecReturn("Hole error: Hole cut depth must be greater or equal to zero");
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"Hole error: Hole cut depth must be greater or equal to zero");
|
||||
|
||||
// Top point
|
||||
gp_Pnt newPoint = toPnt(holeCutRadius * xDir);
|
||||
@@ -1772,7 +1780,8 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
|
||||
// Compute intersection of tapered edge and line at bottom of counterbore hole
|
||||
computeIntersection(gp_Pnt(holeCutRadius, -holeCutDepth, 0 ),
|
||||
gp_Pnt(holeCutRadius - sin(countersinkAngle), -cos(countersinkAngle) - holeCutDepth, 0),
|
||||
gp_Pnt(holeCutRadius - sin(countersinkAngle),
|
||||
-cos(countersinkAngle) - holeCutDepth, 0),
|
||||
gp_Pnt(radius, 0, 0),
|
||||
gp_Pnt(radiusBottom, -length, 0), xPosCounter, zPosCounter);
|
||||
|
||||
@@ -1897,7 +1906,8 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
|
||||
int solidCount = countSolids(base);
|
||||
if (solidCount > 1) {
|
||||
return new App::DocumentObjectExecReturn("Hole: Result has multiple solids. This is not supported at this time.");
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"Hole: Result has multiple solids. This is not supported at this time.");
|
||||
}
|
||||
|
||||
this->Shape.setValue(base);
|
||||
@@ -1905,9 +1915,11 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
if (std::string(e.GetMessageString()) == "TopoDS::Face" &&
|
||||
(std::string(DepthType.getValueAsString()) == "UpToFirst" || std::string(DepthType.getValueAsString()) == "UpToFace"))
|
||||
return new App::DocumentObjectExecReturn("Could not create face from sketch.\n"
|
||||
if (std::string(e.GetMessageString()) == "TopoDS::Face"
|
||||
&& (std::string(DepthType.getValueAsString()) == "UpToFirst"
|
||||
|| std::string(DepthType.getValueAsString()) == "UpToFace"))
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"Could not create face from sketch.\n"
|
||||
"Intersecting sketch entities or multiple faces in a sketch are not allowed "
|
||||
"for making a pocket up to a face.");
|
||||
else
|
||||
@@ -1918,7 +1930,8 @@ App::DocumentObjectExecReturn* Hole::execute()
|
||||
}
|
||||
}
|
||||
|
||||
void Hole::rotateToNormal(const gp_Dir& helixAxis, const gp_Dir& normalAxis, TopoDS_Shape& helixShape) const
|
||||
void Hole::rotateToNormal(const gp_Dir& helixAxis, const gp_Dir& normalAxis,
|
||||
TopoDS_Shape& helixShape) const
|
||||
{
|
||||
auto getRotationAxis = [](const gp_Dir& dir1, const gp_Dir& dir2, gp_Dir& dir3, double& angle) {
|
||||
if (dir1.IsEqual(dir2, Precision::Angular()))
|
||||
@@ -1966,12 +1979,14 @@ gp_Vec Hole::computePerpendicular(const gp_Vec& zDir) const
|
||||
else
|
||||
xDir = gp_Vec(0, -zDir.Z(), zDir.Y());
|
||||
|
||||
// Normalize xDir; this is needed as the computation above does not necessarily give a unit-length vector.
|
||||
// Normalize xDir; this is needed as the computation above does not necessarily give
|
||||
// a unit-length vector.
|
||||
xDir.Normalize();
|
||||
return xDir;
|
||||
}
|
||||
|
||||
TopoDS_Compound Hole::findHoles(const TopoDS_Shape& profileshape, const TopoDS_Shape& protohole) const
|
||||
TopoDS_Compound Hole::findHoles(const TopoDS_Shape& profileshape,
|
||||
const TopoDS_Shape& protohole) const
|
||||
{
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound holes;
|
||||
@@ -2021,11 +2036,11 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
|
||||
// this is the same for all metric and UTS threads as stated here:
|
||||
// https://en.wikipedia.org/wiki/File:ISO_and_UTS_Thread_Dimensions.svg
|
||||
// Note that in the ISO standard, Dmaj is called D, which has been followed here.
|
||||
double D = threadDescription[threadType][threadSize].diameter; // Major diameter
|
||||
double P = getThreadPitch();
|
||||
double H = sqrt(3) / 2 * P; // Height of fundamental triangle
|
||||
double Diam = threadDescription[threadType][threadSize].diameter; // major diameter
|
||||
double Pitch = getThreadPitch();
|
||||
double H = sqrt(3) / 2 * Pitch; // height of fundamental triangle
|
||||
|
||||
double clearance; // clearance to be added on the diameter
|
||||
double clearance; // clearance to be added on the diameter
|
||||
if (UseCustomThreadClearance.getValue())
|
||||
clearance = CustomThreadClearance.getValue();
|
||||
else
|
||||
@@ -2034,12 +2049,12 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
|
||||
// construct the cross section going counter-clockwise
|
||||
// for graphical explanation of geometrical construction of p1-p6 see:
|
||||
// https://forum.freecadweb.org/viewtopic.php?f=19&t=54284#p466570
|
||||
gp_Pnt p1 = toPnt((D / 2 - 5 * H / 8 + clearance / 2) * xDir + P / 8 * zDir);
|
||||
gp_Pnt p2 = toPnt((D / 2 + clearance / 2) * xDir + 7 * P / 16 * zDir);
|
||||
gp_Pnt p3 = toPnt((D / 2 + clearance / 2) * xDir + 9 * P / 16 * zDir);
|
||||
gp_Pnt p4 = toPnt((D / 2 - 5 * H / 8 + clearance / 2) * xDir + 7 * P / 8 * zDir);
|
||||
gp_Pnt p5 = toPnt(0.9 * (D / 2 - 5 * H / 8) * xDir + 7 * P / 8 * zDir);
|
||||
gp_Pnt p6 = toPnt(0.9 * (D / 2 - 5 * H / 8) * xDir + P / 8 * zDir);
|
||||
gp_Pnt p1 = toPnt((Diam / 2 - 5 * H / 8 + clearance / 2) * xDir + Pitch / 8 * zDir);
|
||||
gp_Pnt p2 = toPnt((Diam / 2 + clearance / 2) * xDir + 7 * Pitch / 16 * zDir);
|
||||
gp_Pnt p3 = toPnt((Diam / 2 + clearance / 2) * xDir + 9 * Pitch / 16 * zDir);
|
||||
gp_Pnt p4 = toPnt((Diam / 2 - 5 * H / 8 + clearance / 2) * xDir + 7 * Pitch / 8 * zDir);
|
||||
gp_Pnt p5 = toPnt(0.9 * (Diam / 2 - 5 * H / 8) * xDir + 7 * Pitch / 8 * zDir);
|
||||
gp_Pnt p6 = toPnt(0.9 * (Diam / 2 - 5 * H / 8) * xDir + Pitch / 8 * zDir);
|
||||
|
||||
BRepBuilderAPI_MakeWire mkThreadWire;
|
||||
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge());
|
||||
@@ -2053,7 +2068,7 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
|
||||
|
||||
//create the helix path
|
||||
double threadDepth = ThreadDepth.getValue();
|
||||
double helixLength = threadDepth + P / 2;
|
||||
double helixLength = threadDepth + Pitch / 2;
|
||||
double holeDepth = Depth.getValue();
|
||||
std::string threadDepthMethod(ThreadDepthType.getValueAsString());
|
||||
std::string depthMethod(DepthType.getValueAsString());
|
||||
@@ -2061,28 +2076,28 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
|
||||
if (depthMethod == "ThroughAll") {
|
||||
threadDepth = length;
|
||||
ThreadDepth.setValue(threadDepth);
|
||||
helixLength = threadDepth + 2 * P;
|
||||
helixLength = threadDepth + 2 * Pitch;
|
||||
}
|
||||
else if (threadDepthMethod == "Tapped (DIN76)") {
|
||||
threadDepth = holeDepth - getThreadRunout();
|
||||
ThreadDepth.setValue(threadDepth);
|
||||
helixLength = threadDepth + P / 2;
|
||||
helixLength = threadDepth + Pitch / 2;
|
||||
}
|
||||
else { // Hole depth
|
||||
threadDepth = holeDepth;
|
||||
ThreadDepth.setValue(threadDepth);
|
||||
helixLength = threadDepth + P / 8;
|
||||
helixLength = threadDepth + Pitch / 8;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (depthMethod == "Dimension") {
|
||||
// the thread must not be deeper than the hole
|
||||
// thus the max helixLength is holeDepth + P / 8;
|
||||
if (threadDepth > (holeDepth - P / 2))
|
||||
helixLength = holeDepth + P / 8;
|
||||
if (threadDepth > (holeDepth - Pitch / 2))
|
||||
helixLength = holeDepth + Pitch / 8;
|
||||
}
|
||||
}
|
||||
TopoDS_Shape helix = TopoShape().makeLongHelix(P, helixLength, D / 2, 0.0, leftHanded);
|
||||
TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Diam / 2, 0.0, leftHanded);
|
||||
|
||||
gp_Pnt origo(0.0, 0.0, 0.0);
|
||||
gp_Dir dir_axis1(0.0, 0.0, 1.0); // pointing along the helix axis, as created.
|
||||
|
||||
@@ -456,7 +456,7 @@ void TaskHoleParameters::holeCutDepthChanged(double value)
|
||||
|
||||
// store current depth
|
||||
double DepthDifference = value - pcHole->HoleCutDepth.getValue();
|
||||
// new diameter is the old one + 2*tan(angle/2)*DepthDifference
|
||||
// new diameter is the old one + 2 * tan(angle / 2) * DepthDifference
|
||||
double newDiameter = pcHole->HoleCutDiameter.getValue()
|
||||
+ 2 * tan(Base::toRadians(pcHole->HoleCutCountersinkAngle.getValue() / 2)) * DepthDifference;
|
||||
// only apply if the result is not smaller than the hole diameter
|
||||
|
||||
@@ -535,6 +535,10 @@ Only available for holes without thread</string>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>For countersinks this is the depth of
|
||||
the screw's top below the surface</string>
|
||||
</property>
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user