Incorrect Normals While triangulating

Hi,

I am using OCCT660 to convert an IGES format to OpenSceneGraph Format. I am having troubles calculating normals for each triangle.
here is the code that I am using to calculate normals of triangle.

Handle (Poly_Triangulation) triangulation = BRep_Tool::Triangulation(face, location);
if (!triangulation.IsNull())
{
int noOfNodes = triangulation->NbNodes();

// Store vertices. Build vertex array here
for(int j = 1; j NbNodes(); j++)
{
// populate vertex list
// Ref: http://www.opencascade.org/org/forum/thread_16694/?forum=3
gp_Pnt pt = (triangulation->Nodes())(j).Transformed(transformation * location.Transformation());
vertexList->push_back(osg::Vec3(pt.X(), pt.Y(), pt.Z()));

// calculate normal method 1
gp_Pnt2d uv;
gp_Vec normal;
gp_Pnt pos;
uv = (triangulation->UVNodes())(j);
faceProperty.Normal(uv.X(), uv.Y(), pos, normal);

// normal.Normalize();
normalList->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z()));

// populate color list
colorList->push_back(geomColor);
}
....
....
}

Here most of the time i get normal as (0,0,0) resulting in a crash in normalization. I am attaching the result for your reference.

Thank You
-Abhishek

Abhishek Bansal's picture

I tried solution given in following thread but that also is not working for me..
http://www.opencascade.org/org/forum/thread_12568/?forum=3

Abhishek Bansal's picture

I tried to use code from Ling's question from following thread
http://www.opencascade.org/org/forum/thread_9004/?forum=3

I changed my code.. here it is..

Handle (Poly_Triangulation) triangulation = BRep_Tool::Triangulation(face, location);
if (!triangulation.IsNull())
{
int noOfNodes = triangulation->NbNodes();

// Store vertices. Build vertex array here
for(int j = 1; j <= triangulation->NbNodes(); j++)
{
// populate vertex list
// Ref: http://www.opencascade.org/org/forum/thread_16694/?forum=3
gp_Pnt pt = (triangulation->Nodes())(j).Transformed(transformation * location.Transformation());
vertexList->push_back(osg::Vec3(pt.X(), pt.Y(), pt.Z()));

// populate color list
colorList->push_back(geomColor);
}

/// now we need to get face indices for triangles
// get list of triangle first
const Poly_Array1OfTriangle& triangles = triangulation->Triangles();

//No of triangles in this triangulation
noOfTriangles = triangulation->NbTriangles();

Standard_Integer v1, v2, v3;
for (unsigned int j = 1; j <= noOfTriangles; j++)
{
bool flip = false;
/// If face direction is reversed then we add verticews in reverse order
/// order of vertices is important for normal calculation later
if (face.Orientation() == TopAbs_REVERSED)
{
triangles(j).Get(v1, v3, v2);
flip = true;
}
else
{
triangles(j).Get(v1, v2, v3);
}
triangleStrip->push_back(index + v1 - 1);
triangleStrip->push_back(index + v2 - 1);
triangleStrip->push_back(index + v3 - 1);

Poly_Triangle triangle = (triangulation -> Triangles())(j);

for(int k=1; k<=3; k++)
{
gp_Pnt2d uv;
gp_Vec nn;
uv = (triangulation -> UVNodes())(triangle(k));
prop.SetParameters (uv.X(), uv.Y());

if (prop.IsNormalDefined())
nn = prop.Normal();
else
{
osg::Vec3 op1 = vertexList->at(index + v1 - 1);
osg::Vec3 op2 = vertexList->at(index + v2 - 1);
osg::Vec3 op3 = vertexList->at(index + v3 - 1);

osg::Vec3 n1 = op2-op1;
osg::Vec3 n2 = op3-op2;

osg::Vec3 normal = n1^n2;
nn.SetX(0);
nn.SetY(0);
nn.SetZ(0);
}
if (face.Orientation() == TopAbs_REVERSED)
nn *= -1;

normalList->push_back(osg::Vec3(nn.X(),nn.Y(),nn.Z()));
normalList->push_back(osg::Vec3(nn.X(),nn.Y(),nn.Z()));
normalList->push_back(osg::Vec3(nn.X(),nn.Y(),nn.Z()));
}
}
index = index + noOfNodes;
}
}

The normals are again wrong. I have attached image for your reference.

Sébastien Raymond's picture

Hi,

If you want to access to vertexes formals, you can use Poly_Triangulation::Normals method, C.f. documentation.
Then if you really want to use the triangle face normal, the cross product of the 2 vectors composed by the triangle vertexes is should do the trick.

Abhishek Bansal's picture

Hi,

Thanks for youe reply !

Poly_Triangulation HasNormals() method always return false for me. I checked with multiple models.

Thank You
Abhishek

Sébastien Raymond's picture

Have a look to Poly::ComputeNormals(const Handle(Poly_Triangulation)&Tri)

Shing Liu's picture

Have a look StlTransfer.cxx,
There is a function: Normal() to calculate the normals for the triangualtion.

Junjie Xue's picture

Hi Abhishek,

I met the same problem when i tried to visulization the model in OSG using Triangulation. Have you found a solution to it? I am attaching my result for your reference.

Thank you!
-Junjie Xue

Attachments: 
jan.benscheid_144368's picture

Hi,
I know this thread is old, but for anyone is still experiencing this issue: Flipping the normal in case the face is reversed does the job:

gp_Dir normal = triangulation->Normal(i);
normal.Transform(transformation);
if (face.Orientation() == TopAbs_REVERSED)
{
normal = normal.Reversed();
}

Best,
-Jan