Extracting dimensions from a box

Hi everyone,

I have a code that loads an IGES file into memory and translates all the IGES entities in the file into OCC shapes. The code is:

#include "IGESControl_Reader.hxx"
#include "TColStd_HSequenceOfTransient.hxx"
#include "TopoDS_Shape.hxx"

int main()
{
IGESControl_Reader myIgesReader;
Standard_Integer nIgesFaces,nTransFaces;
myIgesReader.ReadFile ("cuboid.igs");
//loads file MyFile.igs
Handle(TColStd_HSequenceOfTransient) myList = myIgesReader.GiveList("iges-faces");
//selects all IGES faces in the file and puts them into a list called //MyList,
nIgesFaces = myList->Length();
nTransFaces = myIgesReader.TransferList(myList);
//translates MyList,
cout TopoDS_Shape sh = myIgesReader.OneShape();
//and obtains the results in an Open CASCADE shape.
return (0);
}

The file being loaded "cuboid.igs" is a 3D rectangular box.

I need to get the dimensions of this box (length, width, height). I looked through the Geom_Plane.cdl file and it looks like the "Bounds" class has to be used. Could someone tell me how to use this in my code (variables to be declared, headers to be included etc.)?

I'm not an expert programmer. Any help from anyone will be greatly appreciated !!

Thanks !!

Rob Bachrach's picture

Note that the bounding box library will work if the faces of your cuboid are parallel with the standard X-Y-Z coordinate system planes.

#include "Bnd_Box.hxx"
#include "BRepBndLib.hxx"

Bnd_Box bounds;
BRepBndLib::Add(sh, bounds);
bounds.SetGap(0.0);
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);

Make sure you have the TKTopAlgo and TKMath libraries linked as well.

Karthik Viswanathan's picture

Hi Rob,

Thank you very much for your reply. Your code works really well.

However, I would like to get the dimensions of sub-features in the box. For example, if there is a circular hole, I need to get its radius & depth; if there is a rectangular groove, I need its length, width and height and so on. How do you think this can be done?

Also, how do you get the dimensions of other 3D shapes like spheres, cylinders, cones etc.? Do I need to use other classes (like "Bounds" for the cuboid) dependng on the type of shape?

I would appreciate it if you help further !!

Thanks a bunch for your help !!

Rob Bachrach's picture

Since you are looking for specific dimensions of specific features, you need to have different code for each shape you are looking for. You might want to look at the following thread:

http://www.opencascade.org/org/forum/thread_11187/

Karthik Viswanathan's picture

Hi Rob,

I looked at the other thread that you suggested. I'm still not able to figure out how to access dimensions of specific features. For example, if I have a cuboid with a rectangular slot (of a certain length, width & depth) cut in it, how do I access these dimensions of the slot? The following line in my code selects all the faces in the entire model:

Handle(TColStd_HSequenceOfTransient) myList = myIgesReader.GiveList("iges-faces");

I tried changing the argument "iges-faces" to other arguments mentioned in the IGES user's namual, but none of them worked. Is it not possible to select only certain faces/edges in the model, rather than selecting all faces?

You said it may be possible to access dimensions of specific features by interactively selecting them after importing the IGES file. How do I go about doing this?

Thank you very much for your help once again !!

Karthik Viswanathan's picture

Forgot to mention that the rectangular slot was made by drawing a rectangle on one of the faces and using the "Extruded Cut" command in SolidWorks

Rob Bachrach's picture

Although you can import only certain items from the IGES file, the selection of those items is probably more involved than you wish to deal with. It is easier to import the entire IGES file and make a cascade shape.

You can select the face from the cascade shape programatically. Of course, any programmatic selection requires your program to have knowledge of the nature of your geometry. For instance, while traversing the faces of your geometry using TopExp_Explorer, you can get a point on the surface to see how it matches your bounding box:

Standard_Real u1, u2, v1, v2;
BRepTools::UVBounds(face, u1, u2, v1, v2);
Handle(Geom_Surface) surface = BRep_Tool::Surface(face);
gp_Pnt gPt;
surace->D0((u1+u2)/2., (v1+v2)/2., gPt);

Compare the coordinates of gPt to your bounding box to see if it is on the outskirts or on the inside of a hole.

Another option is to find a face with multiple wires (by exploring the faces, then the wires). Ignore the edges in the outermost wire (see BRepTools::OuterWire) and get the lengths of the remaining edges.

As for interactive selection, that is a much bigger task than I am willing to explain here. You would need to implement visualization and selection of your edges in OCC. Your best bet is to look at the code in the example problems and read the documentation.

Good luck.

Karthik Viswanathan's picture

Rob,

I really appreciate your help! I'll try out whatever you have suggested and if I'm unsuccessful, I'll post another message.

Thanks!

Karthik Viswanathan's picture

Hello Rob,

I tried both the methods suggested by you. In the sample code that you gave me, I get an Internet Explorer error message which says: "cuboid_with_slot.exe has encountered a problem and needs to close. We are sorry for the inconvenience." This is being caused from the second line of your code onwards, since I dont get the error when I comment out the 2nd, 3rd, 4th and 5th lines of your code.

As for your second method, I tried to find all the faces in my shape using the following snippet:

TopExp_Explorer Ex;
for (Ex.Init(sh,TopAbs_FACE); Ex.More(); Ex.Next()) {
ProcessFace(Ex.Current());
}

I get an error message that says: "error C2065: 'ProcessFace' : undeclared identifier
Error executing cl.exe".
I have included the following headers in my program:
#include "IGESControl_Reader.hxx"
#include "TColStd_HSequenceOfTransient.hxx"
#include "TopoDS_Shape.hxx"
#include "Bnd_Box.hxx"
#include "BRepBndLib.hxx"
#include "BRepTools.hxx"
#include "Geom_Surface.hxx"
#include "BRep_Tool.hxx"
#include "gp_Pnt.hxx"
#include "Geom_Plane.hxx"
#include "TopoDS_Face.hxx"
#include "TopExp_Explorer.hxx"
#include "TopAbs.hxx"
#include "TopoDS.hxx"
#include "TopExp.hxx"
#include "Standard.hxx"
#include "HLRTopoBRep_OutLiner.hxx"

Am I missing some header(s)? What could be the problem?

Thanks a million once again!!

Rob Bachrach's picture

In the first method, the 2nd-5th lines of code should work fine as long as "face" is a valid face from your geometry.

As for the second method, there is no such function as ProcessFace. You need to implement it to do what you need with the face.

It looks like Chris Oke gave you some detailed code in your other thread on this subject (11613). Give that a try. You could just as easily replace the first call to MapShapes and the for loop with your TopExp::Explorer loop, but either way is fine.

Karthik Viswanathan's picture

Thanks again Rob !

Karthik Viswanathan's picture

Hi Rob & Chris,

Thanks for your help so far. I was able to get some dimensions that I needed using the information that Chris gave me.

I was pondering over an observation that I made:

Wouldn't it be easier to get dimensions if I created the sub-features in my imported shape (using oboolean operations) after importing from IGES instead of translating an IGES solid with the sub-features already created in it?

I figured that since boolean operations are performed on the OCC shape after import, the dimensions of the material removed from the solid will probably be stored somewhere.

So, wouldn't getting the dimensions of just the removed portion be a much easier task? Are these dimensions stored somewhere immediately after the boolean operation has been performed?

Thanks for your replies again!

Rob Bachrach's picture

True, you could perform the boolean operation in OCC. However, may not find it much easier to extract the dimensions this way. If you look at the docs for BRepAlgoAPI_BooleanOperation (the base class of BRepAlgoAPI_Cut), you will see that you can access shapes changed in the first shape of the operation, shapes changed in the second, shapes created, and shapes removed. You can also see the intersection information.

If you try to approach it from this angle, your best bet would be to look at tbe intersection information (SectionEdges) to get your dimensions. However, you may find you lose flexibility for only a small (if any) benefit.