0024131: TKOpenGL redesign GPU memory management for markers presentation
[occt.git] / src / V3d / V3d_CircularGrid.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 /***********************************************************************
19  
20      FONCTION :
21      ----------
22         Classe V3d_CircularGrid :
23  
24      VERSION HISTORY  :
25      --------------------------------
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 #define IMP300300       //GG
41 //                      -> Draw circles with 2 colors (tenth and normal colors)
42
43 /*----------------------------------------------------------------------*/
44 /*
45  * Includes
46  */
47
48 #include <V3d_CircularGrid.ixx>
49
50 #include <TColStd_Array2OfReal.hxx>
51 #include <Graphic3d_AspectLine3d.hxx>
52 #include <Graphic3d_AspectMarker3d.hxx>
53 #include <Graphic3d_Vertex.hxx>
54 #include <Graphic3d_Array1OfVertex.hxx>
55 #include <Graphic3d_ArrayOfSegments.hxx>
56 #include <Graphic3d_ArrayOfPoints.hxx>
57 #include <Graphic3d_ArrayOfPolylines.hxx>
58 #include <Visual3d_ViewManager.hxx>
59 #include <V3d_Viewer.hxx>
60 #include <TColgp_SequenceOfPnt.hxx>
61
62 /*----------------------------------------------------------------------*/
63 /*
64  * Constant
65  */
66
67 #define DIVISION 8
68 #define MYMINMAX 25.
69 #define MYFACTOR 50.
70
71 /*----------------------------------------------------------------------*/
72
73 V3d_CircularGrid::V3d_CircularGrid (const V3d_ViewerPointer& aViewer, const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
74 : Aspect_CircularGrid (1.,8),
75   myStructure (new Graphic3d_Structure (aViewer->Viewer ())),
76   myGroup (new Graphic3d_Group (myStructure)),
77   myViewer (aViewer),
78   myCurAreDefined (Standard_False)
79 {
80   myColor = aColor;
81   myTenthColor = aTenthColor;
82
83   myStructure->SetInfiniteState (Standard_True);
84
85   const Standard_Real step = 10.;
86   const Standard_Real size = 0.5*myViewer->DefaultViewSize();
87   SetGraphicValues (size, step/MYFACTOR);
88   SetRadiusStep (step);
89 }
90
91 void V3d_CircularGrid::SetColors (const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
92 {
93   if( myColor != aColor || myTenthColor != aTenthColor ) {
94     myColor = aColor;
95     myTenthColor = aTenthColor;
96     myCurAreDefined = Standard_False;
97     UpdateDisplay();
98   }
99 }
100
101 void V3d_CircularGrid::Display ()
102 {
103   myStructure->Display (1);
104 }
105
106 void V3d_CircularGrid::Erase () const
107 {
108   myStructure->Erase ();
109 }
110
111 Standard_Boolean V3d_CircularGrid::IsDisplayed () const
112 {
113   return myStructure->IsDisplayed ();
114 }
115
116 void V3d_CircularGrid::UpdateDisplay ()
117 {
118   gp_Ax3 ThePlane = myViewer->PrivilegedPlane();
119
120   Standard_Real xl, yl, zl;
121   Standard_Real xdx, xdy, xdz;
122   Standard_Real ydx, ydy, ydz;
123   Standard_Real dx, dy, dz;
124   ThePlane.Location ().Coord (xl, yl, zl);
125   ThePlane.XDirection ().Coord (xdx, xdy, xdz);
126   ThePlane.YDirection ().Coord (ydx, ydy, ydz);
127   ThePlane.Direction ().Coord (dx, dy, dz);
128
129   Standard_Boolean MakeTransform = !myCurAreDefined;
130   if (!MakeTransform)
131   {
132     MakeTransform = (RotationAngle() != myCurAngle || XOrigin() != myCurXo || YOrigin() != myCurYo);
133     if (!MakeTransform)
134     {
135       Standard_Real curxl, curyl, curzl;
136       Standard_Real curxdx, curxdy, curxdz;
137       Standard_Real curydx, curydy, curydz;
138       Standard_Real curdx, curdy, curdz;
139       myCurViewPlane.Location ().Coord (curxl, curyl, curzl);
140       myCurViewPlane.XDirection ().Coord (curxdx, curxdy, curxdz);
141       myCurViewPlane.YDirection ().Coord (curydx, curydy, curydz);
142       myCurViewPlane.Direction ().Coord (curdx, curdy, curdz);
143       if (xl != curxl || yl != curyl || zl != curzl ||
144           xdx != curxdx || xdy != curxdy || xdz != curxdz ||
145           ydx != curydx || ydy != curydy || ydz != curydz ||
146           dx != curdx || dy != curdy || dz != curdz)
147         MakeTransform = Standard_True;
148     }
149   }
150
151   if (MakeTransform)
152   {
153     const Standard_Real CosAlpha = Cos (RotationAngle ());
154     const Standard_Real SinAlpha = Sin (RotationAngle ());
155     TColStd_Array2OfReal Trsf (1, 4, 1, 4);
156     Trsf (4, 4) = 1.0;
157     Trsf (4, 1) = Trsf (4, 2) = Trsf (4, 3) = 0.0;
158     // Translation
159     Trsf (1, 4) = xl,
160     Trsf (2, 4) = yl,
161     Trsf (3, 4) = zl;
162     // Transformation  change of marker
163     Trsf (1, 1) = xdx,
164     Trsf (2, 1) = xdy,
165     Trsf (3, 1) = xdz,
166     Trsf (1, 2) = ydx,
167     Trsf (2, 2) = ydy,
168     Trsf (3, 2) = ydz,
169     Trsf (1, 3) = dx,
170     Trsf (2, 3) = dy,
171     Trsf (3, 3) = dz;
172     myStructure->SetTransform (Trsf, Graphic3d_TOC_REPLACE);
173
174     // Translation of the origin
175     Trsf (1, 4) = -XOrigin (),
176     Trsf (2, 4) = -YOrigin (),
177     Trsf (3, 4) = 0.0;
178     // Rotation Alpha around axis -Z
179     Trsf (1, 1) = CosAlpha,
180     Trsf (2, 1) = -SinAlpha,
181     Trsf (3, 1) = 0.0,
182     Trsf (1, 2) = SinAlpha,
183     Trsf (2, 2) = CosAlpha,
184     Trsf (3, 2) = 0.0,
185     Trsf (1, 3) = 0.0,
186     Trsf (2, 3) = 0.0,
187     Trsf (3, 3) = 1.0;
188     myStructure->SetTransform (Trsf,Graphic3d_TOC_POSTCONCATENATE);
189
190     myCurAngle = RotationAngle ();
191     myCurXo = XOrigin (), myCurYo = YOrigin ();
192     myCurViewPlane = ThePlane;
193   }
194
195   switch (DrawMode())
196   {
197     default:
198     //case Aspect_GDM_Points:
199       DefinePoints ();
200       myCurDrawMode = Aspect_GDM_Points;
201       break;
202     case Aspect_GDM_Lines:
203       DefineLines ();
204       myCurDrawMode = Aspect_GDM_Lines;
205       break;
206 #ifdef IMP210100
207     case Aspect_GDM_None:
208       myCurDrawMode = Aspect_GDM_None;
209       break;
210 #endif
211   }
212   myCurAreDefined = Standard_True;
213 }
214
215 void V3d_CircularGrid::DefineLines ()
216 {
217   const Standard_Real    aStep     = RadiusStep ();
218   const Standard_Real    aDivision = DivisionNumber ();
219   const Standard_Boolean toUpdate  = !myCurAreDefined
220                                   || myCurDrawMode != Aspect_GDM_Lines
221                                   || aDivision != myCurDivi
222                                   || aStep     != myCurStep;
223   if (!toUpdate)
224   {
225     return;
226   }
227
228   myGroup->Clear ();
229
230   Handle(Graphic3d_AspectLine3d) LineAttrib = new Graphic3d_AspectLine3d ();
231   LineAttrib->SetColor (myColor);
232   LineAttrib->SetType (Aspect_TOL_SOLID);
233   LineAttrib->SetWidth (1.0);
234
235   const Standard_Integer Division = (Standard_Integer )( (aDivision >= DIVISION ? aDivision : DIVISION));
236
237   Standard_Integer nbpnts = 2 * Division;
238   // diametres
239   Standard_Real alpha = M_PI / aDivision;
240   LineAttrib->SetColor (myTenthColor);
241   myGroup->SetGroupPrimitivesAspect (LineAttrib);
242   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2*nbpnts);
243   const gp_Pnt p0(0., 0., -myOffSet);
244   for (Standard_Integer i=1; i<=nbpnts; i++) {
245     aPrims->AddVertex(p0);
246     aPrims->AddVertex(Cos(alpha*i)*myRadius, Sin(alpha*i)*myRadius, -myOffSet);
247   }
248   myGroup->AddPrimitiveArray(aPrims, Standard_False);
249
250   // circles
251   nbpnts = 2 * Division + 1;
252   alpha = M_PI / Division;
253   Standard_Integer nblines = 0;
254   TColgp_SequenceOfPnt aSeqLines, aSeqTenth;
255   for (Standard_Real r=aStep; r<=myRadius; r+=aStep, nblines++) {
256     const Standard_Boolean isTenth = (Modulus(nblines, 10) == 0);
257     for (Standard_Integer i=0; i<nbpnts; i++) {
258       const gp_Pnt pt(Cos(alpha*i)*r,Sin(alpha*i)*r,-myOffSet);
259       (isTenth? aSeqTenth : aSeqLines).Append(pt);
260     }
261   }
262   if (aSeqTenth.Length())
263   {
264     LineAttrib->SetColor (myTenthColor);
265     myGroup->SetGroupPrimitivesAspect (LineAttrib);
266     Standard_Integer n, np;
267     const Standard_Integer nbl = aSeqTenth.Length() / nbpnts;
268     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqTenth.Length(),nbl);
269     for (np = 1, n=0; n<nbl; n++) {
270       aPrims->AddBound(nbpnts);
271       for (Standard_Integer i=0; i<nbpnts; i++, np++)
272         aPrims->AddVertex(aSeqTenth(np));
273   }
274     myGroup->AddPrimitiveArray(aPrims, Standard_False);
275   }
276   if (aSeqLines.Length())
277   {
278     LineAttrib->SetColor (myColor);
279     myGroup->SetPrimitivesAspect (LineAttrib);
280     Standard_Integer n, np;
281     const Standard_Integer nbl = aSeqLines.Length() / nbpnts;
282     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),nbl);
283     for (np = 1, n=0; n<nbl; n++) {
284       aPrims->AddBound(nbpnts);
285       for (Standard_Integer i=0; i<nbpnts; i++, np++)
286         aPrims->AddVertex(aSeqLines(np));
287   }
288     myGroup->AddPrimitiveArray(aPrims, Standard_False);
289   }
290
291   myGroup->SetMinMaxValues(-myRadius, -myRadius, 0.0, myRadius, myRadius, 0.0);
292   myCurStep = aStep, myCurDivi = (Standard_Integer ) aDivision;
293 }
294
295 void V3d_CircularGrid::DefinePoints ()
296 {
297   const Standard_Real    aStep     = RadiusStep();
298   const Standard_Real    aDivision = DivisionNumber();
299   const Standard_Boolean toUpdate  = !myCurAreDefined
300                                   || myCurDrawMode != Aspect_GDM_Points
301                                   || aDivision != myCurDivi
302                                   || aStep     != myCurStep;
303   if (!toUpdate)
304   {
305     return;
306   }
307
308   myGroup->Clear ();
309
310   Handle(Graphic3d_AspectMarker3d) MarkerAttrib = new Graphic3d_AspectMarker3d ();
311   MarkerAttrib->SetColor (myColor);
312   MarkerAttrib->SetType (Aspect_TOM_POINT);
313   MarkerAttrib->SetScale (3.);
314
315   const Standard_Integer nbpnts = Standard_Integer (2*aDivision);
316   Standard_Real r, alpha = M_PI / aDivision;
317
318   // diameters
319   TColgp_SequenceOfPnt aSeqPnts;
320   aSeqPnts.Append(gp_Pnt(0.0, 0.0, -myOffSet));
321   for (r=aStep; r<=myRadius; r+=aStep) {
322     for (Standard_Integer i=0; i<nbpnts; i++)
323       aSeqPnts.Append(gp_Pnt(Cos(alpha*i)*r, Sin(alpha*i)*r, -myOffSet));
324   }
325   myGroup->SetGroupPrimitivesAspect (MarkerAttrib);
326   if (aSeqPnts.Length())
327   {
328     Standard_Real X,Y,Z;
329     const Standard_Integer nbv = aSeqPnts.Length();
330     Handle(Graphic3d_ArrayOfPoints) Cercle = new Graphic3d_ArrayOfPoints (nbv);
331     for (Standard_Integer i=1; i<=nbv; i++)
332     {
333       aSeqPnts(i).Coord(X,Y,Z);
334       Cercle->AddVertex (X,Y,Z);
335     }
336     myGroup->AddPrimitiveArray (Cercle, Standard_False);
337   }
338   myGroup->SetMinMaxValues(-myRadius, -myRadius, 0.0, myRadius, myRadius, 0.0);
339
340   myCurStep = aStep, myCurDivi = (Standard_Integer ) aDivision;
341 }
342
343 void V3d_CircularGrid::GraphicValues (Standard_Real& theRadius, Standard_Real& theOffSet) const
344 {
345   theRadius = myRadius;
346   theOffSet = myOffSet;
347 }
348
349 void V3d_CircularGrid::SetGraphicValues (const Standard_Real theRadius, const Standard_Real theOffSet)
350 {
351   if (! myCurAreDefined) {
352     myRadius = theRadius;
353     myOffSet = theOffSet;
354   }
355   if (myRadius != theRadius) {
356     myRadius = theRadius;
357     myCurAreDefined = Standard_False;
358   }
359   if (myOffSet != theOffSet) {
360     myOffSet = theOffSet;
361     myCurAreDefined = Standard_False;
362   }
363   if( !myCurAreDefined ) UpdateDisplay();
364 }