87a0e112009463d0770eea63c5e18b8e0a728ef8
[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 #include <Graphic3d_ArrayOfPrimitives.hxx>
34
35
36 IMPLEMENT_STANDARD_HANDLE(AIS_Triangulation, AIS_InteractiveObject)
37 IMPLEMENT_STANDARD_RTTIEXT(AIS_Triangulation, AIS_InteractiveObject)
38
39 AIS_Triangulation::AIS_Triangulation(const Handle(Poly_Triangulation)& Triangulation)
40 {
41   myTriangulation = Triangulation;
42   myNbNodes       = Triangulation->NbNodes();
43   myNbTriangles   = Triangulation->NbTriangles();
44   myFlagColor     = 0;
45 }
46
47 //=======================================================================
48 //function : Compute
49 //purpose  :
50 //=======================================================================
51 void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
52                                 const Handle(Prs3d_Presentation)& aPresentation,
53                                 const Standard_Integer aMode)
54 {
55   switch (aMode) 
56   {
57     case 0:
58       const TColgp_Array1OfPnt& nodes = myTriangulation->Nodes();             //Nodes
59       const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();  //Triangle
60       const TShort_Array1OfShortReal& normals = myTriangulation->Normals();   //Normal
61
62       Standard_Boolean hasVNormals  = Standard_False;
63       Standard_Boolean hasVColors   = Standard_False;
64       if( normals.Length() > 0 )
65         hasVNormals = Standard_True;
66       if( myFlagColor == 1 )
67         hasVColors = Standard_True; 
68
69       Handle(Graphic3d_ArrayOfTriangles) array = 
70          new Graphic3d_ArrayOfTriangles ( myNbNodes,        //maxVertexs
71                                           myNbTriangles * 3,//maxEdges
72                                           hasVNormals,      //hasVNormals
73                                           hasVColors,       //hasVColors
74                                           Standard_False,   //hasTexels
75                                           Standard_True     //hasEdgeInfos
76                                          );
77       Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
78       Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
79
80       Standard_Integer i;
81       Standard_Integer j;
82
83       Standard_Real ambient = aspect->FrontMaterial().Ambient();
84       for ( i = nodes.Lower(); i<= nodes.Upper(); i++ ){ 
85         if( myFlagColor == 1 )
86           array->AddVertex( nodes(i), AttenuateColor(myColor->Value(i),ambient));
87         if( myFlagColor == 0 )
88           array->AddVertex( nodes(i) );
89         j = (i - nodes.Lower()) * 3;
90         array->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
91       }
92
93       Standard_Integer indexTriangle[3] = {0,0,0};
94       for ( i = triangles.Lower(); i<= triangles.Upper(); i++ ) {
95         triangles(i).Get(indexTriangle[0], indexTriangle[1], indexTriangle[2]);
96         array->AddEdge(indexTriangle[0]);
97         array->AddEdge(indexTriangle[1]);
98         array->AddEdge(indexTriangle[2]);
99       }
100       TheGroup->SetPrimitivesAspect(aspect);
101       TheGroup->BeginPrimitives();
102       TheGroup->AddPrimitiveArray(array);
103       TheGroup->EndPrimitives();
104       break;
105   }
106 }
107
108 //=======================================================================
109 //function : ComputeSelection
110 //purpose  : 
111 //=======================================================================
112 void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
113                                          const Standard_Integer /*aMode*/)
114 {
115
116 }
117
118 //=======================================================================
119 //function : SetColor
120 //purpose  : Set the color for each node.
121 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
122 //           Order of color components is essential for further usage by OpenGL
123 //=======================================================================
124 void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
125 {
126   myFlagColor = 1;
127   myColor = aColor;
128 }
129
130 //=======================================================================
131 //function : GetColor
132 //purpose  : Get the color for each node.
133 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
134 //           Order of color components is essential for further usage by OpenGL
135 //=======================================================================
136
137 Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
138 {
139   return myColor;
140 }
141
142
143 //=======================================================================
144 //function : SetTriangulation
145 //purpose  : 
146 //=======================================================================
147 void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
148 {
149   myTriangulation = aTriangulation;
150 }
151
152 //=======================================================================
153 //function : GetTriangulation
154 //purpose  : 
155 //=======================================================================
156 Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
157   return myTriangulation;
158 }
159
160 //=======================================================================
161 //function : AttenuateColor
162 //purpose  : Attenuates 32-bit color by a given attenuation factor (0...1):
163 //           aColor = Alpha << 24 + Blue << 16 + Green << 8 + Red
164 //           All color components are multiplied by aComponent, the result is then packed again as 32-bit integer.
165 //           Color attenuation is applied to the vertex colors in order to have correct visual result 
166 //           after glColorMaterial(GL_AMBIENT_AND_DIFFUSE). Without it, colors look unnatural and flat.
167 //=======================================================================
168
169 Standard_Integer AIS_Triangulation::AttenuateColor( const Standard_Integer aColor,
170                                                     const Standard_Real aComposition)
171 {
172   Standard_Integer  red,
173                     green,
174                     blue,
175                     alpha;
176
177   alpha = aColor&0xff000000;
178   alpha >>= 24;
179
180   blue = aColor&0x00ff0000;
181   blue >>= 16;
182
183   green = aColor&0x0000ff00;
184   green >>= 8;
185
186   red = aColor&0x000000ff;
187   red >>= 0; 
188
189   red   = (Standard_Integer)(aComposition * red);
190   green = (Standard_Integer)(aComposition * green);
191   blue  = (Standard_Integer)(aComposition * blue);
192
193   Standard_Integer  color;
194   color = red;
195   color += green << 8;
196   color += blue  << 16; 
197   color += alpha << 24;
198   return color;
199 }
200