Why does a line with a non-zero V or a cylindrical surface with a non-zero Z generate a non-cylindrical helix?

I am generating a spring as a pipe shell using a circular profile and a cylindrical helix. When I specify a U,V line with a U=0.0,V=0.0 starting point, or a cylindrical surface with a X=0.0,Y=0.0,Z=0.0 origin point (Case1) I get a cylindrical helix as expected. However, when I specify a U,V line with a V>0.0 starting point (Case2), or a cylindrical surface with a Z>0.0 origin point (Case3) I get a pear-shaped/hour-glass shaped helix which is unexpected. Why does a line with a non-zero V or a cylindrical surface with a non-zero Z generate a non-cylindrical helix? In the code below please uncomment/comment the lines with Case1, Case2 or Case3. Thanks for your response.

#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepLib.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepOffsetAPI_MakePipeShell.hxx>
#include <BRepTools.hxx>
#include <GCE2d_MakeLine.hxx>
#include <Geom2d_Line.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Standard_Real.hxx>
#include <StlAPI_Writer.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <iostream>

using namespace std;

int main(int argc, const char * argv[]) {

    Standard_Real profileRadius = 0.05275;
    Standard_Real helixRadius = 0.49725;
    Standard_Real centerHelixCoils = 10.0;
    Standard_Real centerHelixPitch = 0.32289;
    Standard_Real centerHelixHypotenuse = sqrt((2.0 * M_PI * 2.0 * M_PI) + (centerHelixPitch * centerHelixPitch));

    // Create Profile Face
    gp_Ax2 anAxis;
    anAxis.SetDirection(gp_Dir(0.0, -1.0, 0.0));
    anAxis.SetLocation(gp_Pnt(helixRadius, 0.0, 0.0));
    gp_Circ profileCircle(anAxis, profileRadius);
    TopoDS_Edge profileEdge = BRepBuilderAPI_MakeEdge(profileCircle).Edge();
    TopoDS_Wire profileWire = BRepBuilderAPI_MakeWire(profileEdge).Wire();
    TopoDS_Face profileFace = BRepBuilderAPI_MakeFace(profileWire).Face();

    // Create Center Helix
//    Standard_Real v = 0.0, z = 0.0; // Case1: Works
//    Standard_Real v = 0.1055, z = 0.0; // Case2: Fails
    Standard_Real v = 0.0, z = 0.1055; // Case3: Fails
    Handle(Geom2d_Line) centerHelixSegment = GCE2d_MakeLine(gp_Pnt2d(0.0, v), gp_Dir2d(2. * M_PI, centerHelixPitch));
    gp_Ax2 centerHelixOrigin(gp_Pnt(0.0, 0.0, z), gp_Dir(0.0, 0.0, 1.0));
    Handle(Geom_CylindricalSurface) centerHelixCylinder = new Geom_CylindricalSurface(centerHelixOrigin, helixRadius);
    TopoDS_Edge centerHelixEdge = BRepBuilderAPI_MakeEdge(centerHelixSegment, centerHelixCylinder, 0.0, centerHelixCoils * centerHelixHypotenuse).Edge();
    BRepLib::BuildCurve3d(centerHelixEdge);

    // Create Center Helix Wire and Pipe
    TopoDS_Wire helixWire = BRepBuilderAPI_MakeWire(centerHelixEdge).Wire();
    BRepOffsetAPI_MakePipeShell helixPipe(helixWire);
    helixPipe.Add(profileWire, Standard_False, Standard_True);
    helixPipe.Build();
    Standard_Boolean flag = helixPipe.MakeSolid();
    std::cout << "flag=" << (flag==true ? "success" : "fail") << std::endl;

    // Mesh Helix Pipe
    BRepMesh_IncrementalMesh mesh1(helixPipe, 0.05, Standard_False, 0.5, Standard_False );
    Standard_Integer status;
    status = mesh1.GetStatusFlags();
    std::cout << "status=" << status << std::endl;

    // Generate Helix Pipe BREP File
    Standard_Boolean brep_result;
    brep_result = BRepTools::Write(helixPipe, "helixPipe.brep", Standard_False, Standard_False, TopTools_FormatVersion_VERSION_1);
    std::cout << "brep_result=" << (brep_result==true ? "success" : "fail") << std::endl;

    return 0;
}

Regards, Brian D. Watt

Case1 Case2 Case3

Brian Watt's picture

Add source and image files.

Mikhail Sazonov's picture

Hi Brian,

When you give a V or Z a no zero value the profile gets out of center helix line. The pipe algorithm here does not have any constraints that avoid rotation of profile relative the helix wire.

 

So, in order to make the spring right regardless of the value of V and Z you must provide that profile is centered at the beginning of helix wire. You can do this by correcting the following line:

anAxis.SetLocation(gp_Pnt(helixRadius, 0.0, v + z));

Regards,
Mikhail

Brian Watt's picture

Mikhail, Thank you very much. Bri