For all issues regarding the Forums use, please, refer to the Forum Rules.

Our Solutions

Need professional assistance?
Consider our:

Support Offerings

 

Need to speed up your development?
Have a look at our:

Samples & Tools

 

Need some functionality extending standard OCCT capabilities?
Check out our:

Adv. Components

Related pages

Getting radius of circle

MechEngr's picture
Forums: 

Hi everyone,

I'm trying to get the radius of a circular hole in a cuboidal model.

Here is part of the code that I tried using:

// iterating through each face in the model
for(i=1; i {
TopoDS_Face face=TopoDS::Face(faces.FindKey(i));

// getting all wires in the face and outerwire
TopTools_IndexedMapOfShape wires;
TopExp::MapShapes(face, TopAbs_WIRE, wires);
TopoDS_Wire outerWire=BRepTools::OuterWire(face);

// iterating through each wire in the faces
for(j=1; j {
TopoDS_Wire wire=TopoDS::Wire(wires.FindKey(j));
if(wire!=outerWire)
{
Standard_Real R,U1,U2;
Handle (Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(wire), U1, U2);
Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C2);
R = C2->Circ().Radius();
cout }

When I try executing this, I get a debug error ("abnormal program termination").

Could someone tell me what I am doing wrong? Also, if someone could provide me with the correct code for getting the radius of the circular hole, I would greatly appreciate it.

Thanks in advance !!

Bearloga's picture

Check handled objects with IsNull method to know if it can be addressed. It is for sure C2 is a null handle if a curve is not of type circle.

P Dolbey's picture

The line-

Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C2);

Did you intend it to be

Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C1);

otherwise how is C2 defined

Pete

MechEngr's picture

Hi Bearloga and P Dobley,

Thanks for your replies. Yes I intended the line to be the second one.

I made the correction in the DownCast argument from C2 to C1. I also checked the handled objects with IsNull. I still get the same error message. After the modifications, the code now looks like this:

// iterating through each face in the model
for(i=1; i {
TopoDS_Face face=TopoDS::Face(faces.FindKey(i));

// getting all wires in the face and outerwire
TopTools_IndexedMapOfShape wires;
TopExp::MapShapes(face, TopAbs_WIRE, wires);
TopoDS_Wire outerWire=BRepTools::OuterWire(face);

// iterating through each wire in the faces
for(j=1; j {
TopoDS_Wire wire=TopoDS::Wire(wires.FindKey(j));
if(wire!=outerWire)
{
Standard_Real R,U1,U2;
Handle (Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(wire), U1, U2);
if (! C1.IsNull())
{
Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C1);
if (! C2.IsNull())
{
R = C2->Circ().Radius();
cout }
}
}

The faces & wires that are encountered prior to encountering the circular hole's wire (which is not an outer wire) are being read. But when the hole's wire is encountered, VC++ spits out the "abnormal program termination" debug error message.

Could anyone please help me out on this?

Thanks a bunch !!

P Dolbey's picture

There's a piece of code from Daniel Kelley in http://www.opencascade.org/org/forum/thread_11618/ that illustrates the "DynamicType" test - could be useful in your algo.

Pete

MechEngr's picture

Pete and Stephane,

Thanks once again for your replies. I tried using TopExp_Explorer to explore the wire to get the edges, as follows:

// iterating through each face in the model
for(i=1; i {
TopoDS_Face face=TopoDS::Face(faces.FindKey(i));

// getting all wires in the face and outerwire
TopTools_IndexedMapOfShape wires;
TopExp::MapShapes(face, TopAbs_WIRE, wires);
TopoDS_Wire outerWire=BRepTools::OuterWire(face);

// iterating through each wire in the faces
for(j=1; j {
TopoDS_Wire wire=TopoDS::Wire(wires.FindKey(j));

if(wire!=outerWire)
{
cout Standard_Real R,U1,U2;
TopExp_Explorer exp;
for (exp.Init(wire,TopAbs_EDGE); exp.More(); exp.Next())
{
Handle (Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), U1, U2);
if (! C1.IsNull())
{
Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C1);
if (! C2.IsNull())
{
R = C2->Circ().Radius();
cout }
}
}
}
}
}

The program builds fine without errors. But while executing it,
the lines after the cout statement - "Circular hole's wire is on face# , wire# " don't get displayed on the result window. In other words, it displays the face# and the wire# of the circular hole's wire but it doesn't execute the subsequent lines. I tried "C1.IsNull()" & "C2.IsNull()" instead of "!C1.IsNull()" & "!C2.IsNull()", but that gave the exact same result.

I also tried testing the curve DynamicType using Daniel Kelley's code. But, doing this gave the error message - "error C2065: 'Geom_BezierCurve_Type_' : undeclared identifier" and so on for 'Geom_BSplineCurve', 'Geom_TrimmedCurve' and all the other curve types.

Does anybody have the code for getting the radius and depth of a circular hole in a cuboid? If you could give me the code, I would greatly appreciate it as I have been struggling with this for way too long now.

Thanks once again!

P Dolbey's picture

To resolve the 'Geom_BezierCurve_Type_', you need to a #include , or and so on for the other Geom classes. I didn't think you'd need these for your algo, as you must already have included and this was the only case you were looking for.

Pete

Stephane Routelous's picture

you cannot TopoDS::Edge(wire)
you have to use TopExp_Explorer to explore the wire to get the edges

Stephane

MechEngr's picture

Pete and Stephane,

Thanks once again for your replies. I tried using TopExp_Explorer to explore the wire to get the edges, as follows:

// iterating through each face in the model
for(i=1; i {
TopoDS_Face face=TopoDS::Face(faces.FindKey(i));

// getting all wires in the face and outerwire
TopTools_IndexedMapOfShape wires;
TopExp::MapShapes(face, TopAbs_WIRE, wires);
TopoDS_Wire outerWire=BRepTools::OuterWire(face);

// iterating through each wire in the faces
for(j=1; j {
TopoDS_Wire wire=TopoDS::Wire(wires.FindKey(j));

if(wire!=outerWire)
{
cout Standard_Real R,U1,U2;
TopExp_Explorer exp;
for (exp.Init(wire,TopAbs_EDGE); exp.More(); exp.Next())
{
Handle (Geom_Curve) C1 = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), U1, U2);
if (! C1.IsNull())
{
Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C1);
if (! C2.IsNull())
{
R = C2->Circ().Radius();
cout }
}
}
}
}
}

The program builds fine without errors. But while executing it,
the lines after the cout statement - "Circular hole's wire is on face# , wire# " don't get displayed on the result window. In other words, it displays the face# and the wire# of the circular hole's wire but it doesn't execute the subsequent lines. I tried "C1.IsNull()" & "C2.IsNull()" instead of "!C1.IsNull()" & "!C2.IsNull()", but that gave the exact same result.

I also tried testing the curve DynamicType using Daniel Kelley's code. But, doing this gave the error message - "error C2065: 'Geom_BezierCurve_Type_' : undeclared identifier" and so on for 'Geom_BSplineCurve', 'Geom_TrimmedCurve' and all the other curve types.

Does anybody have the code for getting the radius and depth of a circular hole in a cuboid? If you could give me the code, I would greatly appreciate it as I have been struggling with this for way too long now.

Thanks once again!

Bearloga's picture

What is the source of your shape? If you imported it from other system (e.g. by iges reader) then it is probably that the edges of the shape do not contain curves 3d (but only 2d curves on surfaces). In this case try to build 3d curves using shape healing. Or, another way (and it is better) is to use 2d curves to retrieve radius (use BRep_Tool::CurveOnSurface).

MechEngr's picture

Hi Bearloga,

Yes my OpenCascade shape was created by translating all the faces in an IGES file, using IGESControl_Reader.

I tried your second method (BRep_Tool::CurveOnSurface), but it still does not work. Here is what I did:

if(wire!=outerWire)
{
Standard_Real R,U1,U2;
TopExp_Explorer exp;

for (exp.Init(wire,TopAbs_EDGE); exp.More(); exp.Next())
{
TopoDS_Edge tmpEdge=TopoDS::Edge(exp.Current());
Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(tmpEdge,face,U1,U2);
Handle (Geom_Circle) C2 = Handle (Geom_Circle)::DownCast(C1);
R = C2->Circ().Radius();
cout }
}

When I execute it, I get an Internet Explorer error (".exe has encountered a problem and needs to close. We are sorry for the inconvenience." All the lines upto this piece of code get executed.

What kind of parameters are U1 and U2? Is there any function for getting the radius of a Geom2d_Curve (like C2->Circ().Radius() in the case of Geom_Circle)?

Stephane Routelous's picture

1/ you cannot downcast a 2d curve into a 3d circle
use Geom2d_Circle instead of Geom_Circle
2/ it crashs because you don't test C1.IsNull() or C2.IsNull()
3/well, maybe it's not a circle, but the iges translation converted it into bspline ...

Stephane

MechEngr's picture

Stephane,

Yes, it turns out that it was in fact the IGES translation was converting it to BSpline. I am able to get the radius now. I am currently working on getting the depth of the circular hole. If I am unsuccessful, I shall post in this thread again.

Thank you once again !!