refactor(PD): new cut profile for threads

fixes tapered threds
removing 2 points increases performance around 10% when doing an M1 in my imprecise testing
This commit is contained in:
Alfredo Monclus
2024-08-05 19:16:14 -03:00
parent 3e161f9c96
commit 80d4185c09

View File

@@ -2204,8 +2204,8 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
// Nomenclature and formulae according to Figure 1 of ISO 68-1
// 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.
double Dmaj = threadDescription[threadType][threadSize].diameter / 2; // major diameter position
// Rmaj is half of the major diameter
double Rmaj = threadDescription[threadType][threadSize].diameter / 2;
double Pitch = getThreadPitch();
double clearance; // clearance to be added on the diameter
@@ -2213,6 +2213,8 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
clearance = CustomThreadClearance.getValue() / 2;
else
clearance = getThreadClassClearance() / 2;
double RmajC = Rmaj + clearance;
double marginZ = 0.001;
BRepBuilderAPI_MakeWire mkThreadWire;
double H;
@@ -2220,47 +2222,70 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
if (threadTypeStr == "BSP") {
H = 0.960491 * Pitch; // Height of Sharp V
double radius = 0.137329 * Pitch; // radius of the crest
double h = 0.640627 * Pitch; // height of the thread
// construct the cross section going counter-clockwise
// --------------
// P | p4
// 5/8P | p3
// | crest
// 3/8P | p2
// 0 | p1
// --------------
// | base-sharpV Rmaj H
gp_Pnt p1 = toPnt((Dmaj - h + clearance) * xDir + Pitch / 8 * zDir);
gp_Pnt p4 = toPnt((Dmaj - h + clearance) * xDir + 7 * Pitch / 8 * zDir);
gp_Pnt p5 = toPnt(0.9 * (Dmaj - h) * xDir + 7 * Pitch / 8 * zDir);
gp_Pnt p6 = toPnt(0.9 * (Dmaj - h) * xDir + Pitch / 8 * zDir);
// the little adjustment of p1 and p4 is here to prevent coincidencies
double marginX = std::tan(62.5 * M_PI / 180.0) * marginZ;
// Calculate positions for p2 and p3 based on the arc radius
double p23x = Dmaj + clearance - radius * (1 - std::cos(M_PI / 4));
gp_Pnt p1 = toPnt(
(RmajC - 5 * H / 6 + marginX) * xDir
+ marginZ * zDir
);
gp_Pnt p4 = toPnt(
(RmajC - 5 * H / 6 + marginX) * xDir
+ (Pitch - marginZ) * zDir
);
gp_Pnt p2 = toPnt(p23x * xDir + 7 * Pitch / 16 * zDir);
gp_Pnt p3 = toPnt(p23x * xDir + 9 * Pitch / 16 * zDir);
gp_Pnt crest = toPnt((Dmaj + clearance) * xDir + Pitch / 2 * zDir);
// Calculate positions for p2 and p3
double p23x = RmajC - radius * 0.58284013094;
gp_Pnt p2 = toPnt(p23x * xDir + 3 * Pitch / 8 * zDir);
gp_Pnt p3 = toPnt(p23x * xDir + 5 * Pitch / 8 * zDir);
gp_Pnt crest = toPnt((RmajC) * xDir + Pitch / 2 * zDir);
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge());
Handle(Geom_TrimmedCurve) arc1 = GC_MakeArcOfCircle(p2, crest, p3).Value();
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(arc1).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p1).Edge());
} else {
H = sqrt(3) / 2 * Pitch; // height of fundamental triangle
double h = 5 * H / 8; // height of the thread
double h = 7 * H / 8; // distance from Rmaj to the base
// construct the cross section going counter-clockwise
// for graphical explanation of geometrical construction of p1-p6 see:
// https://forum.freecad.org/viewtopic.php?f=19&t=54284#p466570
gp_Pnt p1 = toPnt((Dmaj - h + clearance) * xDir + Pitch / 8 * zDir);
gp_Pnt p2 = toPnt((Dmaj + clearance) * xDir + 7 * Pitch / 16 * zDir);
gp_Pnt p3 = toPnt((Dmaj + clearance) * xDir + 9 * Pitch / 16 * zDir);
gp_Pnt p4 = toPnt((Dmaj - h + clearance) * xDir + 7 * Pitch / 8 * zDir);
gp_Pnt p5 = toPnt(0.9 * (Dmaj - h) * xDir + 7 * Pitch / 8 * zDir);
gp_Pnt p6 = toPnt(0.9 * (Dmaj - h) * xDir + Pitch / 8 * zDir);
// pitch
// --------------
// P | p4
// 9/16P | p3
// 7/16P | p2
// 0 | p1
// --------------
// | base-sharpV Rmaj
// the little adjustment of p1 and p4 is here to prevent coincidencies
double marginX = std::tan(60.0 * M_PI / 180.0) * marginZ;
gp_Pnt p1 = toPnt(
(RmajC - h + marginX) * xDir
+ marginZ * zDir
);
gp_Pnt p2 = toPnt((RmajC) * xDir + 7 * Pitch / 16 * zDir);
gp_Pnt p3 = toPnt((RmajC) * xDir + 9 * Pitch / 16 * zDir);
gp_Pnt p4 = toPnt(
(RmajC - h + marginX) * xDir
+ (Pitch - marginZ) * zDir
);
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p1, p2).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p2, p3).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p3, p4).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p5).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p5, p6).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p6, p1).Edge());
mkThreadWire.Add(BRepBuilderAPI_MakeEdge(p4, p1).Edge());
}
mkThreadWire.Build();
@@ -2299,7 +2324,7 @@ TopoDS_Shape Hole::makeThread(const gp_Vec& xDir, const gp_Vec& zDir, double len
}
double helixAngle =
Tapered.getValue() ? TaperedAngle.getValue() - 90 : 0.0;
TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Dmaj, helixAngle, leftHanded);
TopoDS_Shape helix = TopoShape().makeLongHelix(Pitch, helixLength, Rmaj, helixAngle, 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.