BrepMesh::Mesh, unit outward normal

Hello everyone,

I'm using BrepMesh::Mesh to triangulate the faces of a solid, and BRrep_Tool::Triangulation to extract the triangles for a given face.

What would be correct method to determine the unit outward normal to a triangle?

That is, what would be the correct way to determine the sign of the normal, if it should point outwards? Is it possible to deduce this information from the orientation of the vertices?

Thank you for your patience,
Mikko Lyly

Steve Lockley's picture

I think you can get the orientation of the face and check if it is reversed, if it is then the face normal is reversed.
I simply reverse the triangle vertices to align it outwards like this

const Poly_Array1OfTriangle& triangles = facing->Triangles();
Standard_Integer nbTriangles = 0, n1, n2, n3;
nbTriangles = facing->NbTriangles();
for(Standard_Integer tr = 1 ; tr <= nbTriangles ; tr++)
triangles(tr).Get(n1, n2, n3);
TopAbs_Orientation orient = face.Orientation();

if(orient == TopAbs_REVERSED)


TriangleIndices is my own function to pass out the triangle.
Hope this helps

MikkoL's picture

Thank you for the information, it was exactly what I was looking for.

Best regards,

Ling's picture

my email adress:
i hope i can get you help! Thank you very much
Best regard

Ling's picture

hello , i am a student. and i have a task that iges/step to stl.

when iges to stl , i find that some face's normal is reversed, and the problem i think is flow:
face.Orientation() is always TopAbs_FORWARD,

but , when step to stl , it's fine. the face normal is right.
can you give me some advise ,,thank you very much.

this is my code:
TopoDS_Shape shape = Reader.OneShape();
double const deflection = 0.5;
double const angulardeflection = 0.5;
BRepMesh_IncrementalMesh discr(shape, deflection, false, angulardeflection); //shape or face

TopoDS_Face face;

for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next())
TopoDS_Face face = TopoDS::Face(ex.Current());
TopLoc_Location loc;

BRepAdaptor_Surface sf(face, Standard_False);
BRepLProp_SLProps prop(sf, 1, 1e-5);

Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc);

//Handle(Poly_Triangulation) triangulation1 = BRepTools::Triangulation(face, 0.01);

if (!triangulation.IsNull())
gp_Pnt2d uv;
gp_Pnt pnt;
gp_Vec nn;

int ntriangles = triangulation -> NbTriangles();
int npoints = triangulation->NbNodes();

const TColgp_Array1OfPnt& aNodes = triangulation->Nodes();
int num = aNodes.Length();

TColgp_Array1OfPnt aPoints(1, aNodes.Length());
for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)
aPoints(i) = aNodes(i).Transformed(loc);

mesh.add_vertex( TNOMS3D::OPoint( aPoints(i).X(), aPoints(i).Y(), aPoints(i).Z() ) );

const Poly_Array1OfTriangle& triangles =triangulation ->Triangles();

Standard_Integer v1,v2,v3;
for (int j = 1; j <= ntriangles; j++)
if (face.Orientation() == TopAbs_REVERSED)
mesh.add_face( OpenMesh::VertexHandle(index+v1-1), OpenMesh::VertexHandle(index+v2-1), OpenMesh::VertexHandle(index+v3-1));
mesh.add_face( OpenMesh::VertexHandle(index+v1-1), OpenMesh::VertexHandle(index+v2-1), OpenMesh::VertexHandle(index+v3-1));

//mesh.add_face( OpenMesh::VertexHandle(v1-1), OpenMesh::VertexHandle(v2-1), OpenMesh::VertexHandle(v3-1));

Poly_Triangle triangle = (triangulation -> Triangles())(j);
//gp_Vec nn[3];
for(int k=1; k<=3; k++)
uv = (triangulation -> UVNodes())(triangle(k));
prop.SetParameters (uv.X(), uv.Y());

if (prop.IsNormalDefined())
nn = prop.Normal();
// n = gp_Vec (0,0,0);
gp_Vec a(aPoints(v1),aPoints(v2));
gp_Vec b(aPoints(v1),aPoints(v3));
nn = b^a;
if (face.Orientation() == TopAbs_REVERSED) nn *= -1;

if( k==1 )
mesh.set_normal( OpenMesh::VertexHandle(index+v1-1),TNOMS3D::ONormal(nn.X(),nn.Y(),nn.Z()) );
if( k==2 )
mesh.set_normal( OpenMesh::VertexHandle(index+v2-1),TNOMS3D::ONormal(nn.X(),nn.Y(),nn.Z()) );
if( k==3 )
mesh.set_normal( OpenMesh::VertexHandle(index+v3-1),TNOMS3D::ONormal(nn.X(),nn.Y(),nn.Z()) );

index = index+npoints;