0030153: Visualization, TKOpenGl - AIS_ColoredShape::SynchronizeAspects() doesn't...
[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 (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
99     {
100       const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
101       if (aPrsModed.Mode() != AIS_WireFrame)
102       {
103         continue;
104       }
105
106       const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
107
108       for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
109       {
110         const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
111         if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
112         {
113           aGroup->SetGroupPrimitivesAspect (anAreaAsp);
114         }
115       }
116     }
117
118     myRecomputeEveryPrs = Standard_False; // no mode to recalculate - only viewer update
119     myToRecomputeModes.Clear();
120   }
121 }
122
123 //=======================================================================
124 //function : Compute
125 //purpose  :
126 //=======================================================================
127 void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
128                                 const Handle(Prs3d_Presentation)& aPresentation,
129                                 const Standard_Integer aMode)
130 {
131   switch (aMode)
132   {
133     case 0:
134       const TColgp_Array1OfPnt& nodes = myTriangulation->Nodes();             //Nodes
135       const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();  //Triangle
136
137       Standard_Boolean hasVNormals = myTriangulation->HasNormals();
138       Standard_Boolean hasVColors  = HasVertexColors();
139
140       Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (myNbNodes, myNbTriangles * 3,
141                                                                                    hasVNormals, hasVColors, Standard_False);
142       Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
143       Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
144
145       Standard_Integer i;
146       Standard_Integer j;
147
148       Standard_Real ambient = aspect->FrontMaterial().Ambient();
149       if (hasVNormals)
150       {
151         const TShort_Array1OfShortReal& normals = myTriangulation->Normals();
152         if (hasVColors)
153         {
154           const TColStd_Array1OfInteger& colors = myColor->Array1();
155           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
156           {
157             j = (i - nodes.Lower()) * 3;
158             anArray->AddVertex(nodes(i), attenuateColor(colors(i), ambient));
159             anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
160           }
161         }
162         else // !hasVColors
163         {
164           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
165           {
166             j = (i - nodes.Lower()) * 3;
167             anArray->AddVertex(nodes(i));
168             anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
169           }
170         }
171       }
172       else // !hasVNormals
173       {
174         if (hasVColors)
175         {
176           const TColStd_Array1OfInteger& colors = myColor->Array1();
177           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
178           {
179             anArray->AddVertex(nodes(i), attenuateColor(colors(i), ambient));
180           }
181         }
182         else // !hasVColors
183         {
184           for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
185           {
186             anArray->AddVertex(nodes(i));
187           }
188         }
189       }
190
191       Standard_Integer indexTriangle[3] = {0,0,0};
192       for ( i = triangles.Lower(); i<= triangles.Upper(); i++ ) {
193         triangles(i).Get(indexTriangle[0], indexTriangle[1], indexTriangle[2]);
194         anArray->AddEdge(indexTriangle[0]);
195         anArray->AddEdge(indexTriangle[1]);
196         anArray->AddEdge(indexTriangle[2]);
197       }
198       TheGroup->SetPrimitivesAspect(aspect);
199       TheGroup->AddPrimitiveArray(anArray);
200       break;
201   }
202 }
203
204 //=======================================================================
205 //function : ComputeSelection
206 //purpose  :
207 //=======================================================================
208 void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& /*aSelection*/,
209                                          const Standard_Integer /*aMode*/)
210 {
211
212 }
213
214 //=======================================================================
215 //function : SetColor
216 //purpose  : Set the color for each node.
217 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
218 //           Order of color components is essential for further usage by OpenGL
219 //=======================================================================
220 void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
221 {
222   myFlagColor = 1;
223   myColor = aColor;
224 }
225
226 //=======================================================================
227 //function : GetColor
228 //purpose  : Get the color for each node.
229 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
230 //           Order of color components is essential for further usage by OpenGL
231 //=======================================================================
232
233 Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
234 {
235   return myColor;
236 }
237
238
239 //=======================================================================
240 //function : SetTriangulation
241 //purpose  :
242 //=======================================================================
243 void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
244 {
245   myTriangulation = aTriangulation;
246 }
247
248 //=======================================================================
249 //function : GetTriangulation
250 //purpose  :
251 //=======================================================================
252 Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
253   return myTriangulation;
254 }
255
256 //=======================================================================
257 //function : AttenuateColor
258 //purpose  :
259 //=======================================================================
260 Graphic3d_Vec4ub AIS_Triangulation::attenuateColor (const Standard_Integer theColor,
261                                                     const Standard_Real    theComposition)
262 {
263   const Standard_Byte* anRgbx = reinterpret_cast<const Standard_Byte*> (&theColor);
264
265   // If IsTranparent() is false alpha value will be ignored anyway.
266   Standard_Byte anAlpha = IsTransparent() ? static_cast<Standard_Byte> (255.0 - myDrawer->ShadingAspect()->Aspect()->FrontMaterial().Transparency() * 255.0)
267                                           : 255;
268
269   return Graphic3d_Vec4ub ((Standard_Byte)(theComposition * anRgbx[0]),
270                            (Standard_Byte)(theComposition * anRgbx[1]),
271                            (Standard_Byte)(theComposition * anRgbx[2]),
272                            anAlpha);
273 }