248ff48d8305c8601d9abad920a87e28c7c08f40
[occt.git] / src / AIS / AIS_Triangulation.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #include <AIS_Drawer.hxx>
19 #include <AIS_Triangulation.hxx>
20 #include <AIS_InteractiveObject.hxx>
21 #include <Standard_DefineHandle.hxx>
22 #include <Poly_Array1OfTriangle.hxx>
23 #include <Poly_Triangulation.hxx>
24 #include <Prs3d_Root.hxx>
25 #include <Prs3d_ShadingAspect.hxx>
26 #include <TShort_Array1OfShortReal.hxx>
27 #include <TColgp_Array1OfPnt.hxx>
28 #include <TColStd_HArray1OfInteger.hxx>
29 #include <TShort_HArray1OfShortReal.hxx>
30 #include <Graphic3d_Group.hxx>
31 #include <Graphic3d_AspectFillArea3d.hxx>
32 #include <Graphic3d_ArrayOfTriangles.hxx>
33
34
35 IMPLEMENT_STANDARD_HANDLE(AIS_Triangulation, AIS_InteractiveObject)
36 IMPLEMENT_STANDARD_RTTIEXT(AIS_Triangulation, AIS_InteractiveObject)
37
38 AIS_Triangulation::AIS_Triangulation(const Handle(Poly_Triangulation)& Triangulation)
39 {
40   myTriangulation = Triangulation;
41   myNbNodes       = Triangulation->NbNodes();
42   myNbTriangles   = Triangulation->NbTriangles();
43   myFlagColor     = 0;
44 }
45
46 //=======================================================================
47 //function : Compute
48 //purpose  :
49 //=======================================================================
50 void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
51                                 const Handle(Prs3d_Presentation)& aPresentation,
52                                 const Standard_Integer aMode)
53 {
54   switch (aMode) 
55   {
56     case 0:
57       const TColgp_Array1OfPnt& nodes = myTriangulation->Nodes();             //Nodes
58       const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();  //Triangle
59       const TShort_Array1OfShortReal& normals = myTriangulation->Normals();   //Normal
60
61       Standard_Boolean hasVNormals  = Standard_False;
62       Standard_Boolean hasVColors   = Standard_False;
63       if( normals.Length() > 0 )
64         hasVNormals = Standard_True;
65       if( myFlagColor == 1 )
66         hasVColors = Standard_True; 
67
68       Handle(Graphic3d_ArrayOfTriangles) anArray =
69          new Graphic3d_ArrayOfTriangles ( myNbNodes,        //maxVertexs
70                                           myNbTriangles * 3,//maxEdges
71                                           hasVNormals,      //hasVNormals
72                                           hasVColors,       //hasVColors
73                                           Standard_False,   //hasTexels
74                                           Standard_True     //hasEdgeInfos
75                                          );
76       Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
77       Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
78
79       Standard_Integer i;
80       Standard_Integer j;
81
82       Standard_Real ambient = aspect->FrontMaterial().Ambient();
83       for ( i = nodes.Lower(); i<= nodes.Upper(); i++ ){ 
84         if( myFlagColor == 1 )
85           anArray->AddVertex( nodes(i), AttenuateColor(myColor->Value(i),ambient));
86         if( myFlagColor == 0 )
87           anArray->AddVertex( nodes(i) );
88         j = (i - nodes.Lower()) * 3;
89         anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
90       }
91
92       Standard_Integer indexTriangle[3] = {0,0,0};
93       for ( i = triangles.Lower(); i<= triangles.Upper(); i++ ) {
94         triangles(i).Get(indexTriangle[0], indexTriangle[1], indexTriangle[2]);
95         anArray->AddEdge(indexTriangle[0]);
96         anArray->AddEdge(indexTriangle[1]);
97         anArray->AddEdge(indexTriangle[2]);
98       }
99       TheGroup->SetPrimitivesAspect(aspect);
100       TheGroup->AddPrimitiveArray(anArray);
101       break;
102   }
103 }
104
105 //=======================================================================
106 //function : ComputeSelection
107 //purpose  : 
108 //=======================================================================
109 void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
110                                          const Standard_Integer /*aMode*/)
111 {
112
113 }
114
115 //=======================================================================
116 //function : SetColor
117 //purpose  : Set the color for each node.
118 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
119 //           Order of color components is essential for further usage by OpenGL
120 //=======================================================================
121 void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
122 {
123   myFlagColor = 1;
124   myColor = aColor;
125 }
126
127 //=======================================================================
128 //function : GetColor
129 //purpose  : Get the color for each node.
130 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
131 //           Order of color components is essential for further usage by OpenGL
132 //=======================================================================
133
134 Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
135 {
136   return myColor;
137 }
138
139
140 //=======================================================================
141 //function : SetTriangulation
142 //purpose  : 
143 //=======================================================================
144 void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
145 {
146   myTriangulation = aTriangulation;
147 }
148
149 //=======================================================================
150 //function : GetTriangulation
151 //purpose  : 
152 //=======================================================================
153 Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
154   return myTriangulation;
155 }
156
157 //=======================================================================
158 //function : AttenuateColor
159 //purpose  : Attenuates 32-bit color by a given attenuation factor (0...1):
160 //           aColor = Alpha << 24 + Blue << 16 + Green << 8 + Red
161 //           All color components are multiplied by aComponent, the result is then packed again as 32-bit integer.
162 //           Color attenuation is applied to the vertex colors in order to have correct visual result 
163 //           after glColorMaterial(GL_AMBIENT_AND_DIFFUSE). Without it, colors look unnatural and flat.
164 //=======================================================================
165
166 Standard_Integer AIS_Triangulation::AttenuateColor( const Standard_Integer aColor,
167                                                     const Standard_Real aComposition)
168 {
169   Standard_Integer  red,
170                     green,
171                     blue,
172                     alpha;
173
174   alpha = aColor&0xff000000;
175   alpha >>= 24;
176
177   blue = aColor&0x00ff0000;
178   blue >>= 16;
179
180   green = aColor&0x0000ff00;
181   green >>= 8;
182
183   red = aColor&0x000000ff;
184   red >>= 0; 
185
186   red   = (Standard_Integer)(aComposition * red);
187   green = (Standard_Integer)(aComposition * green);
188   blue  = (Standard_Integer)(aComposition * blue);
189
190   Standard_Integer  color;
191   color = red;
192   color += green << 8;
193   color += blue  << 16; 
194   color += alpha << 24;
195   return color;
196 }
197