Get the point with the lowest x-value


I have a TopoDS_Shape and need to get the point on the surface of the shape with the lowest x-value. Is there a OpenCascade function to determine such points or need I to iterate over the whole surface to get the point with the lowest x-value?


Bearloga's picture

You can use BRepExtrema_DistShapeShape, taking a plane X=-1e100 for the second shape.

Markus's picture

My fault - I dont need the distance, I need the exact point where the distance is lowest.

Bearloga's picture

That class provides all necessary information, including points on both shapes for each solution, and parameters of points on supporting geometries, see the methods PointOnShape1, SupportTypeShape1, SupportOnShape1, ParOnEdgeS1, ParOnFaceS1.

Markus's picture

Thank you! Thats the functions I need!

Sharjith Naramparambath's picture

The solution suggested above will give you the distance. However you can compare the shape with the YOZ Plane and get the X coordinate from the distance along X axis. I hope it will work.

N. Sharjith

Vijayaragavan's picture

I need to get the dimension of all entities(edges,circles) from the given model..

Vijayaragavan's picture

I need to get the dimensions of entities(edges,circles,etc) from a given model and export the same to database....which package i have to use for getting dimensions..Is there any API s available to get the dimensions of selected edges...
Please help me...

Thanks and Regards,

Rob Bachrach's picture
Vijayaragavan's picture

Hi Rob,
Thanks for your reply..I got the dimensional data for box and circle..I need to take dimensional data for all basic 2D models(line,triangle,square,ellipse etc)...How can i do that..I am new to Opencascade....If Possible please send me some sample code for doing the same....One part of my project is Taking Dimensional Data from given 2D model..It will be helpful if u send some sample code for extracting dimensional data.....


Rob Bachrach's picture


Here is some sample code I use for getting lines and circles from an IGES file. You can expand this to handle any of the OCC primitive curve types. However, compound shapes like triangles and squares are another story. You would need to write code to look at a set of lines and identify the compound shapes. For example:
- find edges that form a closed loop (you might be able to look at wires in the OCC shape)
- if there are four edges
- if opposite edges have the same length
- if at least one angle is 90 degrees
- this must be a rectangle
- get the lengths of the edges for the dimensions

Other complex shapes can be more or less complicated. We have done some of this work, but it is too complicated to post and is proprietary to my company, so I can't share it. Sorry.

Good luck, here's the code,

// build a compound of edges to be converted
Bnd_Box bound;
Standard_Real minX, minY, minZ, maxX, maxY, maxZ;
BRep_Builder builder;
TopoDS_Compound compound;
TopExp_Explorer ex;
for (ex.Init(shape, TopAbs_EDGE); ex.More(); ex.Next()) {
// get the bounding box for this edge
BRepBndLib::Add(ex.Current(), bound);

// if the edge is parallel to the Z axis, skip it
if (bound.IsVoid() ||
(bound.IsXThin(Precision::Confusion()) &&
bound.IsYThin(Precision::Confusion()))) continue;

// add the edge to the compound
builder.Add(compound, ex.Current());

// get the bounding box of the shape
BRepBndLib::Add(compound, bound);
bound.Get(minX, minY, minZ, maxX, maxY, maxZ);

// get the maximum z plane minus a tolerance
Standard_Real zTop = maxZ-((maxZ-minZ)*BOX_TOL);

// make a map to avoid duplicate edges
TopTools_MapOfShape mapEdges;

// loop through the edges in the shape
for (ex.Init(compound, TopAbs_EDGE); ex.More(); ex.Next()) {
TopoDS_Edge edge = TopoDS::Edge(ex.Current());

// skip this edge if it was already processed
if (mapEdges.Contains(edge)) continue;

// get the bounding box for this edge
BRepBndLib::Add(edge, bound);
bound.Get(minX, minY, minZ, maxX, maxY, maxZ);

// skip this edge if it is not in the top plane
if (minZ < zTop) continue;

// add the edge to the map

// get the curve from the edge
Standard_Real fFirst, fLast;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, fFirst, fLast);

// if the edge is 0 length, throw it away
if (IsEqual(fFirst, fLast)) continue;

// swap the parameters if the edge is reversed
if (edge.Orientation() == TopAbs_REVERSED) {
Standard_Real fTemp = fFirst;
fFirst = fLast;
fLast = fTemp;

// process the curve based on its type
Handle(Standard_Type) type = curve->DynamicType();
if (type == STANDARD_TYPE(Geom_Line)) {
Handle(Geom_Line) line = Handle(Geom_Line)::DownCast(curve);

// get its start and end points
gp_Pnt gPtStart = line->Value(fFirst);
gp_Pnt gPtEnd = line->Value(fLast);

// create a line primitive
else if (type == STANDARD_TYPE(Geom_Circle)) {
Handle(Geom_Circle) circle = Handle(Geom_Circle)::DownCast(curve);

// make a 360 degree arc a circle
if ((fabs(fmod(fFirst, Standard_PI*2.0)) < ZERO_TOL) &&
(fabs(fmod(fLast, Standard_PI*2.0)) < ZERO_TOL)) {
// get the center and radius
gp_Circ gCirc = circle->Circ();
gp_Pnt gPtCenter = gCirc.Location();
float fRadius = (float) gCirc.Radius();

// create the circle primitive
else {
// get the start point, end point, and mid point
gp_Pnt gPtStart = circle->Value(fFirst);
gp_Pnt gPtEnd = circle->Value(fLast);
gp_Pnt gPtMid = circle->Value((fFirst+fLast)/2.0);

// create the arc primitive
else {
qDebug("Unrecognized curve: %s - %g, %g", type->Name(), fFirst, fLast);