diff --git a/src/Mod/PartDesign/App/FeatureHole.cpp b/src/Mod/PartDesign/App/FeatureHole.cpp index 39cf3379b5..9ecabdd8b8 100644 --- a/src/Mod/PartDesign/App/FeatureHole.cpp +++ b/src/Mod/PartDesign/App/FeatureHole.cpp @@ -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. diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp index ab2e3c2bf6..c9d4fa60f2 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.cpp @@ -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 diff --git a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui index 1fa1295e8d..002fcff2f5 100644 --- a/src/Mod/PartDesign/Gui/TaskHoleParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskHoleParameters.ui @@ -535,6 +535,10 @@ Only available for holes without thread 0 + + For countersinks this is the depth of +the screw's top below the surface + false