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