In this tutorial, we will review the usage of a very powerful (yet tricky) function from openCASCADE’s framework:

BRepOffsetAPI_MakeFilling

Advanced shape creation – the basics.

A filling requires that a closed bound is defined.

    
// Full filling options
    Standard_Integer Degree=3;
    Standard_Integer NbPtsOnCur=15;
    Standard_Integer NbIter=2;
    Standard_Boolean Anisotropie=Standard_False;
    Standard_Real Tol2d=0.00001;
    Standard_Real Tol3d=0.0001;
    Standard_Real TolAng=0.01;
    Standard_Real TolCurv=0.01;
    Standard_Integer MaxDeg=8;
    Standard_Integer MaxSegments=9;


    BRepOffsetAPI_MakeFilling fillingOp(Degree,NbPtsOnCur,NbIter,Anisotropie,Tol2d,Tol3d,TolAng,TolCurv,MaxDeg,MaxSegments);
    Standard_Boolean isBound = true;

    double l=100.;
    gp_Dir zDir(0,0,1);

    double rBaseCircle = 50.;
    gp_Pnt cBaseCircle(0,0,0);
    gp_Circ baseCircle(gp_Ax2(cBaseCircle,zDir),rBaseCircle);
    opencascade::handle<Geom_TrimmedCurve> baseTrim = new Geom_TrimmedCurve(new Geom_Circle(baseCircle),0,M_PI);

    double r1TopElips = 20;
    double r2TopElips = 5;
    gp_Pnt cToplips(0,0,l);
    gp_Elips topElips(gp_Ax2(cToplips,zDir),r1TopElips,r2TopElips);
    opencascade::handle<Geom_TrimmedCurve> topTrim = new Geom_TrimmedCurve(new Geom_Ellipse(topElips),0,M_PI);

    auto baseEd     = BRepBuilderAPI_MakeEdge(baseTrim).Edge();
    auto topEd      = BRepBuilderAPI_MakeEdge(topTrim).Edge();
    auto side1      = BRepBuilderAPI_MakeEdge(baseTrim->StartPoint(),topTrim->StartPoint()).Edge();
    auto side2      = BRepBuilderAPI_MakeEdge(baseTrim->EndPoint(),topTrim->EndPoint()).Edge();
    //Add bounds
   fillingOp.Add(baseEd,GeomAbs_C0,isBound);
   fillingOp.Add(topEd,GeomAbs_C0,isBound);
   fillingOp.Add(side1,GeomAbs_C0,isBound);
   fillingOp.Add(side2,GeomAbs_C0,isBound);

   fillingOp.Build();

The surface looks bumpy, it’s true but it satisfy the constrains we have set and the solution is not unique. So if one wants to have a straighter surface

Advanced shape creation – add curve constrain.

Lets add a constrain line to the construction, this line pass trough the half of both top and base curves. To do so one has to add the flowing lines before running Build() command:

 
    //Add constrain
    auto constrain1 = BRepBuilderAPI_MakeEdge(baseTrim->Value(M_PI_2),topTrim->Value(M_PI_2)).Edge();
    fillingOp.Add(constrain1,GeomAbs_C0,!isBound);

Now the surface is not so curved:

But it doesn’t look straight enough. So more constrain lines have to be added, so instead of adding the previous lines, one can substitutes them to these ones:

 
    //Add constrains
    int nConstrains = 5;
    for(int i = 1 ; i <= nConstrains ; i++){
        auto constrain = BRepBuilderAPI_MakeEdge(baseTrim->Value(M_PI*i/(nConstrains+1.)),topTrim->Value(M_PI*i/(nConstrains+1.))).Edge();
        fillingOp.Add(constrain,GeomAbs_C0,!isBound);
        auto oseContrain1 = new ocShapeEntity(constrain ,rootNode,false,true);
        oseContrain1->setLineWidth(5.f);
    }

Now the surface looks more to what we can expect from such a function.

Advanced shape creation – add tangent constrain.

Tangent constrains are specified by linking constrains edges to a face. So before adding constrain faces has to be built:

 
    BRepPrimAPI_MakePrism prismOp(topEd,gp_Vec(0.,0.,l*0.1));
    explorer.Init(prismOp.Shape(),TopAbs_FACE);
    TopoDS_Face tgFace = TopoDS::Face(explorer.Current());

    BRepPrimAPI_MakePrism prismOp2(baseEd,gp_Vec(0.,0.,-l*0.1));
    explorer.Init(prismOp2.Shape(),TopAbs_FACE);
    TopoDS_Face tgFace2 = TopoDS::Face(explorer.Current());

    BRepPrimAPI_MakePrism prismOp3(side1,gp_Vec(0.,-l*0.1,0.));
    explorer.Init(prismOp3.Shape(),TopAbs_FACE);
    TopoDS_Face tgFace3 = TopoDS::Face(explorer.Current());

    BRepPrimAPI_MakePrism prismOp4(side2,gp_Vec(0.,-l*0.1,0.));
    explorer.Init(prismOp4.Shape(),TopAbs_FACE);
    TopoDS_Face tgFace4 = TopoDS::Face(explorer.Current());

Then constrains edges has to be added this way:

 
    //Add bounds
//    fillingOp.Add(baseEd,GeomAbs_C0,isBound);
//    fillingOp.Add(topEd,GeomAbs_C0,isBound);
//    fillingOp.Add(side1,GeomAbs_C0,isBound);
//    fillingOp.Add(side2,GeomAbs_C0,isBound);
    fillingOp.Add(topEd,tgFace,GeomAbs_G1 ,isBound);
    fillingOp.Add(baseEd,tgFace2,GeomAbs_G1 ,isBound);
    fillingOp.Add(side1,tgFace3,GeomAbs_G1 ,isBound);
    fillingOp.Add(side2,tgFace4,GeomAbs_G1 ,isBound);