0032160: Coding Rules - merge AIS_InteractiveContext_*.cxx into single file
[occt.git] / src / V3d / V3d_View_4.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
15 #include <Aspect_GradientBackground.hxx>
16 #include <Aspect_Grid.hxx>
17 #include <Aspect_RectangularGrid.hxx>
18 #include <Aspect_Window.hxx>
19 #include <Bnd_Box.hxx>
20 #include <gp_Ax3.hxx>
21 #include <gp_Dir.hxx>
22 #include <gp_Dir2d.hxx>
23 #include <Graphic3d_Group.hxx>
24 #include <Graphic3d_Structure.hxx>
25 #include <Graphic3d_TextureEnv.hxx>
26 #include <Quantity_Color.hxx>
27 #include <Standard_MultiplyDefined.hxx>
28 #include <Standard_TypeMismatch.hxx>
29 #include <TColStd_Array2OfReal.hxx>
30 #include <V3d_BadValue.hxx>
31 #include <V3d_CircularGrid.hxx>
32 #include <V3d_Light.hxx>
33 #include <V3d_RectangularGrid.hxx>
34 #include <V3d_UnMapped.hxx>
35 #include <V3d_View.hxx>
36 #include <V3d_Viewer.hxx>
37 #include <Aspect_CircularGrid.hxx>
38
39 #define MYEPSILON1 0.0001               // Comparison with 0.0
40 #define MYEPSILON2 M_PI / 180.  // Delta between 2 angles
41
42 //=============================================================================
43 //function : SetGrid
44 //purpose  :
45 //=============================================================================
46 void V3d_View::SetGrid (const gp_Ax3& aPlane, const Handle(Aspect_Grid)& aGrid)
47 {
48   MyPlane       = aPlane;
49   MyGrid        = aGrid;
50
51   Standard_Real xl, yl, zl;
52   Standard_Real xdx, xdy, xdz;
53   Standard_Real ydx, ydy, ydz;
54   Standard_Real dx, dy, dz;
55   aPlane.Location ().Coord (xl, yl, zl);
56   aPlane.XDirection ().Coord (xdx, xdy, xdz);
57   aPlane.YDirection ().Coord (ydx, ydy, ydz);
58   aPlane.Direction ().Coord (dx, dy, dz);
59
60   Standard_Real CosAlpha = Cos (MyGrid->RotationAngle ());
61   Standard_Real SinAlpha = Sin (MyGrid->RotationAngle ());
62
63   TColStd_Array2OfReal Trsf1 (1, 4, 1, 4);
64   Trsf1 (4, 4) = 1.0;
65   Trsf1 (4, 1) = Trsf1 (4, 2) = Trsf1 (4, 3) = 0.0;
66   // Translation
67   Trsf1 (1, 4) = xl,
68   Trsf1 (2, 4) = yl,
69   Trsf1 (3, 4) = zl;
70   // Transformation change of marker
71   Trsf1 (1, 1) = xdx,
72   Trsf1 (2, 1) = xdy,
73   Trsf1 (3, 1) = xdz,
74   Trsf1 (1, 2) = ydx,
75   Trsf1 (2, 2) = ydy,
76   Trsf1 (3, 2) = ydz,
77   Trsf1 (1, 3) = dx,
78   Trsf1 (2, 3) = dy,
79   Trsf1 (3, 3) = dz;
80
81   TColStd_Array2OfReal Trsf2 (1, 4, 1, 4);
82   Trsf2 (4, 4) = 1.0;
83   Trsf2 (4, 1) = Trsf2 (4, 2) = Trsf2 (4, 3) = 0.0;
84   // Translation of the origin
85   Trsf2 (1, 4) = -MyGrid->XOrigin (),
86   Trsf2 (2, 4) = -MyGrid->YOrigin (),
87   Trsf2 (3, 4) = 0.0;
88   // Rotation Alpha around axis -Z
89   Trsf2 (1, 1) = CosAlpha,
90   Trsf2 (2, 1) = -SinAlpha,
91   Trsf2 (3, 1) = 0.0,
92   Trsf2 (1, 2) = SinAlpha,
93   Trsf2 (2, 2) = CosAlpha,
94   Trsf2 (3, 2) = 0.0,
95   Trsf2 (1, 3) = 0.0,
96   Trsf2 (2, 3) = 0.0,
97   Trsf2 (3, 3) = 1.0;
98
99   Standard_Real valuetrsf;
100   Standard_Real valueoldtrsf;
101   Standard_Real valuenewtrsf;
102   Standard_Integer i, j, k;
103   // Calculation of the product of matrices
104   for (i=1; i<=4; i++)
105       for (j=1; j<=4; j++) {
106     MyTrsf (i, j) = 0.0;
107     for (k=1; k<=4; k++) {
108         valueoldtrsf = Trsf1 (i, k);
109         valuetrsf        = Trsf2 (k, j);
110         valuenewtrsf = MyTrsf (i, j) + valueoldtrsf * valuetrsf;
111         MyTrsf (i, j) = valuenewtrsf;
112     }
113      }
114 }
115
116 //=============================================================================
117 //function : SetGridActivity
118 //purpose  :
119 //=============================================================================
120 void V3d_View::SetGridActivity (const Standard_Boolean AFlag)
121 {
122   if (AFlag) MyGrid->Activate ();
123   else MyGrid->Deactivate ();
124 }
125
126 //=============================================================================
127 //function : toPolarCoords
128 //purpose  :
129 //=============================================================================
130 void toPolarCoords (const Standard_Real theX, const Standard_Real theY, 
131                           Standard_Real& theR, Standard_Real& thePhi)
132 {
133   theR = Sqrt (theX * theX + theY * theY);
134   thePhi = ATan2 (theY, theX);  
135 }
136
137 //=============================================================================
138 //function : toCartesianCoords
139 //purpose  :
140 //=============================================================================
141 void toCartesianCoords (const Standard_Real theR, const Standard_Real thePhi, 
142                               Standard_Real& theX, Standard_Real& theY)
143 {
144   theX = theR * Cos (thePhi);
145   theY = theR * Sin (thePhi);
146 }
147
148 //=============================================================================
149 //function : Compute
150 //purpose  :
151 //=============================================================================
152 Graphic3d_Vertex V3d_View::Compute (const Graphic3d_Vertex& theVertex) const
153 {
154   const Handle(Graphic3d_Camera)& aCamera = Camera();
155   gp_Dir VPN = aCamera->Direction().Reversed(); // RefPlane
156   gp_Dir GPN = MyPlane.Direction();
157
158   Standard_Real XPp = 0.0, YPp = 0.0;
159   Project (theVertex.X(), theVertex.Y(), theVertex.Z(), XPp, YPp);
160
161   // Casw when the plane of the grid and the plane of the view
162   // are perpendicular to MYEPSILON2 close radians
163   if (Abs (VPN.Angle (GPN) - M_PI / 2.) < MYEPSILON2)
164   {
165     return theVertex;
166   }
167
168   const gp_XYZ aPnt0 = V3d_View::TrsPoint (Graphic3d_Vertex (0.0, 0.0, 0.0), MyTrsf);
169     
170   // get grid axes in world space
171   const gp_XYZ aPnt1 = V3d_View::TrsPoint (Graphic3d_Vertex (1.0, 0.0, 0.0), MyTrsf);
172   gp_Vec aGridX (aPnt0, aPnt1);
173   aGridX.Normalize();
174
175   const gp_XYZ aPnt2 = V3d_View::TrsPoint (Graphic3d_Vertex (0.0, 1.0, 0.0), MyTrsf);
176   gp_Vec aGridY (aPnt0, aPnt2);
177   aGridY.Normalize();
178
179   // project ray from camera onto grid plane
180   const gp_Vec aProjection  = aCamera->IsOrthographic()
181                             ? gp_Vec (aCamera->Direction())
182                             : gp_Vec (aCamera->Eye(), gp_Pnt (theVertex.X(), theVertex.Y(), theVertex.Z())).Normalized();
183   const gp_Vec aPointOrigin = gp_Vec (gp_Pnt (theVertex.X(), theVertex.Y(), theVertex.Z()), aPnt0);
184   const Standard_Real aT    = aPointOrigin.Dot (MyPlane.Direction()) / aProjection.Dot (MyPlane.Direction());
185   const gp_XYZ aPointOnPlane = gp_XYZ (theVertex.X(), theVertex.Y(), theVertex.Z()) + aProjection.XYZ() * aT;
186
187   if (Handle(Aspect_RectangularGrid) aRectGrid = Handle(Aspect_RectangularGrid)::DownCast (MyGrid))
188   {
189     // project point on plane to grid local space
190     const gp_Vec aToPoint (aPnt0, aPointOnPlane);
191     const Standard_Real anXSteps = Round (aGridX.Dot (aToPoint) / aRectGrid->XStep());
192     const Standard_Real anYSteps = Round (aGridY.Dot (aToPoint) / aRectGrid->YStep());
193
194     // clamp point to grid
195     const gp_Vec aResult = aGridX * anXSteps * aRectGrid->XStep()
196                          + aGridY * anYSteps * aRectGrid->YStep()
197                          + gp_Vec (aPnt0);
198     return Graphic3d_Vertex (aResult.X(), aResult.Y(), aResult.Z());
199   } 
200   else if (Handle(Aspect_CircularGrid) aCircleGrid = Handle(Aspect_CircularGrid)::DownCast (MyGrid))
201   {
202     const Standard_Real anAlpha = M_PI / Standard_Real (aCircleGrid->DivisionNumber());
203
204     // project point on plane to grid local space
205     const gp_Vec aToPoint (aPnt0, aPointOnPlane);
206     Standard_Real aLocalX = aGridX.Dot (aToPoint);
207     Standard_Real aLocalY = aGridY.Dot (aToPoint);
208     Standard_Real anR = 0.0, aPhi = 0.0;
209     toPolarCoords (aLocalX, aLocalY, anR, aPhi);
210
211     // clamp point to grid
212     const Standard_Real anRSteps  = Round (anR / aCircleGrid->RadiusStep());
213     const Standard_Real aPhiSteps = Round (aPhi / anAlpha);
214     toCartesianCoords (anRSteps * aCircleGrid->RadiusStep(), aPhiSteps * anAlpha, aLocalX, aLocalY);
215
216     const gp_Vec aResult = aGridX * aLocalX + aGridY * aLocalY + gp_Vec (aPnt0);
217     return Graphic3d_Vertex (aResult.X(), aResult.Y(), aResult.Z());
218   }
219   return Graphic3d_Vertex (0.0, 0.0, 0.0);
220 }
221
222 //=============================================================================
223 //function : ZBufferTriedronSetup
224 //purpose  :
225 //=============================================================================
226 void V3d_View::ZBufferTriedronSetup(const Quantity_Color&  theXColor,
227                                     const Quantity_Color&  theYColor,
228                                     const Quantity_Color&  theZColor,
229                                     const Standard_Real    theSizeRatio,
230                                     const Standard_Real    theAxisDiametr,
231                                     const Standard_Integer theNbFacettes)
232 {
233   const Handle(V3d_Trihedron)& aTrihedron = Trihedron (true);
234   aTrihedron->SetArrowsColor   (theXColor, theYColor, theZColor);
235   aTrihedron->SetSizeRatio     (theSizeRatio);
236   aTrihedron->SetNbFacets      (theNbFacettes);
237   aTrihedron->SetArrowDiameter (theAxisDiametr);
238 }
239
240 //=============================================================================
241 //function : TriedronDisplay
242 //purpose  :
243 //=============================================================================
244 void V3d_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
245                                 const Quantity_Color& theColor,
246                                 const Standard_Real theScale,
247                                 const V3d_TypeOfVisualization theMode)
248 {
249   const Handle(V3d_Trihedron)& aTrihedron = Trihedron (true);
250   aTrihedron->SetLabelsColor (theColor);
251   aTrihedron->SetScale       (theScale);
252   aTrihedron->SetPosition    (thePosition);
253   aTrihedron->SetWireframe   (theMode == V3d_WIREFRAME);
254
255   aTrihedron->Display (*this);
256 }
257
258 //=============================================================================
259 //function : TriedronErase
260 //purpose  :
261 //=============================================================================
262 void V3d_View::TriedronErase()
263 {
264   if (!myTrihedron.IsNull())
265   {
266     myTrihedron->Erase();
267   }
268 }
269
270 //=============================================================================
271 //function : GetGraduatedTrihedron
272 //purpose  :
273 //=============================================================================
274 const Graphic3d_GraduatedTrihedron& V3d_View::GetGraduatedTrihedron() const
275 {
276   return myView->GetGraduatedTrihedron();
277 }
278
279 //=============================================================================
280 //function : GraduatedTrihedronDisplay
281 //purpose  :
282 //=============================================================================
283 void V3d_View::GraduatedTrihedronDisplay(const Graphic3d_GraduatedTrihedron& theTrihedronData)
284 {
285   myView->GraduatedTrihedronDisplay (theTrihedronData);
286 }
287
288 //=============================================================================
289 //function : GraduatedTrihedronErase
290 //purpose  :
291 //=============================================================================
292 void V3d_View::GraduatedTrihedronErase()
293 {
294   myView->GraduatedTrihedronErase();
295 }