0026154: Visualization - v3d viewer grid disappears due to automatic z-fit
[occt.git] / src / V3d / V3d_CircularGrid.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
59ec40f8 14#include <V3d_CircularGrid.hxx>
7fd59977 15
a577aaab 16#include <Graphic3d_ArrayOfPoints.hxx>
b8ddfc2f 17#include <Graphic3d_ArrayOfPolylines.hxx>
42cf5bc1 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>
42cf5bc1 23#include <Quantity_Color.hxx>
24#include <Standard_Type.hxx>
b8ddfc2f 25#include <TColgp_SequenceOfPnt.hxx>
42cf5bc1 26#include <TColStd_Array2OfReal.hxx>
42cf5bc1 27#include <V3d_Viewer.hxx>
7fd59977 28
92efcf78 29IMPLEMENT_STANDARD_RTTIEXT(V3d_CircularGrid,Aspect_CircularGrid)
30
e36ee967 31namespace
32{
33 static const Standard_Real THE_DEFAULT_GRID_STEP = 10.0;
34 #define DIVISION 8
35 #define MYFACTOR 50.
36}
7fd59977 37
5f6e3a07 38//! Dummy implementation of Graphic3d_Structure overriding ::Compute() method for handling Device Lost.
39class V3d_CircularGrid::CircularGridStructure : public Graphic3d_Structure
40{
41public:
42 //! Main constructor.
43 CircularGridStructure (const Handle(Graphic3d_StructureManager)& theManager, V3d_CircularGrid* theGrid)
44 : Graphic3d_Structure (theManager), myGrid (theGrid) {}
45
46 //! Override method initiating recomputing in V3d_CircularGrid.
47 virtual void Compute() Standard_OVERRIDE
48 {
49 GraphicClear (Standard_False);
50 myGrid->myGroup = NewGroup();
51 myGrid->myCurAreDefined = Standard_False;
52 myGrid->UpdateDisplay();
53 }
54
55private:
56 V3d_CircularGrid* myGrid;
57};
58
7fd59977 59/*----------------------------------------------------------------------*/
60
b8ddfc2f 61V3d_CircularGrid::V3d_CircularGrid (const V3d_ViewerPointer& aViewer, const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
62: Aspect_CircularGrid (1.,8),
b8ddfc2f 63 myViewer (aViewer),
5f6e3a07 64 myCurAreDefined (Standard_False),
e36ee967 65 myToComputePrs (Standard_False),
66 myCurDrawMode (Aspect_GDM_Lines),
67 myCurXo (0.0),
68 myCurYo (0.0),
69 myCurAngle (0.0),
70 myCurStep (0.0),
71 myCurDivi (0),
72 myRadius (0.5 * aViewer->DefaultViewSize()),
73 myOffSet (THE_DEFAULT_GRID_STEP / MYFACTOR)
7fd59977 74{
b8ddfc2f 75 myColor = aColor;
76 myTenthColor = aTenthColor;
7fd59977 77
5f6e3a07 78 myStructure = new CircularGridStructure (aViewer->StructureManager(), this);
79 myGroup = myStructure->NewGroup();
b8ddfc2f 80 myStructure->SetInfiniteState (Standard_True);
7fd59977 81
e36ee967 82 SetRadiusStep (THE_DEFAULT_GRID_STEP);
7fd59977 83}
84
475c2302 85V3d_CircularGrid::~V3d_CircularGrid()
86{
87 myGroup.Nullify();
88 if (!myStructure.IsNull())
89 {
90 myStructure->Erase();
91 }
92}
93
b8ddfc2f 94void V3d_CircularGrid::SetColors (const Quantity_Color& aColor, const Quantity_Color& aTenthColor)
95{
96 if( myColor != aColor || myTenthColor != aTenthColor ) {
97 myColor = aColor;
98 myTenthColor = aTenthColor;
99 myCurAreDefined = Standard_False;
100 UpdateDisplay();
101 }
7fd59977 102}
103
b8ddfc2f 104void V3d_CircularGrid::Display ()
105{
a1954302 106 myStructure->SetDisplayPriority (1);
107 myStructure->Display();
5f6e3a07 108 UpdateDisplay();
7fd59977 109}
110
b8ddfc2f 111void V3d_CircularGrid::Erase () const
112{
113 myStructure->Erase ();
7fd59977 114}
115
b8ddfc2f 116Standard_Boolean V3d_CircularGrid::IsDisplayed () const
117{
118 return myStructure->IsDisplayed ();
7fd59977 119}
120
b8ddfc2f 121void V3d_CircularGrid::UpdateDisplay ()
122{
123 gp_Ax3 ThePlane = myViewer->PrivilegedPlane();
124
125 Standard_Real xl, yl, zl;
126 Standard_Real xdx, xdy, xdz;
127 Standard_Real ydx, ydy, ydz;
128 Standard_Real dx, dy, dz;
129 ThePlane.Location ().Coord (xl, yl, zl);
130 ThePlane.XDirection ().Coord (xdx, xdy, xdz);
131 ThePlane.YDirection ().Coord (ydx, ydy, ydz);
132 ThePlane.Direction ().Coord (dx, dy, dz);
133
134 Standard_Boolean MakeTransform = !myCurAreDefined;
135 if (!MakeTransform)
136 {
137 MakeTransform = (RotationAngle() != myCurAngle || XOrigin() != myCurXo || YOrigin() != myCurYo);
138 if (!MakeTransform)
139 {
140 Standard_Real curxl, curyl, curzl;
141 Standard_Real curxdx, curxdy, curxdz;
142 Standard_Real curydx, curydy, curydz;
143 Standard_Real curdx, curdy, curdz;
144 myCurViewPlane.Location ().Coord (curxl, curyl, curzl);
145 myCurViewPlane.XDirection ().Coord (curxdx, curxdy, curxdz);
146 myCurViewPlane.YDirection ().Coord (curydx, curydy, curydz);
147 myCurViewPlane.Direction ().Coord (curdx, curdy, curdz);
148 if (xl != curxl || yl != curyl || zl != curzl ||
149 xdx != curxdx || xdy != curxdy || xdz != curxdz ||
150 ydx != curydx || ydy != curydy || ydz != curydz ||
151 dx != curdx || dy != curdy || dz != curdz)
152 MakeTransform = Standard_True;
153 }
154 }
155
156 if (MakeTransform)
157 {
158 const Standard_Real CosAlpha = Cos (RotationAngle ());
159 const Standard_Real SinAlpha = Sin (RotationAngle ());
1f7f5a90 160
161 gp_Trsf aTrsf;
b8ddfc2f 162 // Translation
1f7f5a90 163 // Transformation of change of marker
164 aTrsf.SetValues (xdx, ydx, dx, xl,
165 xdy, ydy, dy, yl,
166 xdz, ydz, dz, zl);
b8ddfc2f 167
168 // Translation of the origin
b8ddfc2f 169 // Rotation Alpha around axis -Z
1f7f5a90 170 gp_Trsf aTrsf2;
171 aTrsf2.SetValues ( CosAlpha, SinAlpha, 0.0, -XOrigin(),
172 -SinAlpha, CosAlpha, 0.0, -YOrigin(),
173 0.0, 0.0, 1.0, 0.0);
174 aTrsf.Multiply (aTrsf2);
175 myStructure->SetTransformation (new Geom_Transformation (aTrsf));
b8ddfc2f 176
177 myCurAngle = RotationAngle ();
178 myCurXo = XOrigin (), myCurYo = YOrigin ();
179 myCurViewPlane = ThePlane;
180 }
181
475c2302 182 switch (myDrawMode)
b8ddfc2f 183 {
475c2302 184 case Aspect_GDM_Points:
b8ddfc2f 185 DefinePoints ();
186 myCurDrawMode = Aspect_GDM_Points;
187 break;
188 case Aspect_GDM_Lines:
189 DefineLines ();
190 myCurDrawMode = Aspect_GDM_Lines;
191 break;
b8ddfc2f 192 case Aspect_GDM_None:
193 myCurDrawMode = Aspect_GDM_None;
194 break;
b8ddfc2f 195 }
196 myCurAreDefined = Standard_True;
7fd59977 197}
198
b8ddfc2f 199void V3d_CircularGrid::DefineLines ()
200{
201 const Standard_Real aStep = RadiusStep ();
202 const Standard_Real aDivision = DivisionNumber ();
203 const Standard_Boolean toUpdate = !myCurAreDefined
204 || myCurDrawMode != Aspect_GDM_Lines
205 || aDivision != myCurDivi
206 || aStep != myCurStep;
5f6e3a07 207 if (!toUpdate
208 && !myToComputePrs)
b8ddfc2f 209 {
210 return;
211 }
5f6e3a07 212 else if (!myStructure->IsDisplayed())
213 {
214 myToComputePrs = Standard_True;
215 return;
216 }
b8ddfc2f 217
5f6e3a07 218 myToComputePrs = Standard_False;
b8ddfc2f 219 myGroup->Clear ();
220
b8ddfc2f 221 const Standard_Integer Division = (Standard_Integer )( (aDivision >= DIVISION ? aDivision : DIVISION));
222
223 Standard_Integer nbpnts = 2 * Division;
224 // diametres
225 Standard_Real alpha = M_PI / aDivision;
b6472664 226
227 myGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myTenthColor, Aspect_TOL_SOLID, 1.0));
51740958 228 Handle(Graphic3d_ArrayOfSegments) aPrims1 = new Graphic3d_ArrayOfSegments(2*nbpnts);
b8ddfc2f 229 const gp_Pnt p0(0., 0., -myOffSet);
230 for (Standard_Integer i=1; i<=nbpnts; i++) {
51740958 231 aPrims1->AddVertex(p0);
232 aPrims1->AddVertex(Cos(alpha*i)*myRadius, Sin(alpha*i)*myRadius, -myOffSet);
b8ddfc2f 233 }
51740958 234 myGroup->AddPrimitiveArray(aPrims1, Standard_False);
b8ddfc2f 235
236 // circles
237 nbpnts = 2 * Division + 1;
238 alpha = M_PI / Division;
239 Standard_Integer nblines = 0;
240 TColgp_SequenceOfPnt aSeqLines, aSeqTenth;
241 for (Standard_Real r=aStep; r<=myRadius; r+=aStep, nblines++) {
242 const Standard_Boolean isTenth = (Modulus(nblines, 10) == 0);
243 for (Standard_Integer i=0; i<nbpnts; i++) {
244 const gp_Pnt pt(Cos(alpha*i)*r,Sin(alpha*i)*r,-myOffSet);
245 (isTenth? aSeqTenth : aSeqLines).Append(pt);
246 }
247 }
248 if (aSeqTenth.Length())
249 {
b6472664 250 myGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (myTenthColor, Aspect_TOL_SOLID, 1.0));
b8ddfc2f 251 Standard_Integer n, np;
252 const Standard_Integer nbl = aSeqTenth.Length() / nbpnts;
51740958 253 Handle(Graphic3d_ArrayOfPolylines) aPrims2 = new Graphic3d_ArrayOfPolylines(aSeqTenth.Length(),nbl);
b8ddfc2f 254 for (np = 1, n=0; n<nbl; n++) {
51740958 255 aPrims2->AddBound(nbpnts);
b8ddfc2f 256 for (Standard_Integer i=0; i<nbpnts; i++, np++)
51740958 257 aPrims2->AddVertex(aSeqTenth(np));
b8ddfc2f 258 }
51740958 259 myGroup->AddPrimitiveArray(aPrims2, Standard_False);
b8ddfc2f 260 }
261 if (aSeqLines.Length())
262 {
b6472664 263 myGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (myColor, Aspect_TOL_SOLID, 1.0));
b8ddfc2f 264 Standard_Integer n, np;
265 const Standard_Integer nbl = aSeqLines.Length() / nbpnts;
51740958 266 Handle(Graphic3d_ArrayOfPolylines) aPrims3 = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),nbl);
b8ddfc2f 267 for (np = 1, n=0; n<nbl; n++) {
51740958 268 aPrims3->AddBound(nbpnts);
b8ddfc2f 269 for (Standard_Integer i=0; i<nbpnts; i++, np++)
51740958 270 aPrims3->AddVertex(aSeqLines(np));
b8ddfc2f 271 }
51740958 272 myGroup->AddPrimitiveArray(aPrims3, Standard_False);
b8ddfc2f 273 }
274
e36ee967 275 myGroup->SetMinMaxValues (-myRadius, -myRadius, -myOffSet, myRadius, myRadius, -myOffSet);
b8ddfc2f 276 myCurStep = aStep, myCurDivi = (Standard_Integer ) aDivision;
5f6e3a07 277
278 // update bounding box
279 myStructure->CalculateBoundBox();
280 myViewer->StructureManager()->Update (myStructure->GetZLayer());
7fd59977 281}
282
b8ddfc2f 283void V3d_CircularGrid::DefinePoints ()
284{
285 const Standard_Real aStep = RadiusStep();
286 const Standard_Real aDivision = DivisionNumber();
287 const Standard_Boolean toUpdate = !myCurAreDefined
288 || myCurDrawMode != Aspect_GDM_Points
289 || aDivision != myCurDivi
290 || aStep != myCurStep;
5f6e3a07 291 if (!toUpdate
292 && !myToComputePrs)
b8ddfc2f 293 {
294 return;
295 }
5f6e3a07 296 else if (!myStructure->IsDisplayed())
297 {
298 myToComputePrs = Standard_True;
299 return;
300 }
b8ddfc2f 301
5f6e3a07 302 myToComputePrs = Standard_False;
b8ddfc2f 303 myGroup->Clear ();
304
305 Handle(Graphic3d_AspectMarker3d) MarkerAttrib = new Graphic3d_AspectMarker3d ();
306 MarkerAttrib->SetColor (myColor);
307 MarkerAttrib->SetType (Aspect_TOM_POINT);
308 MarkerAttrib->SetScale (3.);
309
310 const Standard_Integer nbpnts = Standard_Integer (2*aDivision);
311 Standard_Real r, alpha = M_PI / aDivision;
312
313 // diameters
314 TColgp_SequenceOfPnt aSeqPnts;
315 aSeqPnts.Append(gp_Pnt(0.0, 0.0, -myOffSet));
316 for (r=aStep; r<=myRadius; r+=aStep) {
317 for (Standard_Integer i=0; i<nbpnts; i++)
318 aSeqPnts.Append(gp_Pnt(Cos(alpha*i)*r, Sin(alpha*i)*r, -myOffSet));
319 }
320 myGroup->SetGroupPrimitivesAspect (MarkerAttrib);
321 if (aSeqPnts.Length())
322 {
323 Standard_Real X,Y,Z;
324 const Standard_Integer nbv = aSeqPnts.Length();
a577aaab 325 Handle(Graphic3d_ArrayOfPoints) Cercle = new Graphic3d_ArrayOfPoints (nbv);
b8ddfc2f 326 for (Standard_Integer i=1; i<=nbv; i++)
327 {
328 aSeqPnts(i).Coord(X,Y,Z);
a577aaab 329 Cercle->AddVertex (X,Y,Z);
b8ddfc2f 330 }
a577aaab 331 myGroup->AddPrimitiveArray (Cercle, Standard_False);
b8ddfc2f 332 }
e36ee967 333 myGroup->SetMinMaxValues (-myRadius, -myRadius, -myOffSet, myRadius, myRadius, -myOffSet);
b8ddfc2f 334
335 myCurStep = aStep, myCurDivi = (Standard_Integer ) aDivision;
5f6e3a07 336
337 // update bounding box
338 myStructure->CalculateBoundBox();
339 myViewer->StructureManager()->Update (myStructure->GetZLayer());
7fd59977 340}
341
b8ddfc2f 342void V3d_CircularGrid::GraphicValues (Standard_Real& theRadius, Standard_Real& theOffSet) const
343{
344 theRadius = myRadius;
345 theOffSet = myOffSet;
7fd59977 346}
347
b8ddfc2f 348void V3d_CircularGrid::SetGraphicValues (const Standard_Real theRadius, const Standard_Real theOffSet)
349{
350 if (! myCurAreDefined) {
351 myRadius = theRadius;
352 myOffSet = theOffSet;
353 }
354 if (myRadius != theRadius) {
355 myRadius = theRadius;
356 myCurAreDefined = Standard_False;
357 }
358 if (myOffSet != theOffSet) {
359 myOffSet = theOffSet;
360 myCurAreDefined = Standard_False;
361 }
362 if( !myCurAreDefined ) UpdateDisplay();
7fd59977 363}