I want to calculate (and display) a normal for each triangle.

hello
I want to calculate and display each nodes and normal for each triangle.
What is the easiest way to get the normal of each triangle?
Here's the code I'm using to tesselate and display the TopoDS_Shape:

BRepMesh::Mesh(tshape,1);
BRep_Builder builder;
TopoDS_Compound Comp;
builder.MakeCompound(Comp);

for (TopExp_Explorer ex(tshape,TopAbs_FACE) ; ex.More(); ex.Next()) {

TopoDS_Face F =TopoDS::Face(ex.Current());
TopLoc_Location L;
Handle (Poly_Triangulation) facing = BRep_Tool::Triangulation(F,L);
TColgp_Array1OfPnt tab(1,(facing->NbNodes()));
tab = facing->Nodes();
Poly_Array1OfTriangle tri(1,facing->NbTriangles());
tri = facing->Triangles();

for (Standard_Integer i=1;iNbTriangles());i++) {
Poly_Triangle trian = tri.Value(i);
Standard_Integer index1,index2,index3,M,N;
trian.Get(index1,index2,index3);

for (Standard_Integer j=1;j switch (j) {
case 1 :
M = index1;
N = index2;
break;
case 2 :
N = index3;
break;
case 3 :
M = index2;
}

BRepBuilderAPI_MakeEdge ME(tab.Value(M),tab.Value(N));
if (ME.IsDone())
{
builder.Add(Comp,ME.Edge());
}
}
}
}
Handle_AIS_Shape atriangulation = new AIS_Shape(Comp);
myAISContext->SetDisplayMode(atriangulation,0);
myAISContext->SetColor(atriangulation,Quantity_NOC_WHITE);
myAISContext->Display(atriangulation);

Rob Bachrach's picture

Compute the cross product of adjacent edge vectors:

gp_XYZ pt1 = tab.Value(index1).XYZ();
gp_XYZ pt2 = tab.Value(index2).XYZ();
gp_XYZ pt3 = tab.Value(index3).XYZ();

gp_XYZ v1 = pt2-pt1;
gp_XYZ v2 = pt3-pt2;

gp_XYZ normal = v1^v2;

ashu106's picture

thanks...Rob Bachrach
I want to calculate the no of traingles and colour each triangles .i can select each triangle with this code but can't count ...
using this code for selecting the triangle
/meshing part here//////
Standard_Real aDeflection=0.3;
// aDeflection = ... ;

// removes all the triangulations of the faces ,
//and all the polygons on the triangulations of the edges:
BRepTools::Clean(aCyl);

// adds a triangulation of the shape aShape with the deflection aDeflection:
BRepMesh::Mesh(aCyl,aDeflection);

TopExp_Explorer aExpFace,aExpEdge;
for(aExpFace.Init(aCyl,TopAbs_FACE);aExpFace.More();aExpFace.Next())
{
TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
TopLoc_Location aLocation;

// takes the triangulation of the face aFace:
Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);

if(!aTr.IsNull()) // if this triangulation is not NULL
{
// takes the array of nodes for this triangulation:
const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
// takes the array of triangles for this triangulation:
const Poly_Array1OfTriangle& triangles = aTr->Triangles();

// create array of node points in absolute coordinate system
TColgp_Array1OfPnt aPoints(1, aNodes.Length());
for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)
aPoints(i) = aNodes(i).Transformed(aLocation);

// Takes the node points of each triangle of this triangulation.
// takes a number of triangles:
Standard_Integer nnn = aTr->NbTriangles();
Standard_Integer nt,n1,n2,n3;
for( nt = 1 ; nt < nnn+1 ; nt++)
{
// takes the node indices of each triangle in n1,n2,n3:
triangles(nt).Get(n1,n2,n3);
// takes the node points:
gp_Pnt aPnt1 = aPoints(n1);
gp_Pnt aPnt2 = aPoints(n2);
gp_Pnt aPnt3 = aPoints(n3);

Handle(Geom_TrimmedCurve) meshSegment1 = GC_MakeSegment(aPnt1 , aPnt2);

Handle(Geom_TrimmedCurve) meshSegment2 = GC_MakeSegment(aPnt1 , aPnt3);

Handle(Geom_TrimmedCurve) meshSegment3 = GC_MakeSegment(aPnt2 , aPnt3);

TopoDS_Edge meshEdge1 = BRepBuilderAPI_MakeEdge(meshSegment1);

TopoDS_Edge meshEdge2 = BRepBuilderAPI_MakeEdge(meshSegment2);

TopoDS_Edge meshEdge3 = BRepBuilderAPI_MakeEdge(meshSegment3);

BRepBuilderAPI_MakeWire meshWire(meshEdge1 , meshEdge3 , meshEdge2);

Handle(AIS_Shape) anAISShape = new AIS_Shape(meshWire.Shape());

// context->Display( anAISShape, false );

// Takes the polygon associated to an edge.
aExpEdge.Init(aFace,TopAbs_EDGE);
TopoDS_Edge aEdge;
// for example,working with the first edge:
if(aExpEdge.More())
aEdge = TopoDS::Edge(aExpEdge.Current());

if(!aEdge.IsNull()) // if this edge is not NULL
{
// takes the polygon associated to the edge aEdge:
Handle_Poly_PolygonOnTriangulation aPol =
BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());

if(!aPol.IsNull()) // if this polygon is not NULL
// takes the array of nodes for this polygon
// (indexes in the array of nodes for triangulation of theFace):
const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();
}
{

context->Display( anAISShape, false );
}
}

Sharjith Naramparambath's picture

Hi Ashu,
From the code you have written you can get the number of triangles from the code fragment...

// Takes the node points of each triangle of this triangulation.
// takes a number of triangles:
Standard_Integer nnn = aTr->NbTriangles();

this function (NbTriangles()) is actually giving you the number of triangles in the triangulation.

I would also suggest you to add the triangles you construct to the BRepBuilder and make a TopoDS_Compound instead of displaying them directly using multiple AIS_Shapes. For individual selection of the triangles, you can activate the TopABS_FACE selection mode by opening a local context later when required.

For coloring each triangle you can make a custom class derived from AIS_Shape. (See the UserCylinder example). You can Redefine the Compute method to assign color to each triangle (face) as per the properties of Normale etc.

Hope this helps.

Regards
N. Sharjith