Build helix in OpenCascade

Quaoar

Administrator
Staff member
So I took the code from the guy who asked the question and modified it to the following state:

Code:
  const double d         = 30;
  const double r         = 5;
  const int    fullTurns = 10;
  const double pitch     = 3;

  gp_Pnt center = gp::Origin();
  gp_Dir axis   = gp::DZ();

  Handle(Geom_CylindricalSurface)
    cyl = new Geom_CylindricalSurface(gp_Ax2(center, axis), r);

  gp_Lin2d                    helixLine(gp::Origin2d(), gp_Dir2d(r, pitch));
  Handle(Geom2d_TrimmedCurve) segs = GCE2d_MakeSegment(helixLine, 0, 2.0 * M_PI).Value();
  TopoDS_Edge                 helixEdge = BRepBuilderAPI_MakeEdge(segs,
                                                                  cyl,
                                                                  0,
                                                                  fullTurns * 2 * M_PI);

I did not touch it a lot, although it might be that I corrupted the original logic. Still, it kinda works and can be considered as a somewhat minimal example. Here's the picture:

1635968270665.png
Some more advanced helixes can be constructed with some more advanced approaches. I'll post them here if there's an interest in that subject.
 

Quaoar

Administrator
Staff member
One interesting observation regarding the previous example is that the constructed edge does not contain a 3D curve:

1635972658785.png

It's a pure UV-living entity that we see in the 3D scene because the visualization logic can handle such cases and derive the polygonal representation out of the 2D curve and S(u,v) formula for the surface (a cylinder). Therefore, it's not as valid as you might want it to be:

1635973070837.png
 
Last edited:

JSlyadne

Administrator
Staff member
One interesting observation regarding the previous example is that the constructed edge does not contain a 3D curve:

Out of curiosity there are a couple of questions. I didn't deal much either with geometry or visualization stuff so my apologies if you find the questions "primitive". So here they are:

Is it expected outcome that 3D curve is missing or not?

Is there a way to build the 3D curve at the end?

Does "visualization logic can handle such cases" mean the logic realized somewhere in your software, and so it will be normally displayed only there, or there is a low level support at, let's say, OpenGl level for such cases, and so other viewers will be also Ok?
 

DanB

CAD community veteran
One interesting observation regarding the previous example is that the constructed edge does not contain a 3D curve:

View attachment 109

It's a pure UV-living entity that we see in the 3D scene because the visualization logic can handle such cases and derive the polygonal representation out of the 2D curve and S(u,v) formula for the surface (a cylinder). Therefore, it's not as valid as you might want it to be:

View attachment 110
Interesting, so it's only the projection that you are visualizing - not what is projected onto, hence no 3D curve is defined?
 
Last edited:

Quaoar

Administrator
Staff member
Is it expected outcome that 3D curve is missing or not?
Yes and no. I'd say it is expected if you've been working with OpenCascade for years. Still, after a decade with the lib, it was not so expected for me. But once I saw it, I understood why this happens. The cause is that 2D to 3D mapping requires approximation, and that is not something you might want to have automatically, because of possible precision issues and performance overheads.

Is there a way to build the 3D curve at the end?
One pretty straightforward way of doing this is to run shape healing, e.g., like this:

Code:
ShapeFix_Edge sae;
sae.FixAddCurve3d(helixEdge);

Look at this wormlike spline that it builds for you:

1636130120526.png

I'm sure there's a way to build a 3D curve in a more "regular" way, i.e. without these woozy control points positions, but the shape is satisfactory, and it looks good enough. If you follow the original discussion on the OCC forum, you'll see that Roman proposes AdvApprox package to build this 3D curve manually. I'm pretty sure that the shape healing function that I used above is doing the same sort of thing.

Does "visualization logic can handle such cases" mean the logic realized somewhere in your software, and so it will be normally displayed only there, or there is a low level support at, let's say, OpenGl level for such cases, and so other viewers will be also Ok?
Having such edges without 3D reps is, let's say, "mathematically enough" as you can evaluate your surface S(u,v) along the 2D curve and this would yield a perfectly three-dimensional point. So, the 3D representation is kind of implicitly encoded in the surface equation plus pcurve equation. To answer your question, yes, treating such edges properly requires something at the level of your visualization code. To be specific, you need to have a discretizer that is able to generate a polyline from such a "seemingly incomplete" edge definition.

Interesting, so it's only the projection that you are visualizing - not what is projected onto, hence no 3D curve is defined?
Is a 3D polyline visualized, but the code that prepares this polyline is kind of aware that an edge might not have a 3D curve. In such cases, the polygonizer should evaluate S(c2d(t)), where c2d is a pcurve and S is the surface (cylinder here).

All these curve and surface evaluations make precise CAD kernels so exciting, as they naturally bring numerical methods and differential geometry into play. These are the classy things that people have been investigating since the times of Euler, Gauss, Klein, Poincare, etc., etc.
 
Last edited:

DanB

CAD community veteran
Is a 3D polyline visualized, but the code that prepares this polyline is kind of aware that an edge might not have a 3D curve. In such cases, the polygonizer should evaluate S(c2d(t)), where c2d is a pcurve and S is the surface (cylinder here).

All these curve and surface evaluations make precise CAD kernels so exciting, as they naturally bring numerical methods and differential geometry into play. These are the classy things that people have been investigating since the times of Euler, Gauss, Klein, Poincare, etc., etc.
So basically the curve is isometric to r(t) = t in R2.

I do agree, it's neat. You learn in mathematics that programming is where you get your hands dirty - but CAD kernels have mathematical elegance to them.
 
Top