Fix faces with error orientation

I have a .iges file, which contains faces with error orientation. That is, some faces point inside, while others point outside.

I convert it to obj and get 001.png.

I sew faces and get 002.png.

I sew faces and then combine shells to a solid and get 003.png, which is still not correct.

What shoud I do to fix those faces?



Kirill Gavrilov's picture

Sharing a model (input IGES, sewed results and created Solid in .BREP format) would be useful to make any comment.

dade huang's picture

This is another .igs file which has similar problems.

Actually, I found that many .igs models have faces with error orientation.

Like 004.png and 005.png. Maybe this is an common issue for igs files.

Here is my code:

// import iges file
IGESControl_Reader igesReader = IGESControl_Reader();
Standard_Integer status = igesReader.ReadFile(file);
// get shape
TopoDS_Shape igesTopoShape = igesReader.OneShape();
// sewing the shape
BRepBuilderAPI_Sewing sewing = BRepBuilderAPI_Sewing();
TopoDS_Shape sewedShape = sewing.SewedShape();

// try make solid with shells
BRepBuilderAPI_MakeSolid makeSolid;
for (TopExp_Explorer anExp(sewedShape, TopAbs_SHELL); anExp.More(); anExp.Next())
    TopoDS_Shell shell = TopoDS::Shell(anExp.Current());
TopoDS_Solid solid = makeSolid.Solid();

// add left faces
TopoDS_Compound allShapes;
BRep_Builder aBuilder;
aBuilder.Add(allShapes, solid); // add solid
for (TopExp_Explorer anExp(sewedShape, TopAbs_FACE); anExp.More(); anExp.Next())
    TopoDS_Face face = TopoDS::Face(anExp.Current());
    bool faceInSolid = false;
    // check if face is in solid
    for (TopExp_Explorer anExp2(solid, TopAbs_FACE); anExp2.More(); anExp2.Next())
        TopoDS_Face face2 = TopoDS::Face(anExp2.Current());
        if (face == face2)
            faceInSolid = true;
    if (!faceInSolid)
        // face not in solid: add to allShapes
        // not to add face twice
        aBuilder.Add(allShapes, face);

stateof3d_161058's picture

I haven't had any orientation problems with the .igs files before, to be honest

Kirill Gavrilov's picture

Sewing does work for me on a given shape with a reasonable tolerance - wholes between triangulated Faces do not appear and normals are oriented consistently.
Probably you should check the tolerance - algorithm does not sew any faces, only close enough, and geometry tolerance within IGES model might be larger than you expect.

vclose *
# import IGES file
testreadiges 8878777_0.igs i
nbshapes i
# display original shape with oriented normals
incmesh i 1
vinit v1/v1
vnormals i on -length 3 -useMesh -oriented 1
vsetdispmode i 1
vsetcolor i ORANGE4
# export original shape into i.obj file
wavefront i i

# perform sewing with tolerance=1.0
sewing s 1.0 i
nbshapes s
# display sewed shape with oriented normals
incmesh s 1
vinit v2/v1
vnormals s on -length 3 -useMesh -oriented 1
vsetdispmode s 1
vsetcolor s GREEN4
# export sewed shape into s.obj file
wavefront s s

Original shape:

Draw[5]> nbshapes i
Number of shapes in i
 VERTEX    : 72
 EDGE      : 74
 WIRE      : 6
 FACE      : 4
 SHELL     : 0
 SOLID     : 0
 SHAPE     : 157

Result shape (SHELL appeared and several EDGES merged):

Draw[13]> nbshapes s
Number of shapes in s
 VERTEX    : 64
 EDGE      : 66
 WIRE      : 6
 FACE      : 4
 SHELL     : 1
 SOLID     : 0
 SHAPE     : 141
Kirill Gavrilov's picture

Actually, I found that many .igs models have faces with error orientation.

IGES format does not support a proper Solid definition, so that surfaces orientations might be arbitrary and edges between faces duplicated.
This is expected for IGES files, considering limitations of this old format.

STEP format is much more advanced in this aspect and allows preserving correct Solid definition (if it existed in originating CAD software) .
Hence, this format is preferable for data exchange, when possible.

dade huang's picture

THANKS SO MUCH. This really solve my problem. The sewing fixes face orientation problems well if I use a proper tolerance.

BRepBuilderAPI_Sewing sewing = BRepBuilderAPI_Sewing(1.0);
TopoDS_Shape sewedShape= sewing.SewedShape();
Kirill Gavrilov's picture

Note, that 1.0 is just an arbitrary number. Tolerance should be defined based on some other information (like a user input / knowledge of typical models / something else).

stateof3d_161058's picture

Thank you for the detailed explanation, Kirill, as always very informative.