How can I write a function like BRepFill::Shell

Hi.

I would like to write a function similar to BRepFill::Shell, except that one of the wires is on the xy plane, the above is exactly above
at a certain distance (so you can get one from the other by translating with a gp_Vec( 0., 0., z )). Moreover, the wire has linear and circular edges only, so the resulting side faces could be
linear or cylindrical. ( BRepBuilderAPI_MakePrism produces a shape with errors in certain cases. I would like to make the shape quickly, and I want to do boolean operations with the shape quickly, so the BRepFill::Shell's bspline surfaces is not an option.)

The following code works for me. However, I have a problem with it. In this example e2 and e4 edges are built differently depending on
the orientation of the cylinder. I don;t have this option during building the shape I want since all the vertical edges should be
going either upward or downward. However, if I build the edges only one way I cannot make the code work in both cases (cylinder is upward or downward). Does any one has an idea, how I could replace
if ( !bDown ) {
e2 = BRepBuilderAPI_MakeEdge( v2, v4 );
e4 = BRepBuilderAPI_MakeEdge( v1, v3 );
}
else {
e2 = BRepBuilderAPI_MakeEdge( v4, v2 );
e4 = BRepBuilderAPI_MakeEdge( v3, v1 );
}

with

e2 = BRepBuilderAPI_MakeEdge( v2, v4 );
e4 = BRepBuilderAPI_MakeEdge( v1, v3 );
?

The code which is working:

// Let's build first the four edges.
Handle (Geom_CylindricalSurface) S;
Handle (Geom2d_Line) L2d;
Handle (Geom2d_Circle) C2d;
BRep_Builder B;

Standard_Real precision = Precision::Confusion();
precision = 0.01;

gp_Pnt pt1( 5.3, 9, 0 ), pt2( 11.7, 6, 0. ), pt3( pt1.X(), pt1.Y(), 3. ), pt4( pt2.X(), pt2.Y(), 3. );

Handle(Geom_TrimmedCurve) arc1;
Handle(Geom_TrimmedCurve) arc2;

if ( 1 ) { // Change this to get a clockwise or anticlockwise curve.
arc1 = GC_MakeArcOfCircle( pt1, gp_Vec( 0.3, -1., 0. ), pt2 );
arc2 = GC_MakeArcOfCircle( pt3, gp_Vec( 0.3, -1., 0. ), pt4 );
}
else {
arc1 = GC_MakeArcOfCircle( pt1, gp_Vec( 0.3, 1., 0. ), pt2 );
arc2 = GC_MakeArcOfCircle( pt3, gp_Vec( 0.3, 1., 0. ), pt4 );
}

TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex( pt1 );
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex( pt2 );
TopoDS_Vertex v3 = BRepBuilderAPI_MakeVertex( pt3 );
TopoDS_Vertex v4 = BRepBuilderAPI_MakeVertex( pt4 );

TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge( arc1, v1, v2 );
TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge( arc2, v3, v4 );
TopoDS_Edge e2, e4;

//Let's suppose now that e1 and e2 are the lower and upper edges
//v2, v4 are the side edges
// In BRepFill::Shell: Edge1, Edge2, Edge3, Edge4.

// Check whether the curve is clockwise or anti-clockwise
double f1, l1;
Handle(Geom_Circle) pCircle = Handle(Geom_Circle)::DownCast(BRep_Tool::Curve(e1, f1, l1));
if ( pCircle.IsNull() ) return;
gp_Ax2 ax2arc;
if ( !pCircle.IsNull() ) {
ax2arc = pCircle->Circ().Position();
}

// The coordinate system is pointing down.
bool bDown = ax2arc.Direction().Z()

if ( !bDown ) {
e2 = BRepBuilderAPI_MakeEdge( v2, v4 );
e4 = BRepBuilderAPI_MakeEdge( v1, v3 );
}
else {
e2 = BRepBuilderAPI_MakeEdge( v4, v2 );
e4 = BRepBuilderAPI_MakeEdge( v3, v1 );
}

TopoDS_Wire w;
TopoDS_Face face;

Handle(Geom_Circle) pGC_Circ;
if ( !bDown ) {
pGC_Circ = Handle(Geom_Circle)::DownCast(BRep_Tool::Curve(e1, f1, l1));
}
else {
pGC_Circ = Handle(Geom_Circle)::DownCast(BRep_Tool::Curve(e3, f1, l1));
}
gp_Circ circBack = pGC_Circ->Circ();
gp_Ax2 ax2( circBack.Position() );
gp_Cylinder cylSurf( gp_Ax3( ax2 ), circBack.Radius() );
gp_Cylinder cyl( cylSurf );

S = new Geom_CylindricalSurface(cyl);
B.MakeFace(face, S, precision);

B.MakeWire(w);

if ( !bDown ) {
e1.Orientation(TopAbs_FORWARD);
B.Add( w, e1 );

e2.Orientation(TopAbs_FORWARD);
B.Add( w, e2 );

e3.Orientation(TopAbs_REVERSED);
B.Add( w, e3 );

e4.Orientation(TopAbs_REVERSED);
B.Add( w, e4 );
}
else {
e1.Orientation(TopAbs_REVERSED);
B.Add( w, e1 );

e2.Orientation(TopAbs_FORWARD);
B.Add( w, e2 );

e3.Orientation(TopAbs_FORWARD);
B.Add( w, e3 );

e4.Orientation(TopAbs_REVERSED);
B.Add( w, e4 );
}

B.Add(face, w);

if ( !bDown ) {
//Normal
L2d = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(1,0));
B.UpdateEdge(e1, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
B.UpdateEdge(e2, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(f1,3),gp_Dir2d(1,0));
B.UpdateEdge(e3, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
B.UpdateEdge(e4, L2d, face, precision);
}
else {
//Reversed
L2d = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(1,0));
B.UpdateEdge(e3, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
B.UpdateEdge(e2, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(f1,3),gp_Dir2d(1,0));
B.UpdateEdge(e1, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
B.UpdateEdge(e4, L2d, face, precision);
}

if ( bDown ) face.Reverse();

mySphere = new AIS_Shape(face);

myAISContext->SetMaterial(mySphere,Graphic3d_NOM_BRONZE);
myAISContext->SetDisplayMode(mySphere,1);

myAISContext->Display(mySphere);

Thanks. Tibor.

mirjanszky.tibor's picture

This is a self-reply.

I have just realized that what I need is a
if ( bDown ) S->VReverse();

So the code looks now:

// Let's build first the four edges.
//Handle (Geom_CylindricalSurface) S;
Handle(Geom_Surface) S;
Handle (Geom2d_Line) L2d;
Handle (Geom2d_Circle) C2d;
BRep_Builder B;

Standard_Real precision = Precision::Confusion();
precision = 0.01;

gp_Pnt pt1( 5.3, 9, 0 ), pt2( 11.7, 6, 0. ), pt3( pt1.X(), pt1.Y(), 3. ), pt4( pt2.X(), pt2.Y(), 3. );

Handle(Geom_TrimmedCurve) arc1;
Handle(Geom_TrimmedCurve) arc2;

if ( 0 ) { // Change this to get a clockwise or anticlockwise curve.
arc1 = GC_MakeArcOfCircle( pt1, gp_Vec( 0.3, -1., 0. ), pt2 );
arc2 = GC_MakeArcOfCircle( pt3, gp_Vec( 0.3, -1., 0. ), pt4 );
}
else {
arc1 = GC_MakeArcOfCircle( pt1, gp_Vec( 0.3, 1., 0. ), pt2 );
arc2 = GC_MakeArcOfCircle( pt3, gp_Vec( 0.3, 1., 0. ), pt4 );
}

TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex( pt1 );
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex( pt2 );
TopoDS_Vertex v3 = BRepBuilderAPI_MakeVertex( pt3 );
TopoDS_Vertex v4 = BRepBuilderAPI_MakeVertex( pt4 );

TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge( arc1, v1, v2 );
TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge( arc2, v3, v4 );
TopoDS_Edge e2, e4;

//Let's suppose now that e1 and e2 are the lower and upper edges
//v2, v4 are the side edges
// In BRepFill::Shell: Edge1, Edge2, Edge3, Edge4.

// Check whether the curve is clockwise or anti-clockwise
double f1, l1;
Handle(Geom_Circle) pCircle = Handle(Geom_Circle)::DownCast(BRep_Tool::Curve(e1, f1, l1));
if ( pCircle.IsNull() ) return;
gp_Ax2 ax2arc;
if ( !pCircle.IsNull() ) {
ax2arc = pCircle->Circ().Position();
}

// The coordinate system is pointing down.
bool bDown = ax2arc.Direction().Z() < 0;

e2 = BRepBuilderAPI_MakeEdge( v2, v4 );
e4 = BRepBuilderAPI_MakeEdge( v1, v3 );

TopoDS_Wire w;
TopoDS_Face face;

Handle(Geom_Circle) pGC_Circ;
pGC_Circ = Handle(Geom_Circle)::DownCast(BRep_Tool::Curve(e1, f1, l1));
gp_Circ circBack = pGC_Circ->Circ();
gp_Ax2 ax2( circBack.Position() );
gp_Cylinder cylSurf( gp_Ax3( ax2 ), circBack.Radius() );
gp_Cylinder cyl( cylSurf );

S = new Geom_CylindricalSurface(cyl);
if ( bDown ) S->VReverse();

B.MakeFace(face, S, precision);

B.MakeWire(w);

e1.Orientation(TopAbs_FORWARD);
B.Add( w, e1 );

e2.Orientation(TopAbs_FORWARD);
B.Add( w, e2 );

e3.Orientation(TopAbs_REVERSED);
B.Add( w, e3 );

e4.Orientation(TopAbs_REVERSED);
B.Add( w, e4 );

B.Add(face, w);

//Normal
L2d = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(1,0));
B.UpdateEdge(e1, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1));
B.UpdateEdge(e2, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(f1,3),gp_Dir2d(1,0));
B.UpdateEdge(e3, L2d, face, precision);

L2d = new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1));
B.UpdateEdge(e4, L2d, face, precision);

//if ( bDown ) face.Reverse();

mySphere = new AIS_Shape(face);

myAISContext->SetMaterial(mySphere,Graphic3d_NOM_BRONZE);
myAISContext->SetDisplayMode(mySphere,1);

myAISContext->Display(mySphere);