0029395: Visualization, V3d_View - Grid disappears forever after enabling RayTracing
[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 #include <V3d_RectangularGrid.hxx>
15
16 #include <Graphic3d_ArrayOfPoints.hxx>
17 #include <Graphic3d_ArrayOfSegments.hxx>
18 #include <Graphic3d_AspectLine3d.hxx>
19 #include <Graphic3d_AspectMarker3d.hxx>
20 #include <Graphic3d_AspectText3d.hxx>
21 #include <Graphic3d_Group.hxx>
22 #include <Graphic3d_Structure.hxx>
23 #include <Quantity_Color.hxx>
24 #include <Standard_Type.hxx>
25 #include <TColgp_SequenceOfPnt.hxx>
26 #include <TColStd_Array2OfReal.hxx>
27 #include <V3d_Viewer.hxx>
28
29 IMPLEMENT_STANDARD_RTTIEXT(V3d_RectangularGrid,Aspect_RectangularGrid)
30
31 #define MYFACTOR 50.
32
33 //! Dummy implementation of Graphic3d_Structure overriding ::Compute() method for handling Device Lost.
34 class V3d_RectangularGrid::RectangularGridStructure : public Graphic3d_Structure
35 {
36 public:
37   //! Main constructor.
38   RectangularGridStructure (const Handle(Graphic3d_StructureManager)& theManager, V3d_RectangularGrid* theGrid)
39   : Graphic3d_Structure (theManager), myGrid (theGrid) {}
40
41   //! Override method initiating recomputing in V3d_RectangularGrid.
42   virtual void Compute() Standard_OVERRIDE
43   {
44     GraphicClear (Standard_False);
45     myGrid->myGroup = NewGroup();
46     myGrid->myCurAreDefined = Standard_False;
47     myGrid->UpdateDisplay();
48   }
49
50 private:
51   V3d_RectangularGrid* myGrid;
52 };
53
54 /*----------------------------------------------------------------------*/
55
56 V3d_RectangularGrid::V3d_RectangularGrid (const V3d_ViewerPointer& aViewer, const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
57 : Aspect_RectangularGrid (1.,1.),
58   myViewer (aViewer),
59   myCurAreDefined (Standard_False),
60   myToComputePrs (Standard_True)
61 {
62   myColor = aColor;
63   myTenthColor = aTenthColor;
64
65   myStructure = new RectangularGridStructure (aViewer->StructureManager(), this);
66   myGroup = myStructure->NewGroup();
67   myStructure->SetInfiniteState (Standard_True);
68
69   const Standard_Real step = 10.;
70   const Standard_Real gstep = step/MYFACTOR;
71   const Standard_Real size = 0.5*myViewer->DefaultViewSize();
72   SetGraphicValues (size, size, gstep);
73   SetXStep (step);
74   SetYStep (step);
75 }
76
77 V3d_RectangularGrid::~V3d_RectangularGrid()
78 {
79   myGroup.Nullify();
80   if (!myStructure.IsNull())
81   {
82     myStructure->Erase();
83   }
84 }
85
86 void V3d_RectangularGrid::SetColors (const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
87 {
88   if( myColor != aColor || myTenthColor != aTenthColor ) {
89     myColor = aColor;
90     myTenthColor = aTenthColor;
91     myCurAreDefined = Standard_False;
92     UpdateDisplay();
93   }
94 }
95
96 void V3d_RectangularGrid::Display ()
97 {
98   myStructure->SetDisplayPriority (1);
99   myStructure->Display();
100   UpdateDisplay();
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
152     gp_Trsf aTrsf;
153     // Translation
154     // Transformation of change of marker
155     aTrsf.SetValues (xdx, ydx, dx, xl,
156                      xdy, ydy, dy, yl,
157                      xdz, ydz, dz, zl);
158
159     // Translation of the origin
160     // Rotation Alpha around axis -Z
161     gp_Trsf aTrsf2;
162     aTrsf2.SetValues ( CosAlpha, SinAlpha, 0.0, -XOrigin(),
163                       -SinAlpha, CosAlpha, 0.0, -YOrigin(),
164                             0.0,      0.0, 1.0, 0.0);
165     aTrsf.Multiply (aTrsf2);
166     myStructure->SetTransformation (new Geom_Transformation (aTrsf));
167
168     myCurAngle = RotationAngle ();
169     myCurXo = XOrigin (), myCurYo = YOrigin ();
170     myCurViewPlane = ThePlane;
171   }
172
173   switch (myDrawMode)
174   {
175     case Aspect_GDM_Points:
176       DefinePoints ();
177       myCurDrawMode = Aspect_GDM_Points;
178       break;
179     case Aspect_GDM_Lines:
180       DefineLines ();
181       myCurDrawMode = Aspect_GDM_Lines;
182       break;
183     case Aspect_GDM_None:
184       myCurDrawMode = Aspect_GDM_None;
185       break;
186         }
187         myCurAreDefined = Standard_True;
188 }
189
190 void V3d_RectangularGrid::DefineLines ()
191 {
192   const Standard_Real aXStep = XStep();
193   const Standard_Real aYStep = YStep();
194   const Standard_Boolean toUpdate = !myCurAreDefined
195                                  || myCurDrawMode != Aspect_GDM_Lines
196                                  || aXStep != myCurXStep
197                                  || aYStep != myCurYStep;
198   if (!toUpdate
199    && !myToComputePrs)
200   {
201     return;
202   }
203   else if (!myStructure->IsDisplayed())
204   {
205     myToComputePrs = Standard_True;
206     return;
207   }
208
209   myToComputePrs = Standard_False;
210   myGroup->Clear();
211
212   Standard_Integer nblines;
213   Standard_Real xl, yl, zl = myOffSet;
214
215   TColgp_SequenceOfPnt aSeqLines, aSeqTenth;
216
217   // verticals
218   aSeqTenth.Append(gp_Pnt(0., -myYSize, -zl));
219   aSeqTenth.Append(gp_Pnt(0.,  myYSize, -zl));
220   for (nblines = 1, xl = aXStep; xl < myXSize; xl += aXStep, nblines++)
221   {
222     TColgp_SequenceOfPnt &aSeq = (Modulus(nblines, 10) != 0)? aSeqLines : aSeqTenth;
223     aSeq.Append(gp_Pnt( xl, -myYSize, -zl));
224     aSeq.Append(gp_Pnt( xl,  myYSize, -zl));
225     aSeq.Append(gp_Pnt(-xl, -myYSize, -zl));
226     aSeq.Append(gp_Pnt(-xl,  myYSize, -zl));
227   }
228
229   // horizontals
230   aSeqTenth.Append(gp_Pnt(-myXSize, 0., -zl));
231   aSeqTenth.Append(gp_Pnt( myXSize, 0., -zl));
232   for (nblines = 1, yl = aYStep; yl < myYSize; yl += aYStep, nblines++)
233   {
234     TColgp_SequenceOfPnt &aSeq = (Modulus(nblines, 10) != 0)? aSeqLines : aSeqTenth;
235     aSeq.Append(gp_Pnt(-myXSize,  yl, -zl));
236     aSeq.Append(gp_Pnt( myXSize,  yl, -zl));
237     aSeq.Append(gp_Pnt(-myXSize, -yl, -zl));
238     aSeq.Append(gp_Pnt( myXSize, -yl, -zl));
239   }
240
241   if (aSeqLines.Length())
242   {
243     Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d (myColor, Aspect_TOL_SOLID, 1.0);
244     myGroup->SetPrimitivesAspect (aLineAspect);
245     const Standard_Integer nbv = aSeqLines.Length();
246     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(nbv);
247     Standard_Integer n = 1;
248     while (n<=nbv)
249       aPrims->AddVertex(aSeqLines(n++));
250     myGroup->AddPrimitiveArray(aPrims, Standard_False);
251   }
252   if (aSeqTenth.Length())
253   {
254     Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d (myTenthColor, Aspect_TOL_SOLID, 1.0);
255     myGroup->SetPrimitivesAspect (aLineAspect);
256     const Standard_Integer nbv = aSeqTenth.Length();
257     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(nbv);
258     Standard_Integer n = 1;
259     while (n<=nbv)
260       aPrims->AddVertex(aSeqTenth(n++));
261     myGroup->AddPrimitiveArray(aPrims, Standard_False);
262   }
263
264   myGroup->SetMinMaxValues(-myXSize, -myYSize, 0.0, myXSize, myYSize, 0.0);
265   myCurXStep = aXStep, myCurYStep = aYStep;
266
267   // update bounding box
268   myStructure->CalculateBoundBox();
269   myViewer->StructureManager()->Update (myStructure->GetZLayer());
270 }
271
272 void V3d_RectangularGrid::DefinePoints ()
273 {
274   const Standard_Real aXStep = XStep();
275   const Standard_Real aYStep = YStep();
276   const Standard_Boolean toUpdate = !myCurAreDefined
277                                   || myCurDrawMode != Aspect_GDM_Points
278                                   || aXStep != myCurXStep
279                                   || aYStep != myCurYStep;
280   if (!toUpdate
281    && !myToComputePrs)
282   {
283     return;
284   }
285   else if (!myStructure->IsDisplayed())
286   {
287     myToComputePrs = Standard_True;
288     return;
289   }
290
291   myToComputePrs = Standard_False;
292   myGroup->Clear();
293
294   // horizontals
295   Standard_Real xl, yl;
296   TColgp_SequenceOfPnt aSeqPnts;
297   for (xl = 0.0; xl <= myXSize; xl += aXStep) {
298     aSeqPnts.Append(gp_Pnt( xl, 0.0, -myOffSet));
299     aSeqPnts.Append(gp_Pnt(-xl, 0.0, -myOffSet));
300     for (yl = aYStep; yl <= myYSize; yl += aYStep) {
301       aSeqPnts.Append(gp_Pnt( xl,  yl, -myOffSet));
302       aSeqPnts.Append(gp_Pnt( xl, -yl, -myOffSet));
303       aSeqPnts.Append(gp_Pnt(-xl,  yl, -myOffSet));
304       aSeqPnts.Append(gp_Pnt(-xl, -yl, -myOffSet));
305     }
306   }
307   if (aSeqPnts.Length())
308   {
309     Standard_Integer i;
310     Standard_Real X,Y,Z;
311     const Standard_Integer nbv = aSeqPnts.Length();
312     Handle(Graphic3d_ArrayOfPoints) Vertical = new Graphic3d_ArrayOfPoints (nbv);
313     for (i=1; i<=nbv; i++)
314     {
315       aSeqPnts(i).Coord(X,Y,Z);
316       Vertical->AddVertex (X,Y,Z);
317     }
318
319     Handle(Graphic3d_AspectMarker3d) aMarkerAspect = new Graphic3d_AspectMarker3d (Aspect_TOM_POINT, myColor, 3.0);
320     myGroup->SetGroupPrimitivesAspect (aMarkerAspect);
321     myGroup->AddPrimitiveArray (Vertical, Standard_False);
322   }
323
324   myGroup->SetMinMaxValues(-myXSize, -myYSize, 0.0, myXSize, myYSize, 0.0);
325   myCurXStep = aXStep, myCurYStep = aYStep;
326
327   // update bounding box
328   myStructure->CalculateBoundBox();
329   myViewer->StructureManager()->Update (myStructure->GetZLayer());
330 }
331
332 void V3d_RectangularGrid::GraphicValues (Standard_Real& theXSize, Standard_Real& theYSize, Standard_Real& theOffSet) const
333 {
334   theXSize = myXSize;
335   theYSize = myYSize;
336   theOffSet = myOffSet;
337 }
338
339 void V3d_RectangularGrid::SetGraphicValues (const Standard_Real theXSize, const Standard_Real theYSize, const Standard_Real theOffSet)
340 {
341   if (! myCurAreDefined) {
342     myXSize = theXSize;
343     myYSize = theYSize;
344     myOffSet = theOffSet;
345   }
346   if (myXSize != theXSize) {
347     myXSize = theXSize;
348     myCurAreDefined = Standard_False;
349   }
350   if (myYSize != theYSize) {
351     myYSize = theYSize;
352     myCurAreDefined = Standard_False;
353   }
354   if (myOffSet != theOffSet) {
355     myOffSet = theOffSet;
356     myCurAreDefined = Standard_False;
357   }
358   if( !myCurAreDefined ) UpdateDisplay();
359 }