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