How would you construct this cylinder?


I'm trying to construct a cylinder which shall have one or more of the following attributes:
- elliptical base
- lateral with a certain thickness
- sloped top
- segmented lateral

What would be your approach?

I've tried to construct the latheral and then use BRepOffsetApi_MakeThickSolid. This algorithm fails for certain correct parameter combinations (when the base is very elliptical).

Using BRepOffsetAPI_MakeOffset on base-ellipse or on latheral-face produces no elliptical inner cylinder and even crashes in some parameter combinations, so it's not applicable.

I'd like to avoid boolean operations as they are too slow. A simple cut takes ~1.5sec on my machine - I would need up to 3 cuts per cylinder (sloped top, segmentation, drilling to achieve a thickness).

My current approach is this:
- construct inner and outer base ellipses
- extrude the resulting face via BRepPrimAPI_MakePrism
- apply BRepOffsetAPI_DraftAngle to the top face of the resulting cylinder
But again, this fails in some accurate parameter combinations. (See code below)

As the situation looks a bit hopeless and I already failed constructing a cone with attributes similar to the ones of the cylinder, every hint is very welcome (even for the cone).

I'm using OCC6.3 on Windows.

Code of the last approach to construct a cylinder:
// Cylinder's topological data
Standard_Real slopingAngle = 15*PI/180.; // change this to 5 degree to fail
Standard_Real diam = 8; // or change this to 50 to crash
Standard_Real diame = 2;
Standard_Real thick = 0.1;
gp_Pnt bottomCentre(0, -3, 0);
gp_Pnt topCentre(0, 3, 0);
gp_Pnt diameDirectionPoint(1, -3, 0);

gp_Dir diameDirection(gp_Vec(bottomCentre, diameDirectionPoint));

// Construct outer ellipse of bottom
gp_Ax2 bottomSystem(bottomCentre, gp_Dir(gp_Vec(bottomCentre, topCentre)), diameDirection);
gp_Elips bottomEllipse = getEllipse(bottomSystem, diame/2., diam/2.);
BRepBuilderAPI_MakeEdge edgeMaker(bottomEllipse);
BRepBuilderAPI_MakeWire wireMaker(edgeMaker);
BRepBuilderAPI_MakeFace faceMaker(wireMaker);

// Construct inner ellipse of bottom
gp_Elips innerBase = getEllipse(bottomSystem, diame/2.-thick, diam/2.-thick);
BRepBuilderAPI_MakeEdge innerEdge(innerBase);
BRepBuilderAPI_MakeWire innerWire(innerEdge);
TopoDS_Face bottomFace = faceMaker.Face();

// Extrude base to top
gp_Vec extrusionVector(bottomCentre, topCentre);
BRepPrimAPI_MakePrism prismMaker(bottomFace, extrusionVector);
TopoDS_Shape cylinder = prismMaker.Shape();

// Slope top
BRepOffsetAPI_DraftAngle draftAngle(cylinder);

// determine upper face
TopExp_Explorer ex;
TopoDS_Face upperFace;
for (ex.Init(cylinder, TopAbs_FACE); ex.More(); ex.Next())
// The upper face is the last one. (Admitted, this might be optimized :)
upperFace = TopoDS::Face(ex.Current());

gp_Pln neutralPlane = gp_Pln(topCentre, diameDirection);
gp_Dir removalDirection = diameDirection;
Standard_Real rotationAngle = slopingAngle;

// slope top to other direction
if(slopingAngle {
Standard_Real neutralPlaneAngle = PI;
removalDirection = removalDirection.Reversed();
rotationAngle = -slopingAngle;

draftAngle.Add(upperFace, removalDirection, rotationAngle, neutralPlane, 0);
cylinder = draftAngle.Shape();

gp_Elips TopoFeatureElliptical::getEllipse(const gp_Ax2& system, Standard_Real radius1, Standard_Real radius2)
if(radius1 {
gp_Elips ellipse(system, radius2, radius1);
ellipse.Rotate(system.Axis(), PI*90/180);
return ellipse;
gp_Elips ellipse(system, radius1, radius2);
return ellipse;

Roman Lygin's picture

Hi mz,

Could you give some sketch of the expected solid ? I'm not sure I understand what "segmented lateral" means for instance.
Anyway, here are a couple of additional alternatives that could possibly help:
1. create a profile (cutting section of a lateral faces) and sweep along the bottom ellipse - see attached image;
2. create the whole body bottom-up - you will need to create 4 individual phases (2 lateral - outer and inner, and 2 top and bottom).

Hope this helps.
--- - the Open CASCADE blog - CAD Exchanger, your 3D data translator

mz's picture

Hi Roman,

By segmentation I meant to cut out a pie slice out of the lateral. (see attached file - I'd like to construct these shapes with OCC)

The construction of the cylinder does work in principle. My current problem is sloping the top which fails under certain circumstances. Could a sweep along the bottom ellipse solve the sloping? If so, could you give a more detailled hint? (I'm not too familiar with OCC)

If I had to create the whole body by myself - my problem would be the sloping top again. How could I determine the dimensions of the top face? As indicated in the code snippet, all I have are the points gp_Pnt bottomCentre, topCentre, diameDirectionPoint and the sloping angle (and thick, diam and diame).

Thanks a lot!

Roman Lygin's picture

OK. I see now thanks.
Sweeping seems to not work here.
Well, I'd still try Boolean cuts - in Debug mode cut of the cylinder top took ~0.4s, so in Release - likely about as twice as little. Just make sure you take a large enough tool (box) to avoid any tangency.
Thus, overall approach could be:
1. create a bottom face (full ellipse, full ellipse minus segment or full ellipse with a hole) - you can always model an exact boundary
2. prism
3. cut

Hope this helps.

mz's picture

Thanks, Roman. Because of your recommendation I will give the BOP-approach another try. I will report here about the result.

Again, thanks a lot for your help!

Roman Lygin's picture

Just in case, here is a sequence of DRAWEXE commands that demonstrates the idea:

> pload MODELING
# base face
> ellipse e 0 0 0 4 2
> trim e e -1.5 4.5
> cvalue e -1.5 x1 y1 z1
> cvalue e 4.5 x2 y2 z2
> mkedge e1 e
> polyline p x1 y1 z1 0 0 0 x2 y2 z2
> wire w e1 p
> mkplane pl w
# prism
> prism pr pl 0 0 10
# tool and cut
> box b -10 -10 0 20 20 10
> trotate b 0 0 0 0 1 0 10
> ttranslate b 0 0 8
> bop pr b
> bopcut res

# display result
> smallview
> donly res
> fit

Good luck !