0028889: Visualization, V3d_View - View specific Graphic3d_Structure should be remove...
[occt.git] / src / V3d / V3d_CircularGrid.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_CircularGrid.hxx>
15
16 #include <Graphic3d_ArrayOfPoints.hxx>
17 #include <Graphic3d_ArrayOfPolylines.hxx>
18 #include <Graphic3d_ArrayOfSegments.hxx>
19 #include <Graphic3d_AspectLine3d.hxx>
20 #include <Graphic3d_AspectMarker3d.hxx>
21 #include <Graphic3d_Group.hxx>
22 #include <Graphic3d_Structure.hxx>
23 #include <Graphic3d_Vertex.hxx>
24 #include <Quantity_Color.hxx>
25 #include <Standard_Type.hxx>
26 #include <TColgp_SequenceOfPnt.hxx>
27 #include <TColStd_Array2OfReal.hxx>
28 #include <V3d_Viewer.hxx>
29
30 IMPLEMENT_STANDARD_RTTIEXT(V3d_CircularGrid,Aspect_CircularGrid)
31
32 /*----------------------------------------------------------------------*/
33 /*
34  * Constant
35  */
36 #define DIVISION 8
37 #define MYFACTOR 50.
38
39 /*----------------------------------------------------------------------*/
40
41 V3d_CircularGrid::V3d_CircularGrid (const V3d_ViewerPointer& aViewer, const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
42 : Aspect_CircularGrid (1.,8),
43   myStructure (new Graphic3d_Structure (aViewer->StructureManager())),
44   myGroup (myStructure->NewGroup()),
45   myViewer (aViewer),
46   myCurAreDefined (Standard_False)
47 {
48   myColor = aColor;
49   myTenthColor = aTenthColor;
50
51   myStructure->SetInfiniteState (Standard_True);
52
53   const Standard_Real step = 10.;
54   const Standard_Real size = 0.5*myViewer->DefaultViewSize();
55   SetGraphicValues (size, step/MYFACTOR);
56   SetRadiusStep (step);
57 }
58
59 V3d_CircularGrid::~V3d_CircularGrid()
60 {
61   myGroup.Nullify();
62   if (!myStructure.IsNull())
63   {
64     myStructure->Erase();
65   }
66 }
67
68 void V3d_CircularGrid::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_CircularGrid::Display ()
79 {
80   myStructure->SetDisplayPriority (1);
81   myStructure->Display();
82 }
83
84 void V3d_CircularGrid::Erase () const
85 {
86   myStructure->Erase ();
87 }
88
89 Standard_Boolean V3d_CircularGrid::IsDisplayed () const
90 {
91   return myStructure->IsDisplayed ();
92 }
93
94 void V3d_CircularGrid::UpdateDisplay ()
95 {
96   gp_Ax3 ThePlane = myViewer->PrivilegedPlane();
97
98   Standard_Real xl, yl, zl;
99   Standard_Real xdx, xdy, xdz;
100   Standard_Real ydx, ydy, ydz;
101   Standard_Real dx, dy, dz;
102   ThePlane.Location ().Coord (xl, yl, zl);
103   ThePlane.XDirection ().Coord (xdx, xdy, xdz);
104   ThePlane.YDirection ().Coord (ydx, ydy, ydz);
105   ThePlane.Direction ().Coord (dx, dy, dz);
106
107   Standard_Boolean MakeTransform = !myCurAreDefined;
108   if (!MakeTransform)
109   {
110     MakeTransform = (RotationAngle() != myCurAngle || XOrigin() != myCurXo || YOrigin() != myCurYo);
111     if (!MakeTransform)
112     {
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   {
131     const Standard_Real CosAlpha = Cos (RotationAngle ());
132     const Standard_Real SinAlpha = Sin (RotationAngle ());
133
134     gp_Trsf aTrsf;
135     // Translation
136     // Transformation of change of marker
137     aTrsf.SetValues (xdx, ydx, dx, xl,
138                      xdy, ydy, dy, yl,
139                      xdz, ydz, dz, zl);
140
141     // Translation of the origin
142     // Rotation Alpha around axis -Z
143     gp_Trsf aTrsf2;
144     aTrsf2.SetValues ( CosAlpha, SinAlpha, 0.0, -XOrigin(),
145                       -SinAlpha, CosAlpha, 0.0, -YOrigin(),
146                             0.0,      0.0, 1.0, 0.0);
147     aTrsf.Multiply (aTrsf2);
148     myStructure->SetTransformation (new Geom_Transformation (aTrsf));
149
150     myCurAngle = RotationAngle ();
151     myCurXo = XOrigin (), myCurYo = YOrigin ();
152     myCurViewPlane = ThePlane;
153   }
154
155   switch (myDrawMode)
156   {
157     case Aspect_GDM_Points:
158       DefinePoints ();
159       myCurDrawMode = Aspect_GDM_Points;
160       break;
161     case Aspect_GDM_Lines:
162       DefineLines ();
163       myCurDrawMode = Aspect_GDM_Lines;
164       break;
165     case Aspect_GDM_None:
166       myCurDrawMode = Aspect_GDM_None;
167       break;
168   }
169   myCurAreDefined = Standard_True;
170 }
171
172 void V3d_CircularGrid::DefineLines ()
173 {
174   const Standard_Real    aStep     = RadiusStep ();
175   const Standard_Real    aDivision = DivisionNumber ();
176   const Standard_Boolean toUpdate  = !myCurAreDefined
177                                   || myCurDrawMode != Aspect_GDM_Lines
178                                   || aDivision != myCurDivi
179                                   || aStep     != myCurStep;
180   if (!toUpdate)
181   {
182     return;
183   }
184
185   myGroup->Clear ();
186
187   const Standard_Integer Division = (Standard_Integer )( (aDivision >= DIVISION ? aDivision : DIVISION));
188
189   Standard_Integer nbpnts = 2 * Division;
190   // diametres
191   Standard_Real alpha = M_PI / aDivision;
192
193   myGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myTenthColor, Aspect_TOL_SOLID, 1.0));
194   Handle(Graphic3d_ArrayOfSegments) aPrims1 = new Graphic3d_ArrayOfSegments(2*nbpnts);
195   const gp_Pnt p0(0., 0., -myOffSet);
196   for (Standard_Integer i=1; i<=nbpnts; i++) {
197     aPrims1->AddVertex(p0);
198     aPrims1->AddVertex(Cos(alpha*i)*myRadius, Sin(alpha*i)*myRadius, -myOffSet);
199   }
200   myGroup->AddPrimitiveArray(aPrims1, Standard_False);
201
202   // circles
203   nbpnts = 2 * Division + 1;
204   alpha = M_PI / Division;
205   Standard_Integer nblines = 0;
206   TColgp_SequenceOfPnt aSeqLines, aSeqTenth;
207   for (Standard_Real r=aStep; r<=myRadius; r+=aStep, nblines++) {
208     const Standard_Boolean isTenth = (Modulus(nblines, 10) == 0);
209     for (Standard_Integer i=0; i<nbpnts; i++) {
210       const gp_Pnt pt(Cos(alpha*i)*r,Sin(alpha*i)*r,-myOffSet);
211       (isTenth? aSeqTenth : aSeqLines).Append(pt);
212     }
213   }
214   if (aSeqTenth.Length())
215   {
216     myGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myTenthColor, Aspect_TOL_SOLID, 1.0));
217     Standard_Integer n, np;
218     const Standard_Integer nbl = aSeqTenth.Length() / nbpnts;
219     Handle(Graphic3d_ArrayOfPolylines) aPrims2 = new Graphic3d_ArrayOfPolylines(aSeqTenth.Length(),nbl);
220     for (np = 1, n=0; n<nbl; n++) {
221       aPrims2->AddBound(nbpnts);
222       for (Standard_Integer i=0; i<nbpnts; i++, np++)
223         aPrims2->AddVertex(aSeqTenth(np));
224   }
225     myGroup->AddPrimitiveArray(aPrims2, Standard_False);
226   }
227   if (aSeqLines.Length())
228   {
229     myGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (myColor, Aspect_TOL_SOLID, 1.0));
230     Standard_Integer n, np;
231     const Standard_Integer nbl = aSeqLines.Length() / nbpnts;
232     Handle(Graphic3d_ArrayOfPolylines) aPrims3 = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),nbl);
233     for (np = 1, n=0; n<nbl; n++) {
234       aPrims3->AddBound(nbpnts);
235       for (Standard_Integer i=0; i<nbpnts; i++, np++)
236         aPrims3->AddVertex(aSeqLines(np));
237   }
238     myGroup->AddPrimitiveArray(aPrims3, Standard_False);
239   }
240
241   myGroup->SetMinMaxValues(-myRadius, -myRadius, 0.0, myRadius, myRadius, 0.0);
242   myCurStep = aStep, myCurDivi = (Standard_Integer ) aDivision;
243 }
244
245 void V3d_CircularGrid::DefinePoints ()
246 {
247   const Standard_Real    aStep     = RadiusStep();
248   const Standard_Real    aDivision = DivisionNumber();
249   const Standard_Boolean toUpdate  = !myCurAreDefined
250                                   || myCurDrawMode != Aspect_GDM_Points
251                                   || aDivision != myCurDivi
252                                   || aStep     != myCurStep;
253   if (!toUpdate)
254   {
255     return;
256   }
257
258   myGroup->Clear ();
259
260   Handle(Graphic3d_AspectMarker3d) MarkerAttrib = new Graphic3d_AspectMarker3d ();
261   MarkerAttrib->SetColor (myColor);
262   MarkerAttrib->SetType (Aspect_TOM_POINT);
263   MarkerAttrib->SetScale (3.);
264
265   const Standard_Integer nbpnts = Standard_Integer (2*aDivision);
266   Standard_Real r, alpha = M_PI / aDivision;
267
268   // diameters
269   TColgp_SequenceOfPnt aSeqPnts;
270   aSeqPnts.Append(gp_Pnt(0.0, 0.0, -myOffSet));
271   for (r=aStep; r<=myRadius; r+=aStep) {
272     for (Standard_Integer i=0; i<nbpnts; i++)
273       aSeqPnts.Append(gp_Pnt(Cos(alpha*i)*r, Sin(alpha*i)*r, -myOffSet));
274   }
275   myGroup->SetGroupPrimitivesAspect (MarkerAttrib);
276   if (aSeqPnts.Length())
277   {
278     Standard_Real X,Y,Z;
279     const Standard_Integer nbv = aSeqPnts.Length();
280     Handle(Graphic3d_ArrayOfPoints) Cercle = new Graphic3d_ArrayOfPoints (nbv);
281     for (Standard_Integer i=1; i<=nbv; i++)
282     {
283       aSeqPnts(i).Coord(X,Y,Z);
284       Cercle->AddVertex (X,Y,Z);
285     }
286     myGroup->AddPrimitiveArray (Cercle, Standard_False);
287   }
288   myGroup->SetMinMaxValues(-myRadius, -myRadius, 0.0, myRadius, myRadius, 0.0);
289
290   myCurStep = aStep, myCurDivi = (Standard_Integer ) aDivision;
291 }
292
293 void V3d_CircularGrid::GraphicValues (Standard_Real& theRadius, Standard_Real& theOffSet) const
294 {
295   theRadius = myRadius;
296   theOffSet = myOffSet;
297 }
298
299 void V3d_CircularGrid::SetGraphicValues (const Standard_Real theRadius, const Standard_Real theOffSet)
300 {
301   if (! myCurAreDefined) {
302     myRadius = theRadius;
303     myOffSet = theOffSet;
304   }
305   if (myRadius != theRadius) {
306     myRadius = theRadius;
307     myCurAreDefined = Standard_False;
308   }
309   if (myOffSet != theOffSet) {
310     myOffSet = theOffSet;
311     myCurAreDefined = Standard_False;
312   }
313   if( !myCurAreDefined ) UpdateDisplay();
314 }