PartDesign: Improve orientation behaviour for conical helices (#5363)

* PartDesign: Improve orientation behavior for conical helices

As identified in the forum
https://forum.freecadweb.org/viewtopic.php?f=3&t=65136

The Freenet orientation mode does not give expected results for helices with cone angle.
By using an auxiliary helix that is axially offset it is guaranteed that the orientation frame
is always consistent with a cylindrical coordinate system.

Results will be the same as before when cone angle is 0.
This commit is contained in:
David Österberg
2022-01-09 22:13:15 +01:00
committed by GitHub
parent f44c683e0e
commit 9c142ccb8b
2 changed files with 13 additions and 6 deletions

View File

@@ -227,6 +227,8 @@ App::DocumentObjectExecReturn* Helix::execute(void)
// generate the helix path
TopoDS_Shape path = generateHelixPath();
TopoDS_Shape auxpath = generateHelixPath(1.0);
std::vector<TopoDS_Wire> wires;
try {
@@ -249,7 +251,9 @@ App::DocumentObjectExecReturn* Helix::execute(void)
mkPS.SetTolerance(Precision::Confusion());
mkPS.SetTransitionMode(BRepBuilderAPI_Transformed);
mkPS.SetMode(true); //This is for frenet
//mkPS.SetMode(true); //This is for frenet
mkPS.SetMode(TopoDS::Wire(auxpath), true); // this is for auxilliary
for (TopoDS_Wire& wire : wires) {
wire.Move(invObjLoc);
@@ -398,7 +402,7 @@ void Helix::updateAxis(void)
Axis.setValue(dir.x, dir.y, dir.z);
}
TopoDS_Shape Helix::generateHelixPath(void)
TopoDS_Shape Helix::generateHelixPath(double startOffset0)
{
double turns = Turns.getValue();
double height = Height.getValue();
@@ -436,8 +440,11 @@ TopoDS_Shape Helix::generateHelixPath(void)
// Find out in what quadrant relative to the axis the profile is located, and the exact position.
Base::Vector3d profileCenter = getProfileCenterPoint();
double axisOffset = profileCenter * start - b * start;
double startOffset = profileCenter * v - b * v;
// The factor of 100 below ensures that profile size is small compared to the curvature of the helix.
// This improves the issue reported in https://forum.freecadweb.org/viewtopic.php?f=10&t=65048
double axisOffset = 100 * (profileCenter * start - b * start);
double startOffset = startOffset0 + profileCenter * v - b * v;
double radius = std::fabs(axisOffset);
bool turned = axisOffset < 0;
@@ -445,7 +452,7 @@ TopoDS_Shape Helix::generateHelixPath(void)
// in this case ensure that axis is not in the sketch plane
if (std::fabs(v * normal) < Precision::Confusion())
throw Base::ValueError("Error: Result is self intersecting");
radius = 1.0; //fallback to radius 1
radius = 1000.0; //fallback to radius 1000
}
bool growthMode = std::string(Mode.getValueAsString()).find("growth") != std::string::npos;

View File

@@ -80,7 +80,7 @@ protected:
void updateAxis(void);
/// generate helix and move it to the right location.
TopoDS_Shape generateHelixPath(void);
TopoDS_Shape generateHelixPath(double startOffset0 = 0.0);
// project shape on plane. Used for detecting self intersection.
TopoDS_Shape projectShape(const TopoDS_Shape& input, const gp_Ax2& plane);