0024394: Visualization - implement more general way for rendering of immediate objects
[occt.git] / src / V3d / V3d_RectangularGrid.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  
16      FONCTION :
17      ----------
18         Classe V3d_CircularGrid :
19  
20      HISTORIQUE DES MODIFICATIONS   :
21      --------------------------------
22       16-08-98 : CAL ; S3892. Ajout grilles 3d.
23       13-10-98 : CAL ; S3892. Ajout de la gestion de la taille des grilles 3d.
24       23-10-98 : CAL ; PRO 15885. Patch K4403 et K4404
25       03-11-98 : CAL ; PRO 16161. Patch K4418 et K4419
26       IMP230300: GG The color fields and methods have moved in Aspect_Grid
27
28
29 ************************************************************************/
30
31 #define IMP200100       //GG 
32 //                      -> Compute the case Aspect_GDM_None
33 //                      -> Initialize the grid size according to the
34 //                        viewer default size.
35
36 #define IMP200300       //GG
37 //                      -> Recompute the grid when any graphic parameter is
38 //                        modified.
39
40 /*----------------------------------------------------------------------*/
41 /*
42  * Includes
43  */
44
45 #include <V3d_RectangularGrid.ixx>
46
47 #include <TColStd_Array2OfReal.hxx>
48 #include <Graphic3d_AspectLine3d.hxx>
49 #include <Graphic3d_AspectMarker3d.hxx>
50 #include <Graphic3d_AspectText3d.hxx>
51 #include <Graphic3d_ArrayOfPoints.hxx>
52 #include <Visual3d_ViewManager.hxx>
53 #include <V3d_Viewer.hxx>
54 #include <TColgp_SequenceOfPnt.hxx>
55 #include <Graphic3d_ArrayOfSegments.hxx>
56
57 /*----------------------------------------------------------------------*/
58 /*
59  * Constant
60  */
61
62 #define MYMINMAX 25.
63 #define MYFACTOR 50.
64
65 /*----------------------------------------------------------------------*/
66
67 V3d_RectangularGrid::V3d_RectangularGrid (const V3d_ViewerPointer& aViewer, const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
68 : Aspect_RectangularGrid (1.,1.),
69   myStructure (new Graphic3d_Structure (aViewer->Viewer ())),
70   myGroup (myStructure->NewGroup()),
71   myViewer (aViewer),
72   myCurAreDefined (Standard_False)
73 {
74   myColor = aColor;
75   myTenthColor = aTenthColor;
76
77   myStructure->SetInfiniteState (Standard_True);
78
79   const Standard_Real step = 10.;
80   const Standard_Real gstep = step/MYFACTOR;
81   const Standard_Real size = 0.5*myViewer->DefaultViewSize();
82   SetGraphicValues (size, size, gstep);
83   SetXStep (step);
84   SetYStep (step);
85 }
86
87 void V3d_RectangularGrid::SetColors (const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
88 {
89   if( myColor != aColor || myTenthColor != aTenthColor ) {
90     myColor = aColor;
91     myTenthColor = aTenthColor;
92     myCurAreDefined = Standard_False;
93     UpdateDisplay();
94   }
95 }
96
97 void V3d_RectangularGrid::Display ()
98 {
99   myStructure->SetDisplayPriority (1);
100   myStructure->Display();
101 }
102
103 void V3d_RectangularGrid::Erase () const
104 {
105   myStructure->Erase ();
106 }
107
108 Standard_Boolean V3d_RectangularGrid::IsDisplayed () const
109 {
110   return myStructure->IsDisplayed ();
111 }
112
113 void V3d_RectangularGrid::UpdateDisplay ()
114 {
115   gp_Ax3 ThePlane = myViewer->PrivilegedPlane ();
116
117   Standard_Boolean MakeTransform = Standard_False;
118   Standard_Real xl, yl, zl;
119   Standard_Real xdx, xdy, xdz;
120   Standard_Real ydx, ydy, ydz;
121   Standard_Real dx, dy, dz;
122   ThePlane.Location ().Coord (xl, yl, zl);
123   ThePlane.XDirection ().Coord (xdx, xdy, xdz);
124   ThePlane.YDirection ().Coord (ydx, ydy, ydz);
125   ThePlane.Direction ().Coord (dx, dy, dz);
126   if (! myCurAreDefined)
127     MakeTransform = Standard_True;
128   else {
129     if (RotationAngle() != myCurAngle || XOrigin() != myCurXo || YOrigin() != myCurYo)
130       MakeTransform = Standard_True;
131     if (! MakeTransform) {
132       Standard_Real curxl, curyl, curzl;
133       Standard_Real curxdx, curxdy, curxdz;
134       Standard_Real curydx, curydy, curydz;
135       Standard_Real curdx, curdy, curdz;
136       myCurViewPlane.Location ().Coord (curxl, curyl, curzl);
137       myCurViewPlane.XDirection ().Coord (curxdx, curxdy, curxdz);
138       myCurViewPlane.YDirection ().Coord (curydx, curydy, curydz);
139       myCurViewPlane.Direction ().Coord (curdx, curdy, curdz);
140       if (xl != curxl || yl != curyl || zl != curzl ||
141           xdx != curxdx || xdy != curxdy || xdz != curxdz ||
142           ydx != curydx || ydy != curydy || ydz != curydz ||
143           dx != curdx || dy != curdy || dz != curdz)
144         MakeTransform = Standard_True;
145     }
146   }
147
148   if (MakeTransform) {
149     const Standard_Real CosAlpha = Cos (RotationAngle ());
150     const Standard_Real SinAlpha = Sin (RotationAngle ());
151     TColStd_Array2OfReal Trsf (1, 4, 1, 4);
152     Trsf (4, 4) = 1.0;
153     Trsf (4, 1) = Trsf (4, 2) = Trsf (4, 3) = 0.0;
154     // Translation
155     Trsf (1, 4) = xl,
156     Trsf (2, 4) = yl,
157     Trsf (3, 4) = zl;
158     // Transformation of change of marker
159     Trsf (1, 1) = xdx,
160     Trsf (2, 1) = xdy,
161     Trsf (3, 1) = xdz,
162     Trsf (1, 2) = ydx,
163     Trsf (2, 2) = ydy,
164     Trsf (3, 2) = ydz,
165     Trsf (1, 3) = dx,
166     Trsf (2, 3) = dy,
167     Trsf (3, 3) = dz;
168     myStructure->SetTransform (Trsf, Graphic3d_TOC_REPLACE);
169
170     // Translation of the origin
171     Trsf (1, 4) = -XOrigin (),
172     Trsf (2, 4) = -YOrigin (),
173     Trsf (3, 4) = 0.0;
174     // Rotation Alpha around axis -Z
175     Trsf (1, 1) = CosAlpha,
176     Trsf (2, 1) = -SinAlpha,
177     Trsf (3, 1) = 0.0,
178     Trsf (1, 2) = SinAlpha,
179     Trsf (2, 2) = CosAlpha,
180     Trsf (3, 2) = 0.0,
181     Trsf (1, 3) = 0.0,
182     Trsf (2, 3) = 0.0,
183     Trsf (3, 3) = 1.0;
184     myStructure->SetTransform (Trsf,Graphic3d_TOC_POSTCONCATENATE);
185
186     myCurAngle = RotationAngle ();
187     myCurXo = XOrigin (), myCurYo = YOrigin ();
188     myCurViewPlane = ThePlane;
189   }
190
191   switch (DrawMode ())
192   {
193     default:
194     //case Aspect_GDM_Points:
195       DefinePoints ();
196       myCurDrawMode = Aspect_GDM_Points;
197       break;
198     case Aspect_GDM_Lines:
199       DefineLines ();
200       myCurDrawMode = Aspect_GDM_Lines;
201       break;
202 #ifdef IMP210100
203     case Aspect_GDM_None:
204       myCurDrawMode = Aspect_GDM_None;
205       break;
206 #endif
207         }
208         myCurAreDefined = Standard_True;
209 }
210
211 void V3d_RectangularGrid::DefineLines ()
212 {
213   const Standard_Real aXStep = XStep();
214   const Standard_Real aYStep = YStep();
215   const Standard_Boolean toUpdate = !myCurAreDefined
216                                  || myCurDrawMode != Aspect_GDM_Lines
217                                  || aXStep != myCurXStep
218                                  || aYStep != myCurYStep;
219   if (!toUpdate)
220   {
221     return;
222   }
223
224   myGroup->Clear();
225
226   Handle(Graphic3d_AspectLine3d) LineAttrib = new Graphic3d_AspectLine3d ();
227   LineAttrib->SetColor (myColor);
228   LineAttrib->SetType (Aspect_TOL_SOLID);
229   LineAttrib->SetWidth (1.0);
230
231   Standard_Integer nblines;
232   Standard_Real xl, yl, zl = myOffSet;
233
234   TColgp_SequenceOfPnt aSeqLines, aSeqTenth;
235
236   // verticals
237   aSeqTenth.Append(gp_Pnt(0., -myYSize, -zl));
238   aSeqTenth.Append(gp_Pnt(0.,  myYSize, -zl));
239   for (nblines = 1, xl = aXStep; xl < myXSize; xl += aXStep, nblines++)
240   {
241     TColgp_SequenceOfPnt &aSeq = (Modulus(nblines, 10) != 0)? aSeqLines : aSeqTenth;
242     aSeq.Append(gp_Pnt( xl, -myYSize, -zl));
243     aSeq.Append(gp_Pnt( xl,  myYSize, -zl));
244     aSeq.Append(gp_Pnt(-xl, -myYSize, -zl));
245     aSeq.Append(gp_Pnt(-xl,  myYSize, -zl));
246   }
247
248   // horizontals
249   aSeqTenth.Append(gp_Pnt(-myXSize, 0., -zl));
250   aSeqTenth.Append(gp_Pnt( myXSize, 0., -zl));
251   for (nblines = 1, yl = aYStep; yl < myYSize; yl += aYStep, nblines++)
252   {
253     TColgp_SequenceOfPnt &aSeq = (Modulus(nblines, 10) != 0)? aSeqLines : aSeqTenth;
254     aSeq.Append(gp_Pnt(-myXSize,  yl, -zl));
255     aSeq.Append(gp_Pnt( myXSize,  yl, -zl));
256     aSeq.Append(gp_Pnt(-myXSize, -yl, -zl));
257     aSeq.Append(gp_Pnt( myXSize, -yl, -zl));
258   }
259
260   if (aSeqLines.Length())
261   {
262     LineAttrib->SetColor (myColor);
263     myGroup->SetPrimitivesAspect (LineAttrib);
264     const Standard_Integer nbv = aSeqLines.Length();
265     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(nbv);
266     Standard_Integer n = 1;
267     while (n<=nbv)
268       aPrims->AddVertex(aSeqLines(n++));
269     myGroup->AddPrimitiveArray(aPrims, Standard_False);
270   }
271   if (aSeqTenth.Length())
272   {
273     LineAttrib->SetColor (myTenthColor);
274     myGroup->SetPrimitivesAspect (LineAttrib);
275     const Standard_Integer nbv = aSeqTenth.Length();
276     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(nbv);
277     Standard_Integer n = 1;
278     while (n<=nbv)
279       aPrims->AddVertex(aSeqTenth(n++));
280     myGroup->AddPrimitiveArray(aPrims, Standard_False);
281   }
282
283   myGroup->SetMinMaxValues(-myXSize, -myYSize, 0.0, myXSize, myYSize, 0.0);
284   myCurXStep = aXStep, myCurYStep = aYStep;
285 }
286
287 void V3d_RectangularGrid::DefinePoints ()
288 {
289   const Standard_Real aXStep = XStep();
290   const Standard_Real aYStep = YStep();
291   const Standard_Boolean toUpdate = !myCurAreDefined
292                                   || myCurDrawMode != Aspect_GDM_Points
293                                   || aXStep != myCurXStep
294                                   || aYStep != myCurYStep;
295   if (!toUpdate)
296   {
297     return;
298   }
299
300   myGroup->Clear ();
301
302   Handle(Graphic3d_AspectMarker3d) MarkerAttrib = new Graphic3d_AspectMarker3d ();
303   MarkerAttrib->SetColor (myColor);
304   MarkerAttrib->SetType (Aspect_TOM_POINT);
305   MarkerAttrib->SetScale (3.);
306
307   // horizontals
308   Standard_Real xl, yl;
309   TColgp_SequenceOfPnt aSeqPnts;
310   for (xl = 0.0; xl <= myXSize; xl += aXStep) {
311     aSeqPnts.Append(gp_Pnt( xl, 0.0, -myOffSet));
312     aSeqPnts.Append(gp_Pnt(-xl, 0.0, -myOffSet));
313     for (yl = aYStep; yl <= myYSize; yl += aYStep) {
314       aSeqPnts.Append(gp_Pnt( xl,  yl, -myOffSet));
315       aSeqPnts.Append(gp_Pnt( xl, -yl, -myOffSet));
316       aSeqPnts.Append(gp_Pnt(-xl,  yl, -myOffSet));
317       aSeqPnts.Append(gp_Pnt(-xl, -yl, -myOffSet));
318     }
319   }
320   if (aSeqPnts.Length())
321   {
322     Standard_Integer i;
323     Standard_Real X,Y,Z;
324     const Standard_Integer nbv = aSeqPnts.Length();
325     Handle(Graphic3d_ArrayOfPoints) Vertical = new Graphic3d_ArrayOfPoints (nbv);
326     for (i=1; i<=nbv; i++)
327     {
328       aSeqPnts(i).Coord(X,Y,Z);
329       Vertical->AddVertex (X,Y,Z);
330     }
331     myGroup->SetGroupPrimitivesAspect (MarkerAttrib);
332     myGroup->AddPrimitiveArray (Vertical, Standard_False);
333   }
334
335   myGroup->SetMinMaxValues(-myXSize, -myYSize, 0.0, myXSize, myYSize, 0.0);
336   myCurXStep = aXStep, myCurYStep = aYStep;
337 }
338
339 void V3d_RectangularGrid::GraphicValues (Standard_Real& theXSize, Standard_Real& theYSize, Standard_Real& theOffSet) const
340 {
341   theXSize = myXSize;
342   theYSize = myYSize;
343   theOffSet = myOffSet;
344 }
345
346 void V3d_RectangularGrid::SetGraphicValues (const Standard_Real theXSize, const Standard_Real theYSize, const Standard_Real theOffSet)
347 {
348   if (! myCurAreDefined) {
349     myXSize = theXSize;
350     myYSize = theYSize;
351     myOffSet = theOffSet;
352   }
353   if (myXSize != theXSize) {
354     myXSize = theXSize;
355     myCurAreDefined = Standard_False;
356   }
357   if (myYSize != theYSize) {
358     myYSize = theYSize;
359     myCurAreDefined = Standard_False;
360   }
361   if (myOffSet != theOffSet) {
362     myOffSet = theOffSet;
363     myCurAreDefined = Standard_False;
364   }
365   if( !myCurAreDefined ) UpdateDisplay();
366 }