0024428: Implementation of LGPL license
[occt.git] / src / AIS / AIS_Triangulation.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and / or modify it
6 // under the terms of the GNU Lesser General Public version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <AIS_Drawer.hxx>
15 #include <AIS_Triangulation.hxx>
16 #include <AIS_InteractiveObject.hxx>
17 #include <Standard_DefineHandle.hxx>
18 #include <Poly_Array1OfTriangle.hxx>
19 #include <Poly_Triangulation.hxx>
20 #include <Prs3d_Root.hxx>
21 #include <Prs3d_ShadingAspect.hxx>
22 #include <TShort_Array1OfShortReal.hxx>
23 #include <TColgp_Array1OfPnt.hxx>
24 #include <TColStd_HArray1OfInteger.hxx>
25 #include <TShort_HArray1OfShortReal.hxx>
26 #include <Graphic3d_Group.hxx>
27 #include <Graphic3d_AspectFillArea3d.hxx>
28 #include <Graphic3d_ArrayOfTriangles.hxx>
29
30
31 IMPLEMENT_STANDARD_HANDLE(AIS_Triangulation, AIS_InteractiveObject)
32 IMPLEMENT_STANDARD_RTTIEXT(AIS_Triangulation, AIS_InteractiveObject)
33
34 AIS_Triangulation::AIS_Triangulation(const Handle(Poly_Triangulation)& Triangulation)
35 {
36   myTriangulation = Triangulation;
37   myNbNodes       = Triangulation->NbNodes();
38   myNbTriangles   = Triangulation->NbTriangles();
39   myFlagColor     = 0;
40 }
41
42 //=======================================================================
43 //function : Compute
44 //purpose  :
45 //=======================================================================
46 void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
47                                 const Handle(Prs3d_Presentation)& aPresentation,
48                                 const Standard_Integer aMode)
49 {
50   switch (aMode) 
51   {
52     case 0:
53       const TColgp_Array1OfPnt& nodes = myTriangulation->Nodes();             //Nodes
54       const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();  //Triangle
55
56       Standard_Boolean hasVNormals = myTriangulation->HasNormals();
57       Standard_Boolean hasVColors  = (myFlagColor == 1);
58
59       Handle(Graphic3d_ArrayOfTriangles) anArray =
60          new Graphic3d_ArrayOfTriangles ( myNbNodes,        //maxVertexs
61                                           myNbTriangles * 3,//maxEdges
62                                           hasVNormals,      //hasVNormals
63                                           hasVColors,       //hasVColors
64                                           Standard_False,   //hasTexels
65                                           Standard_True     //hasEdgeInfos
66                                          );
67       Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
68       Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
69
70       Standard_Integer i;
71       Standard_Integer j;
72
73       Standard_Real ambient = aspect->FrontMaterial().Ambient();
74       if (hasVNormals)
75       {
76         const TShort_Array1OfShortReal& normals = myTriangulation->Normals();
77         if (hasVColors)
78         {
79           const TColStd_Array1OfInteger& colors = myColor->Array1();
80           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
81           {
82             j = (i - nodes.Lower()) * 3;
83             anArray->AddVertex(nodes(i), AttenuateColor(colors(i), ambient));
84             anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
85           }
86         }
87         else // !hasVColors
88         {
89           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
90           {
91             j = (i - nodes.Lower()) * 3;
92             anArray->AddVertex(nodes(i));
93             anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
94           }
95         }
96       }
97       else // !hasVNormals
98       {
99         if (hasVColors)
100         {
101           const TColStd_Array1OfInteger& colors = myColor->Array1();
102           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
103           {
104             anArray->AddVertex(nodes(i), AttenuateColor(colors(i), ambient));
105           }
106         }
107         else // !hasVColors
108         {
109           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
110           {
111             anArray->AddVertex(nodes(i));
112           }
113         }
114       }
115
116       Standard_Integer indexTriangle[3] = {0,0,0};
117       for ( i = triangles.Lower(); i<= triangles.Upper(); i++ ) {
118         triangles(i).Get(indexTriangle[0], indexTriangle[1], indexTriangle[2]);
119         anArray->AddEdge(indexTriangle[0]);
120         anArray->AddEdge(indexTriangle[1]);
121         anArray->AddEdge(indexTriangle[2]);
122       }
123       TheGroup->SetPrimitivesAspect(aspect);
124       TheGroup->AddPrimitiveArray(anArray);
125       break;
126   }
127 }
128
129 //=======================================================================
130 //function : ComputeSelection
131 //purpose  : 
132 //=======================================================================
133 void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& /*aSelection*/,
134                                          const Standard_Integer /*aMode*/)
135 {
136
137 }
138
139 //=======================================================================
140 //function : SetColor
141 //purpose  : Set the color for each node.
142 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
143 //           Order of color components is essential for further usage by OpenGL
144 //=======================================================================
145 void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
146 {
147   myFlagColor = 1;
148   myColor = aColor;
149 }
150
151 //=======================================================================
152 //function : GetColor
153 //purpose  : Get the color for each node.
154 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
155 //           Order of color components is essential for further usage by OpenGL
156 //=======================================================================
157
158 Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
159 {
160   return myColor;
161 }
162
163
164 //=======================================================================
165 //function : SetTriangulation
166 //purpose  : 
167 //=======================================================================
168 void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
169 {
170   myTriangulation = aTriangulation;
171 }
172
173 //=======================================================================
174 //function : GetTriangulation
175 //purpose  : 
176 //=======================================================================
177 Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
178   return myTriangulation;
179 }
180
181 //=======================================================================
182 //function : AttenuateColor
183 //purpose  : Attenuates 32-bit color by a given attenuation factor (0...1):
184 //           aColor = Alpha << 24 + Blue << 16 + Green << 8 + Red
185 //           All color components are multiplied by aComponent, the result is then packed again as 32-bit integer.
186 //           Color attenuation is applied to the vertex colors in order to have correct visual result 
187 //           after glColorMaterial(GL_AMBIENT_AND_DIFFUSE). Without it, colors look unnatural and flat.
188 //=======================================================================
189
190 Standard_Integer AIS_Triangulation::AttenuateColor( const Standard_Integer aColor,
191                                                     const Standard_Real aComposition)
192 {
193   Standard_Integer  red,
194                     green,
195                     blue,
196                     alpha;
197
198   alpha = aColor&0xff000000;
199   alpha >>= 24;
200
201   blue = aColor&0x00ff0000;
202   blue >>= 16;
203
204   green = aColor&0x0000ff00;
205   green >>= 8;
206
207   red = aColor&0x000000ff;
208   red >>= 0; 
209
210   red   = (Standard_Integer)(aComposition * red);
211   green = (Standard_Integer)(aComposition * green);
212   blue  = (Standard_Integer)(aComposition * blue);
213
214   Standard_Integer  color;
215   color = red;
216   color += green << 8;
217   color += blue  << 16; 
218   color += alpha << 24;
219   return color;
220 }
221