Exploring faces and edges in an IGES file

Hello,

I've been trying to solve a problem for almost 2 months now and figured it was worth posting here to see if anyone could help.

I'm trying to write an IGES reader for a mesher. All I need to do is write functions to read the file, list all the surfaces and curves, do some parametric conversions, and then relate the curves to the surfaces.

To debug my code I've made a cube in solid works and saved it as an IGES file.

It's easiest to explain my problems with my code so here it goes...

class OCCT_FLITE
{
//This class contains functions to communicate between //OCCT and FLITE
private:
IGESControl_Reader reader;
Standard_Integer nshapes;
Standard_Integer ncurves;
Standard_Integer nsurfaces;

TopTools_IndexedMapOfShape edgemap, facemap;

public:

void OCCT_LoadGeom(Standard_CString filename)
{
//This function reads the geometry file and translates to //OCCT

//reads file
IFSelect_ReturnStatus stat = reader.ReadFile(filename);

//check file
IFSelect_PrintCount mode = IFSelect_ItemsByEntity;
reader.PrintCheckLoad(Standard_False,mode);

//Translate to OCCT
reader.TransferRoots();

//Store these in a single compound shape
TopoDS_Shape shape;
shape = reader.OneShape();
BRepTools::Clean(shape);
//Split into two indexed maps, edgemap and facemap
//edgemap(i) gives the ith edge
TopExp::MapShapes(shape,TopAbs_EDGE,edgemap); TopExp::MapShapes(shape,TopAbs_FACE,facemap);

};

The above function reads the file, then I have two functions (below) to report number of surfaces and curves...

Standard_Integer OCCT_GetNumCurves(void)
{
ncurves = edgemap.Extent();
return ncurves;
};

Standard_Integer OCCT_GetNumSurfaces(void)
{
nsurfaces = facemap.Extent();
return nsurfaces;
};

Problem 1: When I read in the cube file I get 6 surfaces (correct) but 24 edges. Really I only want the 12 edges defining the cube, I thought this may have been because each edge was being counted twice (two different orientations), but I don't think this should happen using IndexedMapOfShape?

In the meshing code we need to know which curves are part of given surface. I wrote this function to do this...

Standard_Integer* OCCT_GetSurfaceCurves(Standard_Integer surfNum, Standard_Integer &numCurves)

{
// Returns the number of curves in a suface and their identifiers in
// list

TopoDS_Face anFace = TopoDS::Face(facemap(surfNum));

// Create indexed map of edges
TopTools_IndexedMapOfShape localmap;
TopExp::MapShapes(anFace,TopAbs_EDGE,localmap);

numCurves = localmap.Extent();

Standard_Integer* list;
list = (Standard_Integer*) calloc((numCurves),sizeof(Standard_Integer ));

// Now need to find the indices of curves in this local //map in the
// global map

//NOTE: Irritatingly indices in C++ start at 0 and in //OPENCascade they
//start at 1

int count = 0;
for (count =0; count {

//Get the edge
TopoDS_Edge anEdge = TopoDS::Edge(edgemap(count+1));

list[count] = edgemap.FindIndex(anEdge);
//cout

};

return list;

};

Problem 2: Whatever value I give surfNum in the above function I always get 4 edges, and the indices returned are always 1,2,3,4

I have a feeling my problem is something to do with topology vs geometry, but I'm struggling to find documentation or examples to help me. If anyone could help I would really appricate it. I hope I've included enough information. I've attached my C++ source file to the post.

sean.walton84's picture

Just noticed I've posted this in the installation forum, I meant to post it in usage issues, could a mod move it?

Hennig's picture

Hey Sean,

i didnt check your code. But when you want to read some good articles about topology and geometry in OCC loo here: http://opencascade.wikidot.com/romansarticles

hope this will help you.
Paul

sean.walton84's picture

Thanks for the reply Paul.

I read those, and most of his blog, before I started - which is why I'm confused my stuff isn't working. I'm re-reading all the documentation now to see if I missed something!

Roman Lygin's picture

Hi Sean,

Your #1 is most likely due to the fact that all your faces are topologically disconnected. So instead of 12 unique edges with 2 instances per each you really have 24 unique edges. This most likely comes from upstream - from your IGES file, where all faces are likely written as Type 144 Trimmed Surfaces. To address that you can:
- instruct your sending system (Solidworks) to use IGES version 5.1 and MSBO (Manifold-Solid-BRep-Objects) in order to store connectivity
- use STEP
- apply sewing in Open CASCADE.
The latter is time consuming and is sensitive to input geometry.

#2 is because you explore a wrong map. You should be exploring the local map and search for indices in the global.
As for "irritating" index numbering an easy work-around is to offset your pointer first:

--list;
for (int count =1; count <= numCurves; count++)
{

//Get the edge
const TopoDS_Edge& anEdge = TopoDS::Edge(localmap(count));

list[count] = edgemap.FindIndex(anEdge);
//cout << edgemap.FindIndex(anEdge) << "\n";

};

Good luck!
Roman

sean.walton84's picture

Thanks for the reply, I'll have a play this afternoon.

I'm going to suggest using STEP to my boss, I've seen other people have problems using IGES.

...didn't realise I'd left that irritating comment in there, wrote it in after I'd spend ages trying to figure out why I was getting weird errors due to wrong indexing on my part!

sean.walton84's picture

Also I feel slightly silly about problem #2 - strange how you never see those little errors

Roman Lygin's picture

This is when peer code review helps ;-)

sean.walton84's picture

Everything in my code now works, huzzah! Fixing those bugs helped me quickly debug the other problems I was having (which I didn't post here)

Well, it all works if I import STEP files! Now I've got to convince my boss STEP is enough...

Roman Lygin's picture

Congrats!