Simple BREP cylinder

Hello Users !

I'm struggling with a simple BREP-defined cylinder..  :-(
I know I could have used somekind of  ' MakeCylinderSurface ' call. But my final target is more complex ( slanted ends ), so this simple cylinder is a starting point for me.

With the code below, I'm sucessful in defining ans visualizing the Wire for the cylindrical face.
But I cannot use that Wire to make the cylinder Face.
Although the Wire seems OK, it doesn't restrict the infinite extand of the underlying cylindrical geometry.
So the face also has infinite extand.

Any help would be greatly appreciated !


 // Left surface.
 gp_Pnt  Left_Vertex_gpPnt(,, );
 // Left Surface Normal.
 gp_Dir  LeftSurface_Normal_gpDir( -Geometry_LeftSurface_Center_GlobalBasis.Nx,     -Geometry_LeftSurface_Center_GlobalBasis.Ny,   -Geometry_LeftSurface_Center_GlobalBasis.Nz );
 // Left Surface Center .
 gp_Pnt  Left_Center_gpPnt( Geometry_LeftSurface_Center_GlobalBasis.X,  Geometry_LeftSurface_Center_GlobalBasis.Y,  Geometry_LeftSurface_Center_GlobalBasis.Z );
 // Basis.
 auto LeftSurface_Axis  = gp_Ax2( Left_Center_gpPnt,  LeftSurface_Normal_gpDir  );
 // Left Underlying Surf.
 Handle(Geom_Circle) LeftCircle_UnderlyingGeom = GC_MakeCircle( LeftSurface_Axis, Cylinder_Radius );

 // Right surface.
 gp_Pnt  Right_Vertex_gpPnt(,, );
 // Right Surface Normal.
 gp_Dir  RightSurface_Normal_gpDir( Geometry_RightSurface_Center_GlobalBasis.Nx, Geometry_RightSurface_Center_GlobalBasis.Ny,  Geometry_RightSurface_Center_GlobalBasis.Nz );
 // Right Surface Vertex.
 gp_Pnt  Right_Center_gpPnt( Geometry_RightSurface_Center_GlobalBasis.X,  Geometry_RightSurface_Center_GlobalBasis.Y,  Geometry_RightSurface_Center_GlobalBasis.Z );
 // Basis.
 auto RightSurface_Axis  = gp_Ax2( Right_Center_gpPnt,  RightSurface_Normal_gpDir  );
 // Right Underlying Surf.
 Handle(Geom_Circle) RightCircle_UnderlyingGeom  = GC_MakeCircle( RightSurface_Axis, Cylinder_Radius );

 // Cylinder.
 Handle(Geom_CylindricalSurface) Cylinder_UnderlyingGeom = GC_MakeCylindricalSurface( LeftSurface_Axis, Cylinder_Radius );
 Handle( Geom_Line )             Line_UnderlyingGeom     = GC_MakeLine( Left_Vertex_gpPnt, Right_Vertex_gpPnt );

 BRep_Builder aBuilder;

 // Vertices.
 TopoDS_Vertex   Left_BREPvertex, Right_BREPvertex;

 aBuilder.MakeVertex( Left_BREPvertex,  Left_Vertex_gpPnt,   Precision::Confusion()  );
 aBuilder.MakeVertex( Right_BREPvertex, Right_Vertex_gpPnt,  Precision::Confusion()  );

 // Edges.
 TopoDS_Edge   Left_Edge  = BRepBuilderAPI_MakeEdge( LeftCircle_UnderlyingGeom,  Left_BREPvertex,   TopoDS::Vertex( Left_BREPvertex.Reversed()  )  );
 TopoDS_Edge   Right_Edge = BRepBuilderAPI_MakeEdge( RightCircle_UnderlyingGeom, Right_BREPvertex,  TopoDS::Vertex( Right_BREPvertex.Reversed() )  );

 TopoDS_Edge   Line_Edge      = BRepBuilderAPI_MakeEdge( Line_UnderlyingGeom,        Left_BREPvertex,   TopoDS::Vertex( Right_BREPvertex.Reversed() )  );

 // Wires.
 TopoDS_Wire Left_Wire  = BRepBuilderAPI_MakeWire( Left_Edge );
 TopoDS_Wire Right_Wire = BRepBuilderAPI_MakeWire( Right_Edge );

 // Cylinder Wire.
 TopoDS_Wire Cyl_Wire;
 aBuilder.MakeWire( Cyl_Wire );
 aBuilder.Add( Cyl_Wire, Left_Edge );
 aBuilder.Add( Cyl_Wire, Line_Edge );
 aBuilder.Add( Cyl_Wire, Right_Edge.Reversed());
 aBuilder.Add( Cyl_Wire, Line_Edge.Reversed());

 // Faces.
 TopoDS_Face Cyl_Face;
 aBuilder.MakeFace( Cyl_Face, Cylinder_UnderlyingGeom, Precision::Confusion());
 aBuilder.Add( Cyl_Face, Cyl_Wire);

Mikhail Sazonov's picture

Your face is incorrect, because it does not contains a boundary in its parametric (2D) space. You need to create 2D curves on surface to create a closed boundary in 2D.

Why have you chosen such low level of implementation? It is much easier to create simple primitives with BRepBuilderAPI classes, and Booleans to cut as you need. 

John Whitaker's picture

Hey Mikhail,
Thanks for your kind answer.
My target is to build a cylinder with slanted ends with real time update of shape.
Yes, I could have used a boolean operator to do this.

But I've assumed (and I might be wrong) that a BREP description would be much faster that boolean operator to.
Isn't it true ?

John Whitaker's picture

Thanks for your answer Mikhail,
In fact, my final target isn't just a simple cylinder but a cylinder with slanted ends.
I need real time feedback to any change of geometrical parameters (radius, length, angle). So, in my case execution speed does matter.

I thought (and I might be wrong) that BREP characterization would be much faster that any boolean-based construction.
Isn't it right ?

Many thanks,

Kirill Gavrilov's picture

Are you changing parameters of a single cylinder or of many of them at once (how many then?)?

Mikhail Sazonov's picture

I believe that Boolean of simple cylinder with plane will provide real-time feedback.
Direct BREP construction is not possible without some complex computation in this case. You will need to make projection of an ellipse to the cylinder. It will take approximately the same CPU time as intersection of cylinder by plane.

John Whitaker's picture

Hi Kirill,

I'm changing only one single cylinder, but a huge amount of time per second because it's used for geometry optimization by Least Square Error method.

Kirill Gavrilov's picture

What is the purpose of transient values then? Visualization?
I would expect that BOP should be fast enough on a single cylinder, but if it is not the case (which numbers do you observe?), you may simulate cuttings using a longer cylinder with two clipping+capping planes applied on visualization level for preview and use real operation at the very end.

John Whitaker's picture

Hello Mikhail,

In fact I've been trying not to project the ellipse but to use the ellipse within cylinder BREP wire definition to restrict the infinite extand of cylinder underlying surface.

Mikhail Sazonov's picture

As I told your definition of shape is invalid. A valid face must be restricted by two representations of edges - 3D and 2D. In order to obtain 2D edges you need to project 3D curve on the surface. When Boolean operation makes intersection between surfaces it constructs both types of intersection curves 3D and 2D at once.
What kind of operations do you perform with the target cylinder each time you create a new instance? May be you do not need to create a TopoDS_Shape at all.

John Whitaker's picture

The execution speed constraint doesn't come from visualization.
The application is optimization of shape with respect to light interaction.
So I basically need to compute several (a few tens) of shape--line intersection anytime the shape is changed.