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