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 |
29 | IMPLEMENT_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. |
35 | class V3d_CircularGrid::CircularGridStructure : public Graphic3d_Structure |
36 | { |
37 | public: |
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 | |
51 | private: |
52 | V3d_CircularGrid* myGrid; |
53 | }; |
54 | |
7fd59977 |
55 | /*----------------------------------------------------------------------*/ |
56 | |
b8ddfc2f |
57 | V3d_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 |
76 | V3d_CircularGrid::~V3d_CircularGrid() |
77 | { |
78 | myGroup.Nullify(); |
79 | if (!myStructure.IsNull()) |
80 | { |
81 | myStructure->Erase(); |
82 | } |
83 | } |
84 | |
b8ddfc2f |
85 | void 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 |
95 | void V3d_CircularGrid::Display () |
96 | { |
a1954302 |
97 | myStructure->SetDisplayPriority (1); |
98 | myStructure->Display(); |
5f6e3a07 |
99 | UpdateDisplay(); |
7fd59977 |
100 | } |
101 | |
b8ddfc2f |
102 | void V3d_CircularGrid::Erase () const |
103 | { |
104 | myStructure->Erase (); |
7fd59977 |
105 | } |
106 | |
b8ddfc2f |
107 | Standard_Boolean V3d_CircularGrid::IsDisplayed () const |
108 | { |
109 | return myStructure->IsDisplayed (); |
7fd59977 |
110 | } |
111 | |
b8ddfc2f |
112 | void 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 |
190 | void 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 |
274 | void 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 |
333 | void V3d_CircularGrid::GraphicValues (Standard_Real& theRadius, Standard_Real& theOffSet) const |
334 | { |
335 | theRadius = myRadius; |
336 | theOffSet = myOffSet; |
7fd59977 |
337 | } |
338 | |
b8ddfc2f |
339 | void 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 | } |