0031458: Visualization - refine classes across Prs3d and StdPrs packages
[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 under
6 // the terms of the GNU Lesser General Public License 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_DisplayMode.hxx>
15 #include <AIS_Triangulation.hxx>
16 #include <AIS_InteractiveObject.hxx>
17 #include <Standard_Type.hxx>
18 #include <Poly_Array1OfTriangle.hxx>
19 #include <Poly_Triangulation.hxx>
20 #include <Prs3d_Drawer.hxx>
21 #include <Prs3d_Root.hxx>
22 #include <Prs3d_ShadingAspect.hxx>
23 #include <TShort_Array1OfShortReal.hxx>
24 #include <TColgp_Array1OfPnt.hxx>
25 #include <TColStd_HArray1OfInteger.hxx>
26 #include <TShort_HArray1OfShortReal.hxx>
27 #include <Graphic3d_Group.hxx>
28 #include <Graphic3d_AspectFillArea3d.hxx>
29 #include <Graphic3d_ArrayOfTriangles.hxx>
30
31
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 : SetTransparency
44 //purpose  :
45 //=======================================================================
46 void AIS_Triangulation::SetTransparency (const Standard_Real theValue)
47 {
48   if (!myDrawer->HasOwnShadingAspect())
49   {
50     myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
51     if (myDrawer->HasLink())
52     {
53       *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
54     }
55   }
56
57   // override transparency
58   myDrawer->ShadingAspect()->SetTransparency (theValue, myCurrentFacingModel);
59   myDrawer->SetTransparency ((Standard_ShortReal )theValue);
60
61   updatePresentation();
62 }
63
64 //=======================================================================
65 //function : UnsetTransparency
66 //purpose  :
67 //=======================================================================
68 void AIS_Triangulation::UnsetTransparency()
69 {
70   myDrawer->SetTransparency (0.0f);
71   if (!myDrawer->HasOwnShadingAspect())
72   {
73     return;
74   }
75   else if (HasColor() || HasMaterial())
76   {
77     myDrawer->ShadingAspect()->SetTransparency (0.0, myCurrentFacingModel);
78   }
79
80   updatePresentation();
81 }
82
83 //=======================================================================
84 //function : updatePresentation
85 //purpose  :
86 //=======================================================================
87 void AIS_Triangulation::updatePresentation()
88 {
89   if (HasVertexColors())
90   {
91     SetToUpdate (AIS_WireFrame);
92   }
93   else
94   {
95     // modify shading presentation without re-computation
96     const PrsMgr_Presentations&        aPrsList  = Presentations();
97     Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
98     for (PrsMgr_Presentations::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
99     {
100       if (aPrsIter.Value()->Mode() != AIS_WireFrame)
101       {
102         continue;
103       }
104
105       const Handle(Prs3d_Presentation)& aPrs = aPrsIter.Value();
106       for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
107       {
108         const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
109         aGroup->SetGroupPrimitivesAspect (anAreaAsp);
110       }
111     }
112   }
113 }
114
115 //=======================================================================
116 //function : Compute
117 //purpose  :
118 //=======================================================================
119 void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
120                                 const Handle(Prs3d_Presentation)& aPresentation,
121                                 const Standard_Integer aMode)
122 {
123   switch (aMode)
124   {
125     case 0:
126       const TColgp_Array1OfPnt& nodes = myTriangulation->Nodes();             //Nodes
127       const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();  //Triangle
128
129       Standard_Boolean hasVNormals = myTriangulation->HasNormals();
130       Standard_Boolean hasVColors  = HasVertexColors();
131
132       Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (myNbNodes, myNbTriangles * 3,
133                                                                                    hasVNormals, hasVColors, Standard_False);
134       Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
135       Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
136
137       Standard_Integer i;
138       Standard_Integer j;
139
140       const Standard_Real ambient = 0.2;
141       if (hasVNormals)
142       {
143         const TShort_Array1OfShortReal& normals = myTriangulation->Normals();
144         if (hasVColors)
145         {
146           const TColStd_Array1OfInteger& colors = myColor->Array1();
147           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
148           {
149             j = (i - nodes.Lower()) * 3;
150             anArray->AddVertex(nodes(i), attenuateColor(colors(i), ambient));
151             anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
152           }
153         }
154         else // !hasVColors
155         {
156           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
157           {
158             j = (i - nodes.Lower()) * 3;
159             anArray->AddVertex(nodes(i));
160             anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
161           }
162         }
163       }
164       else // !hasVNormals
165       {
166         if (hasVColors)
167         {
168           const TColStd_Array1OfInteger& colors = myColor->Array1();
169           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
170           {
171             anArray->AddVertex(nodes(i), attenuateColor(colors(i), ambient));
172           }
173         }
174         else // !hasVColors
175         {
176           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
177           {
178             anArray->AddVertex(nodes(i));
179           }
180         }
181       }
182
183       Standard_Integer indexTriangle[3] = {0,0,0};
184       for ( i = triangles.Lower(); i<= triangles.Upper(); i++ ) {
185         triangles(i).Get(indexTriangle[0], indexTriangle[1], indexTriangle[2]);
186         anArray->AddEdge(indexTriangle[0]);
187         anArray->AddEdge(indexTriangle[1]);
188         anArray->AddEdge(indexTriangle[2]);
189       }
190       TheGroup->SetPrimitivesAspect(aspect);
191       TheGroup->AddPrimitiveArray(anArray);
192       break;
193   }
194 }
195
196 //=======================================================================
197 //function : ComputeSelection
198 //purpose  :
199 //=======================================================================
200 void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& /*aSelection*/,
201                                          const Standard_Integer /*aMode*/)
202 {
203
204 }
205
206 //=======================================================================
207 //function : SetColor
208 //purpose  : Set the color for each node.
209 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
210 //           Order of color components is essential for further usage by OpenGL
211 //=======================================================================
212 void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
213 {
214   myFlagColor = 1;
215   myColor = aColor;
216 }
217
218 //=======================================================================
219 //function : GetColor
220 //purpose  : Get the color for each node.
221 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
222 //           Order of color components is essential for further usage by OpenGL
223 //=======================================================================
224
225 Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
226 {
227   return myColor;
228 }
229
230
231 //=======================================================================
232 //function : SetTriangulation
233 //purpose  :
234 //=======================================================================
235 void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
236 {
237   myTriangulation = aTriangulation;
238 }
239
240 //=======================================================================
241 //function : GetTriangulation
242 //purpose  :
243 //=======================================================================
244 Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
245   return myTriangulation;
246 }
247
248 //=======================================================================
249 //function : AttenuateColor
250 //purpose  :
251 //=======================================================================
252 Graphic3d_Vec4ub AIS_Triangulation::attenuateColor (const Standard_Integer theColor,
253                                                     const Standard_Real    theComposition)
254 {
255   const Standard_Byte* anRgbx = reinterpret_cast<const Standard_Byte*> (&theColor);
256
257   // If IsTranparent() is false alpha value will be ignored anyway.
258   Standard_Byte anAlpha = IsTransparent() ? static_cast<Standard_Byte> (255.0 - myDrawer->ShadingAspect()->Aspect()->FrontMaterial().Transparency() * 255.0)
259                                           : 255;
260
261   return Graphic3d_Vec4ub ((Standard_Byte)(theComposition * anRgbx[0]),
262                            (Standard_Byte)(theComposition * anRgbx[1]),
263                            (Standard_Byte)(theComposition * anRgbx[2]),
264                            anAlpha);
265 }