Creating a curved face (se picture)

I like to create the following solid:
http://www.ceco.se/images/Curved_Wall.jpg

It is a curved Wall that I have two lines and two trimmed circles, (the upper profile of the wall).
My (first) problem is how to create the trimmed circles. I se in the “Bottle”-example of of Open CASCADE how to make a trimmed circle of three poins but not when I have the radius and endpoints of a circle.

For the two lines do I have the location of the line and a vector. (The vector does have a Orientation and a Magnitude).

All suggestions how to tackle my problem are welcomed.

Rob Bachrach's picture

If you have the radius and endpoints of your arc, you can create a circle with GccAna_Circ2d2TanRad. Keep in mind that this will most likely return 2 answers and you will have to pick the right one. You can then make the trimmed edge using BRepBuilderAPI_MakeEdge2d (the constructor that takes a gp_Circ2d and 2 gp_Pnt2d objects for the endpoints). As for your connecting lines, since you already have the endpoints you can use BRepBuilderAPI_MakeEdge2d with the endpoints for each edge. Then, make a wire from your edges and a planar face from the wire.

d00_ape's picture

Ok, thanks, My goal is to get the 4 edges and then to make a face of it.
How would you create the one of the lines to a TopoDS_Edge from the following parameters:

1. Start point (X,Y,Z)
2. A vector with the following params:
a, Direction (X,Y,Z)
b, Length (REAL)

Thanks!

Rob Bachrach's picture

The easiest way would be:
BRepBuilderAPI_MakeEdge2d(gp_Lin2d(startPt, direc),0,length);

The 0 and length are start and end parameters of the trimmed edge. Since you created the line with the start point as the reference, a parameter of 0 produces that point. The length will be that many millimeters along the direction (use a unity vector for the direction).

d00_ape's picture

I suppose I can do it this way too.... ?

double X, Y, Z, vX, vY, vZ;
...
gp_Pnt startpoint(X, Y, Z);
gp_Dir direction(vX, vY, vZ);
edge = BRepBuilderAPI_MakeEdge(gp_Lin(startpoint, direction), 0, length);

Rob Bachrach's picture

Yep, it's just a matter of whether you're working in 2D or 3D.

d00_ape's picture

What could be wrong if the GccAna_Circ2d2TanRad(...) function "IsDone" and I make this:

GccAna_Circ2d2TanRad TR(gp_Pnt2d(X1, Y1), gp_Pnt2d(X2, Y2), circle.Radius(), 0.1);
if (TR.IsDone()) {
cout << TR.NbSolutions(); // PRINTS "2"
if (TR.NbSolutions() > 0) {
gp_Circ2d gpcircle = TR.ThisSolution(0); // EXCEPTION
...
}
}

At the TR.ThisSolution(0) call I got the exception:
"Microsoft C++ exception: Standard_OutOfRange"

Rob Bachrach's picture

Indexed OCC containers start at 1 (for some reason). The two solutions will be at indexes 1 and 2.

d00_ape's picture

... ohhhh that was a tricky one. Thanks!
When I got you on the line Rob ;-) Can you answer this? I've created a TopoDS_Face and extrudet it in a direction to make a solid like this:

TopoDS_Shape shape = BRepPrimAPI_MakePrism(face, Dir);

Now I still have the bottom (the original face) and the "extruded sides" of my new shape. how do I add the top of the extruded shape?
I've looked at the bottle example (In My first Application) but I can't find any difference in my code...

Rob Bachrach's picture

If you are extruding a face, the result should be a solid (with a top and bottom). The only way you would not get the end caps would be if you extruded a wire. Maybe there is something wrong with the way you are examining your results?

d00_ape's picture

Yeah, I might examine the resulting shape in a wrong way. I do it like this: I am triangulate the shape with this codeblock:
-------------------------------------------------------
BRepMesh::Mesh(shape, 1);
Standard_Integer result(0);
for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) {
TopoDS_Face F = TopoDS::Face(ex.Current());
TopLoc_Location L;
Handle_Poly_Triangulation triangulation = BRep_Tool::Triangulation(F, L);
const TColgp_Array1OfPnt& nodes = triangulation->Nodes();
for (int i = nodes.Lower(); i <= nodes.Upper(); i++) {
gp_Pnt point = nodes(i);
...
}
int index1, index2, index3;
const Poly_Array1OfTriangle& triangles = triangulation->Triangles();
for (int j = triangles.Lower(); j <= triangles.Upper(); j++) {
const Poly_Triangle& triangle = triangles(j);
triangle.Get(index1, index2, index3);
...
}
} // for TopExp_Explorer
--------------------------------------------------------

then I'm putting in the points and triangles into my render system (debugging with VRML)

Rob Bachrach's picture

That's the problem. You will find that the top and bottom faces reference the same TopoDS_Face with different transformation matrices. So, the triangulations are the same. If you transform the nodes of each face using the TopLoc_Location for that face, the faces should appear in their proper locations.

d00_ape's picture

I don't really get what I'm doing wrong...

Is my code:
---------------------
...
TopLoc_Location L;
Handle_Poly_Triangulation triangulation = BRep_Tool::Triangulation(F, L);
...
---------------------

or should I do something else with my shape before triangulation? Thanks for your help Rob.

Rob Bachrach's picture

You are retrieving the location of the triangulation (L), but you are not applying it to the node locations. Try something like this...

Above the node loop, create a transformation from the location:

gp_Trsf xform = L;

Inside the node loop, instead of:

gp_Pnt point = nodes(i);

Try:

gp_Pnt point = nodes(i).Transformed(xform);

That should take the node location and apply the face transformation.

d00_ape's picture

YOU ARE THE KING!

d00_ape's picture

Whatch this URL for example of an extruded circle:
http://www.ceco.se/images/ExtrudedCircle.JPG

d00_ape's picture

The edge is created like this:

TopoDS_Edge edge = BRepBuilderAPI_MakeFace(Wire);