0025789: Visualization - get rid of obsolete 2d layers implementation
[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 <Graphic3d_Vector.hxx>
27 #include <Quantity_Color.hxx>
28 #include <Standard_MultiplyDefined.hxx>
29 #include <Standard_TypeMismatch.hxx>
30 #include <TColStd_Array2OfReal.hxx>
31 #include <V3d_BadValue.hxx>
32 #include <V3d_CircularGrid.hxx>
33 #include <V3d_Light.hxx>
34 #include <V3d_RectangularGrid.hxx>
35 #include <V3d_UnMapped.hxx>
36 #include <V3d_View.hxx>
37 #include <V3d_Viewer.hxx>
38 #include <Visual3d_View.hxx>
39
40 #define MYEPSILON1 0.0001               // Comparison with 0.0
41 #define MYEPSILON2 M_PI / 180.  // Delta between 2 angles
42
43 /*----------------------------------------------------------------------*/
44
45 void V3d_View::SetGrid (const gp_Ax3& aPlane, const Handle(Aspect_Grid)& aGrid)
46 {
47   MyPlane       = aPlane;
48   MyGrid        = aGrid;
49
50   Standard_Real xl, yl, zl;
51   Standard_Real xdx, xdy, xdz;
52   Standard_Real ydx, ydy, ydz;
53   Standard_Real dx, dy, dz;
54   aPlane.Location ().Coord (xl, yl, zl);
55   aPlane.XDirection ().Coord (xdx, xdy, xdz);
56   aPlane.YDirection ().Coord (ydx, ydy, ydz);
57   aPlane.Direction ().Coord (dx, dy, dz);
58
59   Standard_Real CosAlpha = Cos (MyGrid->RotationAngle ());
60   Standard_Real SinAlpha = Sin (MyGrid->RotationAngle ());
61
62   TColStd_Array2OfReal Trsf1 (1, 4, 1, 4);
63   Trsf1 (4, 4) = 1.0;
64   Trsf1 (4, 1) = Trsf1 (4, 2) = Trsf1 (4, 3) = 0.0;
65   // Translation
66   Trsf1 (1, 4) = xl,
67   Trsf1 (2, 4) = yl,
68   Trsf1 (3, 4) = zl;
69   // Transformation change of marker
70   Trsf1 (1, 1) = xdx,
71   Trsf1 (2, 1) = xdy,
72   Trsf1 (3, 1) = xdz,
73   Trsf1 (1, 2) = ydx,
74   Trsf1 (2, 2) = ydy,
75   Trsf1 (3, 2) = ydz,
76   Trsf1 (1, 3) = dx,
77   Trsf1 (2, 3) = dy,
78   Trsf1 (3, 3) = dz;
79
80   TColStd_Array2OfReal Trsf2 (1, 4, 1, 4);
81   Trsf2 (4, 4) = 1.0;
82   Trsf2 (4, 1) = Trsf2 (4, 2) = Trsf2 (4, 3) = 0.0;
83   // Translation of the origin
84   Trsf2 (1, 4) = -MyGrid->XOrigin (),
85   Trsf2 (2, 4) = -MyGrid->YOrigin (),
86   Trsf2 (3, 4) = 0.0;
87   // Rotation Alpha around axis -Z
88   Trsf2 (1, 1) = CosAlpha,
89   Trsf2 (2, 1) = -SinAlpha,
90   Trsf2 (3, 1) = 0.0,
91   Trsf2 (1, 2) = SinAlpha,
92   Trsf2 (2, 2) = CosAlpha,
93   Trsf2 (3, 2) = 0.0,
94   Trsf2 (1, 3) = 0.0,
95   Trsf2 (2, 3) = 0.0,
96   Trsf2 (3, 3) = 1.0;
97
98   Standard_Real valuetrsf;
99   Standard_Real valueoldtrsf;
100   Standard_Real valuenewtrsf;
101   Standard_Integer i, j, k;
102   // Calculation of the product of matrices
103   for (i=1; i<=4; i++)
104       for (j=1; j<=4; j++) {
105     MyTrsf (i, j) = 0.0;
106     for (k=1; k<=4; k++) {
107         valueoldtrsf = Trsf1 (i, k);
108         valuetrsf        = Trsf2 (k, j);
109         valuenewtrsf = MyTrsf (i, j) + valueoldtrsf * valuetrsf;
110         MyTrsf (i, j) = valuenewtrsf;
111     }
112      }
113 }
114
115 void V3d_View::SetGridActivity (const Standard_Boolean AFlag)
116 {
117   if (AFlag) MyGrid->Activate ();
118   else MyGrid->Deactivate ();
119 }
120
121 void V3d_View::SetGridGraphicValues (const Handle(Aspect_Grid)& )
122 {
123 }
124
125
126 void toPolarCoords (const Standard_Real theX, const Standard_Real theY, 
127                           Standard_Real& theR, Standard_Real& thePhi)
128 {
129   theR = Sqrt (theX * theX + theY * theY);
130   thePhi = ATan2 (theY, theX);  
131 }
132
133 void toCartesianCoords (const Standard_Real theR, const Standard_Real thePhi, 
134                               Standard_Real& theX, Standard_Real& theY)
135 {
136   theX = theR * Cos (thePhi);
137   theY = theR * Sin (thePhi);
138 }
139
140 Graphic3d_Vertex V3d_View::Compute (const Graphic3d_Vertex & AVertex) const
141 {
142   Graphic3d_Vertex CurPoint, NewPoint;
143   Standard_Real X1, Y1, Z1, X2, Y2, Z2;
144   Standard_Real XPp, YPp;
145
146   gp_Dir aRefPlane = myCamera->Direction().Reversed();
147   X1 = aRefPlane.X(); Y1 = aRefPlane.Y(); Z1 = aRefPlane.Z();
148   MyPlane.Direction ().Coord (X2, Y2, Z2);
149
150   gp_Dir VPN (X1, Y1, Z1);
151   gp_Dir GPN (X2, Y2, Z2);
152
153   AVertex.Coord (X1, Y1, Z1);
154   Project (X1, Y1, Z1, XPp, YPp);
155
156   // Casw when the plane of the grid and the plane of the view
157   // are perpendicular to MYEPSILON2 close radians
158   if (Abs (VPN.Angle (GPN) - M_PI / 2.) < MYEPSILON2) {
159     NewPoint.SetCoord (X1, Y1, Z1);
160     return NewPoint;
161   }
162
163   Standard_Boolean IsRectangular = 
164     MyGrid->IsKind (STANDARD_TYPE (Aspect_RectangularGrid));
165
166   Graphic3d_Vertex P1;
167
168   Standard_Real x0, y0, z0, x1, y1, z1, x2, y2, z2;
169     
170   P1.SetCoord (0.0, 0.0, 0.0);
171   CurPoint = V3d_View::TrsPoint (P1, MyTrsf);
172   CurPoint.Coord (x0, y0, z0);
173     
174   // get grid axes in world space
175   P1.SetCoord (1.0, 0.0, 0.0);
176   CurPoint = V3d_View::TrsPoint (P1, MyTrsf);
177   CurPoint.Coord (x1, y1, z1);
178   gp_Vec aGridX (gp_Pnt (x0, y0, z0), gp_Pnt (x1, y1, z1));
179   aGridX.Normalize();
180
181   P1.SetCoord (0.0, 1.0, 0.0);
182   CurPoint = V3d_View::TrsPoint (P1, MyTrsf);
183   CurPoint.Coord (x2, y2, z2);
184   gp_Vec aGridY (gp_Pnt (x0, y0, z0), gp_Pnt (x2, y2, z2));
185   aGridY.Normalize();
186
187   // get grid normal
188   MyPlane.Direction().Coord (x2, y2, z2);
189   gp_Vec aPlaneNormal (x2, y2, z2);
190
191   gp_Vec aPointOnPlane = gp_Vec (0.0, 0.0, 0.0);
192
193   AVertex.Coord (x1, y1, z1);
194     
195   // project ray from camera onto grid plane
196   gp_Vec aProjection  = myCamera->IsOrthographic()
197                       ? gp_Vec (myCamera->Direction())
198                       : gp_Vec (myCamera->Eye(), gp_Pnt (x1, y1, z1)).Normalized();
199   gp_Vec aPointOrigin = gp_Vec (gp_Pnt (x1, y1, z1), gp_Pnt (x0, y0, z0));
200   Standard_Real aT    = aPointOrigin.Dot (aPlaneNormal) / aProjection.Dot (aPlaneNormal);
201   aPointOnPlane       = gp_Vec (x1, y1, z1) + aProjection * aT;
202
203   if (IsRectangular) {
204     Standard_Real XS, YS;
205     Handle(Aspect_RectangularGrid) theGrid =
206       Handle(Aspect_RectangularGrid)::DownCast (MyGrid);
207     XS = theGrid->XStep (), YS = theGrid->YStep ();
208
209     // project point on plane to grid local space
210     gp_Vec aToPoint (gp_Pnt (x0, y0, z0), 
211                      gp_Pnt (aPointOnPlane.X(), aPointOnPlane.Y(), aPointOnPlane.Z()));
212     Standard_Real anXSteps = Round (aGridX.Dot (aToPoint) / XS);
213     Standard_Real anYSteps = Round (aGridY.Dot (aToPoint) / YS);
214
215     // clamp point to grid
216     gp_Vec aResult = aGridX * anXSteps * XS + aGridY * anYSteps * YS + gp_Vec (x0, y0, z0);
217     NewPoint.SetCoord (aResult.X(), aResult.Y(), aResult.Z());
218
219   } 
220   else // IsCircular
221   {
222     Standard_Real RS;
223     Standard_Integer DN;
224     Standard_Real Alpha;
225     Handle(Aspect_CircularGrid) theGrid =
226       Handle(Aspect_CircularGrid)::DownCast (MyGrid);
227     RS = theGrid->RadiusStep ();
228     DN = theGrid->DivisionNumber ();
229     Alpha = M_PI / Standard_Real (DN);
230
231     // project point on plane to grid local space
232     gp_Vec aToPoint (gp_Pnt (x0, y0, z0), 
233                      gp_Pnt (aPointOnPlane.X(), aPointOnPlane.Y(), aPointOnPlane.Z()));
234
235     Standard_Real anR = 0.0, aPhi = 0.0;
236     Standard_Real aLocalX = aGridX.Dot (aToPoint);
237     Standard_Real aLocalY = aGridY.Dot (aToPoint);
238     toPolarCoords (aLocalX, aLocalY, anR, aPhi);
239
240     // clamp point to grid
241     Standard_Real anRSteps  = Round (anR / RS);
242     Standard_Real aPhiSteps = Round (aPhi / Alpha);
243     toCartesianCoords (anRSteps * RS, aPhiSteps * Alpha, aLocalX, aLocalY);
244
245     gp_Vec aResult = aGridX * aLocalX + aGridY * aLocalY + gp_Vec (x0, y0, z0);
246     NewPoint.SetCoord (aResult.X(), aResult.Y(), aResult.Z());
247   }
248
249   return NewPoint;
250 }
251
252 // Triedron methods : the Triedron is a non-zoomable object.
253
254 void V3d_View::ZBufferTriedronSetup(const Quantity_NameOfColor XColor,
255                                     const Quantity_NameOfColor YColor,
256                                     const Quantity_NameOfColor ZColor,
257                                     const Standard_Real        SizeRatio,
258                                     const Standard_Real        AxisDiametr,
259                                     const Standard_Integer     NbFacettes)
260 {
261   MyView->ZBufferTriedronSetup(XColor, YColor, ZColor, SizeRatio, AxisDiametr, NbFacettes);
262 }
263
264 void V3d_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition,
265  const Quantity_NameOfColor AColor, const Standard_Real AScale, const V3d_TypeOfVisualization AMode )
266 {
267   MyView->TriedronDisplay (APosition, AColor, AScale, (AMode == V3d_WIREFRAME));
268 }
269
270 void V3d_View::TriedronErase ( )
271 {
272   MyView->TriedronErase ( );
273 }
274
275 void V3d_View::TriedronEcho (const Aspect_TypeOfTriedronEcho AType )
276 {
277   MyView->TriedronEcho (AType);
278 }
279
280 const Graphic3d_GraduatedTrihedron& V3d_View::GetGraduatedTrihedron() const
281 {
282   return MyView->GetGraduatedTrihedron();
283 }
284
285 void V3d_View::GraduatedTrihedronDisplay(const Graphic3d_GraduatedTrihedron& theTrihedronData)
286 {
287   MyView->GraduatedTrihedronDisplay(theTrihedronData);
288 }
289
290 void V3d_View::GraduatedTrihedronErase()
291 {
292   MyView->GraduatedTrihedronErase();
293 }