wrong normal directions by use BRepLProp_SLProps

This is part of my code, and I got some wrong normal directions by use BRepLProp_SLProps,
Can you give me some advice?thanks a lot

 

 

for (faceExplorer.Init(aShape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next())
{

TopLoc_Location loc ;
TopoDS_Face aFace = TopoDS::Face(faceExplorer.Current());
Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(aFace, loc);
BRepLProp_SLProps theProp(BRepAdaptor_Surface(aFace), 1, Precision::Confusion());

if (triFace.IsNull()) continue;

Standard_Boolean hasNormal = triFace->HasNormals();
Standard_Boolean hasuvNormal = triFace->HasUVNodes();

Standard_Integer l = triFace->Nodes().Length();
Standard_Integer nTriangles = triFace->NbTriangles();

TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
Poly_Array1OfTriangle triangles(1, triFace->NbTriangles());
nodes = triFace->Nodes();
triangles = triFace->Triangles();

BRepAdaptor_Surface S;
S.Initialize(aFace, Standard_False);

for (Standard_Integer i = 1; i <= nTriangles; i++)
{
Poly_Triangle aTriangle = triangles.Value(i);
aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);

vertex1 = nodes.Value(nVertexIndex1).Transformed(loc.Transformation());
vertex2 = nodes.Value(nVertexIndex2).Transformed(loc.Transformation());
vertex3 = nodes.Value(nVertexIndex3).Transformed(loc.Transformation());

gp_Pnt2d theUV1 = triFace->UVNodes().Value(aTriangle(1));
gp_Pnt2d theUV2 = triFace->UVNodes().Value(aTriangle(2));
gp_Pnt2d theUV3 = triFace->UVNodes().Value(aTriangle(3));

positionBuffer.push_back(aiVector3D());
aiVector3D* vt1 = &positionBuffer.back();
vt1->x = vertex1.X();
vt1->y = vertex1.Y();
vt1->z = vertex1.Z();

positionBuffer.push_back(aiVector3D());
aiVector3D* vt2 = &positionBuffer.back();
vt2->x = vertex2.X();
vt2->y = vertex2.Y();
vt2->z = vertex2.Z();

positionBuffer.push_back(aiVector3D());
aiVector3D* vt3 = &positionBuffer.back();
vt3->x = vertex3.X();
vt3->y = vertex3.Y();
vt3->z = vertex3.Z();

// find the normal for the triangle mesh.

gp_Vec V12(vertex1, vertex2);
gp_Vec V13(vertex1, vertex3);
gp_Vec theNormal = V12 ^ V13;
gp_Vec theNormal1 = theNormal;
gp_Vec theNormal2 = theNormal;
gp_Vec theNormal3 = theNormal;
if (theNormal.Magnitude() > Precision::Confusion())
{
theNormal.Normalize();
theNormal1.Normalize();
theNormal2.Normalize();
theNormal3.Normalize();
}

theProp.SetParameters(theUV1.X(), theUV1.Y());
if (theProp.IsNormalDefined())
{
theNormal1 = theProp.Normal();
}

theProp.SetParameters(theUV2.X(), theUV2.Y());
if (theProp.IsNormalDefined())
{
theNormal2 = theProp.Normal();
}

theProp.SetParameters(theUV3.X(), theUV3.Y());
if (theProp.IsNormalDefined())
{
theNormal3 = theProp.Normal();
}

if (aFace.Orientation() == TopAbs_REVERSED)
{
theNormal.Reverse();
theNormal1.Reverse();
theNormal2.Reverse();
theNormal3.Reverse();
}

normalBuffer.push_back(aiVector3D());
aiVector3D* vn1 = &normalBuffer.back();
vn1->x = theNormal1.X();
vn1->y = theNormal1.Y();
vn1->z = theNormal1.Z();

normalBuffer.push_back(aiVector3D());
aiVector3D* vn2 = &normalBuffer.back();
vn2->x = theNormal2.X();
vn2->y = theNormal2.Y();
vn2->z = theNormal2.Z();

normalBuffer.push_back(aiVector3D());
aiVector3D* vn3 = &normalBuffer.back();
vn3->x = theNormal3.X();
vn3->y = theNormal3.Y();
vn3->z = theNormal3.Z();

}
}

Guido van Hilst not specified's picture

In addition to reversing the normal depending on the face orientation, you must also reverse the winding order of the vertices if the orientation is reversed:

You can do that by flipping two indices of the triangle:


OCTopoDS_Face face = ....

OCTopLoc_Location faceLocation = face.Location();

OCPoly_Triangulation tri = OCBRep_Tool.Triangulation(face, faceLocation);
OCgp_Trsf faceTransformation = faceLocation.Transformation();

bool reversed = face.Orientation() == OCTopAbs_Orientation.TopAbs_REVERSED;

OCPoly_Triangle triangle = triangles.Value (i);
int n1 = 0, n2 = 0, n3 = 0;

triangle.Get (ref n1, ref n2, ref n3);

if (reversed)
{
	int tmp = n1;
	n1 = n2;
	n2 = tmp;
}


OCgp_Pnt p1 = nodes.Value(n1).Transformed(faceTransformation);
OCgp_Pnt p2 = nodes.Value(n2).Transformed(faceTransformation);
OCgp_Pnt p3 = nodes.Value(n3).Transformed(faceTransformation);

See C# example here: MeshFromShape