054b71986af846510420a6aee5e98521811a8d1e
[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_Triangulation.hxx>
15
16 #include <AIS_DisplayMode.hxx>
17 #include <AIS_InteractiveObject.hxx>
18 #include <Standard_Type.hxx>
19 #include <Poly_Array1OfTriangle.hxx>
20 #include <Poly_Triangulation.hxx>
21 #include <Prs3d_Drawer.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_PresentationManager)& ,
120                                  const Handle(Prs3d_Presentation)& thePrs,
121                                  const Standard_Integer theMode)
122 {
123   if (theMode != 0)
124   {
125     return;
126   }
127
128   Standard_Boolean hasVNormals = myTriangulation->HasNormals();
129   Standard_Boolean hasVColors  = HasVertexColors();
130
131   Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (myNbNodes, myNbTriangles * 3,
132                                                                                hasVNormals, hasVColors, Standard_False);
133   Handle(Graphic3d_Group) aGroup = thePrs->CurrentGroup();
134   Handle(Graphic3d_AspectFillArea3d) anAspect = myDrawer->ShadingAspect()->Aspect();
135
136   const Standard_Real anAmbient = 0.2;
137   if (hasVNormals)
138   {
139     gp_Vec3f aNormal;
140     if (hasVColors)
141     {
142       const TColStd_Array1OfInteger& colors = myColor->Array1();
143       for (Standard_Integer aNodeIter = 1; aNodeIter <= myTriangulation->NbNodes(); ++aNodeIter)
144       {
145         anArray->AddVertex (myTriangulation->Node (aNodeIter), attenuateColor (colors[aNodeIter], anAmbient));
146         myTriangulation->Normal (aNodeIter, aNormal);
147         anArray->SetVertexNormal (aNodeIter, aNormal.x(), aNormal.y(), aNormal.z());
148       }
149     }
150     else // !hasVColors
151     {
152       for (Standard_Integer aNodeIter = 1; aNodeIter <= myTriangulation->NbNodes(); ++aNodeIter)
153       {
154         anArray->AddVertex (myTriangulation->Node (aNodeIter));
155         myTriangulation->Normal (aNodeIter, aNormal);
156         anArray->SetVertexNormal(aNodeIter, aNormal.x(), aNormal.y(), aNormal.z());
157       }
158     }
159   }
160   else // !hasVNormals
161   {
162     if (hasVColors)
163     {
164       const TColStd_Array1OfInteger& colors = myColor->Array1();
165       for (Standard_Integer aNodeIter = 1; aNodeIter <= myTriangulation->NbNodes(); ++aNodeIter)
166       {
167         anArray->AddVertex (myTriangulation->Node (aNodeIter), attenuateColor (colors[aNodeIter], anAmbient));
168       }
169     }
170     else // !hasVColors
171     {
172       for (Standard_Integer aNodeIter = 1; aNodeIter <= myTriangulation->NbNodes(); ++aNodeIter)
173       {
174         anArray->AddVertex (myTriangulation->Node (aNodeIter));
175       }
176     }
177   }
178
179   Standard_Integer aTriIndices[3] = {0,0,0};
180   for (Standard_Integer aTriIter = 1; aTriIter <= myTriangulation->NbTriangles(); ++aTriIter)
181   {
182     myTriangulation->Triangle (aTriIter).Get (aTriIndices[0], aTriIndices[1], aTriIndices[2]);
183     anArray->AddEdge (aTriIndices[0]);
184     anArray->AddEdge (aTriIndices[1]);
185     anArray->AddEdge (aTriIndices[2]);
186   }
187   aGroup->SetPrimitivesAspect (anAspect);
188   aGroup->AddPrimitiveArray (anArray);
189 }
190
191 //=======================================================================
192 //function : ComputeSelection
193 //purpose  :
194 //=======================================================================
195 void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& /*aSelection*/,
196                                          const Standard_Integer /*aMode*/)
197 {
198
199 }
200
201 //=======================================================================
202 //function : SetColor
203 //purpose  : Set the color for each node.
204 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
205 //           Order of color components is essential for further usage by OpenGL
206 //=======================================================================
207 void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
208 {
209   myFlagColor = 1;
210   myColor = aColor;
211 }
212
213 //=======================================================================
214 //function : GetColor
215 //purpose  : Get the color for each node.
216 //           Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
217 //           Order of color components is essential for further usage by OpenGL
218 //=======================================================================
219
220 Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
221 {
222   return myColor;
223 }
224
225
226 //=======================================================================
227 //function : SetTriangulation
228 //purpose  :
229 //=======================================================================
230 void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
231 {
232   myTriangulation = aTriangulation;
233 }
234
235 //=======================================================================
236 //function : GetTriangulation
237 //purpose  :
238 //=======================================================================
239 Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
240   return myTriangulation;
241 }
242
243 //=======================================================================
244 //function : AttenuateColor
245 //purpose  :
246 //=======================================================================
247 Graphic3d_Vec4ub AIS_Triangulation::attenuateColor (const Standard_Integer theColor,
248                                                     const Standard_Real    theComposition)
249 {
250   const Standard_Byte* anRgbx = reinterpret_cast<const Standard_Byte*> (&theColor);
251
252   // If IsTranparent() is false alpha value will be ignored anyway.
253   Standard_Byte anAlpha = IsTransparent() ? static_cast<Standard_Byte> (255.0 - myDrawer->ShadingAspect()->Aspect()->FrontMaterial().Transparency() * 255.0)
254                                           : 255;
255
256   return Graphic3d_Vec4ub ((Standard_Byte)(theComposition * anRgbx[0]),
257                            (Standard_Byte)(theComposition * anRgbx[1]),
258                            (Standard_Byte)(theComposition * anRgbx[2]),
259                            anAlpha);
260 }