Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-09-20 |
2 | // Created by: Sergey ZERCHANINOV | |
a174a3c5 | 3 | // Copyright (c) 2011-2013 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
b311480e | 15 | |
5f8b738e | 16 | #include <OpenGl_GlCore11.hxx> |
7fd59977 | 17 | |
c827ea3a | 18 | #include <OpenGl_GraduatedTrihedron.hxx> |
a79f67f8 | 19 | |
20 | #include <Graphic3d_ArrayOfPolylines.hxx> | |
21 | #include <Graphic3d_ArrayOfSegments.hxx> | |
c04c30b3 | 22 | #include <Graphic3d_GraphicDriver.hxx> |
825aa485 | 23 | #include <Graphic3d_TransformPers.hxx> |
24 | #include <Graphic3d_TransformUtils.hxx> | |
a79f67f8 | 25 | #include <gp_Ax3.hxx> |
2166f0fa SK |
26 | #include <OpenGl_Workspace.hxx> |
27 | #include <OpenGl_View.hxx> | |
a79f67f8 | 28 | #include <Precision.hxx> |
7fd59977 | 29 | |
c04c30b3 | 30 | #ifndef _WIN32 |
31 | #include <string.h> | |
32 | #endif | |
33 | ||
536d98e2 | 34 | namespace |
35 | { | |
36 | static const OpenGl_TextParam THE_LABEL_PARAMS = | |
37 | { | |
38 | 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM | |
39 | }; | |
40 | } | |
41 | ||
a79f67f8 | 42 | // ======================================================================= |
43 | // function : Constructor | |
44 | // purpose : | |
45 | // ======================================================================= | |
536d98e2 | 46 | OpenGl_GraduatedTrihedron::OpenGl_GraduatedTrihedron() |
a79f67f8 | 47 | : myMin (0.0f, 0.0f, 0.0f), |
c357e426 | 48 | myMax (100.0f, 100.0f, 100.0f), |
49 | myIsInitialized (Standard_False) | |
536d98e2 | 50 | { |
51 | // | |
52 | } | |
53 | ||
54 | // ======================================================================= | |
55 | // function : SetValues | |
56 | // purpose : | |
57 | // ======================================================================= | |
c357e426 | 58 | void OpenGl_GraduatedTrihedron::SetValues (const Graphic3d_GraduatedTrihedron& theData) |
a174a3c5 | 59 | { |
c357e426 | 60 | myData = theData; |
61 | myIsInitialized = Standard_False; | |
7fd59977 | 62 | } |
63 | ||
a79f67f8 | 64 | // ======================================================================= |
65 | // function : Destructor | |
66 | // purpose : | |
67 | // ======================================================================= | |
68 | OpenGl_GraduatedTrihedron::~OpenGl_GraduatedTrihedron() | |
7fd59977 | 69 | { |
a79f67f8 | 70 | // |
7fd59977 | 71 | } |
72 | ||
a174a3c5 | 73 | // ======================================================================= |
74 | // function : Release | |
75 | // purpose : | |
76 | // ======================================================================= | |
10b9c7df | 77 | void OpenGl_GraduatedTrihedron::Release (OpenGl_Context* theCtx) |
7fd59977 | 78 | { |
a79f67f8 | 79 | myAxes[0].Release (theCtx); |
80 | myAxes[1].Release (theCtx); | |
81 | myAxes[2].Release (theCtx); | |
a174a3c5 | 82 | myLabelValues.Release (theCtx); |
7fd59977 | 83 | } |
84 | ||
c357e426 | 85 | // ======================================================================= |
86 | // function : initResources | |
87 | // purpose : | |
88 | // ======================================================================= | |
89 | void OpenGl_GraduatedTrihedron::initGlResources (const Handle(OpenGl_Context)& theCtx) const | |
90 | { | |
91 | myAxes[0].Release (theCtx.operator->()); | |
92 | myAxes[1].Release (theCtx.operator->()); | |
93 | myAxes[2].Release (theCtx.operator->()); | |
94 | myLabelValues.Release (theCtx.operator->()); | |
95 | ||
96 | // Initialize text label parameters for x, y, and z axes | |
97 | myAxes[0] = Axis (myData.XAxisAspect(), OpenGl_Vec3 (1.0f, 0.0f, 0.0f)); | |
98 | myAxes[1] = Axis (myData.YAxisAspect(), OpenGl_Vec3 (0.0f, 1.0f, 0.0f)); | |
99 | myAxes[2] = Axis (myData.ZAxisAspect(), OpenGl_Vec3 (0.0f, 0.0f, 1.0f)); | |
100 | ||
101 | // Initialize constant primitives: text, arrows. | |
102 | myAxes[0].InitArrow (theCtx, myData.ArrowsLength(), OpenGl_Vec3 (0.0f, 0.0f, 1.0f)); | |
103 | myAxes[1].InitArrow (theCtx, myData.ArrowsLength(), OpenGl_Vec3 (0.0f, 0.0f, 1.0f)); | |
104 | myAxes[2].InitArrow (theCtx, myData.ArrowsLength(), OpenGl_Vec3 (1.0f, 0.0f, 0.0f)); | |
105 | for (Standard_Integer anIt = 0; anIt < 3; ++anIt) | |
106 | { | |
107 | myAxes[anIt].Label.SetFontSize (theCtx, myData.NamesSize()); | |
108 | } | |
109 | ||
110 | myLabelValues.SetFontSize (theCtx, myData.ValuesSize()); | |
111 | ||
b6472664 | 112 | myAspectLabels.Aspect()->SetTextFontAspect (myData.NamesFontAspect()); |
bf5f0ca2 | 113 | myAspectLabels.Aspect()->SetTextFont (!myData.NamesFont().IsEmpty() |
114 | ? new TCollection_HAsciiString (myData.NamesFont()) | |
115 | : Handle(TCollection_HAsciiString )()); | |
c357e426 | 116 | |
b6472664 | 117 | myAspectValues.Aspect()->SetTextFontAspect (myData.ValuesFontAspect()); |
bf5f0ca2 | 118 | myAspectValues.Aspect()->SetTextFont (!myData.ValuesFont().IsEmpty() |
119 | ? new TCollection_HAsciiString (myData.ValuesFont()) | |
120 | : Handle(TCollection_HAsciiString )()); | |
c357e426 | 121 | |
122 | // Grid aspect | |
b6472664 | 123 | myGridLineAspect.Aspect()->SetColor (myData.GridColor()); |
c357e426 | 124 | } |
125 | ||
a79f67f8 | 126 | // ======================================================================= |
127 | // method : getNormal | |
128 | // purpose : Normal of the view (not normalized!) | |
129 | // ======================================================================= | |
130 | Standard_ShortReal OpenGl_GraduatedTrihedron::getNormal (const Handle(OpenGl_Context)& theContext, | |
131 | OpenGl_Vec3& theNormal) const | |
7fd59977 | 132 | { |
3bffef55 | 133 | const Standard_Integer* aViewport = theContext->Viewport(); |
a79f67f8 | 134 | |
135 | OpenGl_Mat4 aModelMatrix; | |
136 | OpenGl_Mat4 aProjMatrix; | |
137 | aModelMatrix.Convert (theContext->ModelWorldState.Current() * theContext->WorldViewState.Current()); | |
138 | aProjMatrix .Convert (theContext->ProjectionState.Current()); | |
139 | ||
140 | OpenGl_Vec3 aPoint1, aPoint2, aPoint3; | |
825aa485 | 141 | Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) aViewport[0], |
142 | (Standard_ShortReal) aViewport[1], | |
143 | 0.0f, | |
144 | aModelMatrix, aProjMatrix, aViewport, | |
145 | aPoint1.x(), aPoint1.y(), aPoint1.z()); | |
146 | ||
147 | Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) (aViewport[0] + aViewport[2]), | |
148 | (Standard_ShortReal) aViewport[1], | |
149 | 0.0f, | |
150 | aModelMatrix, aProjMatrix, aViewport, | |
151 | aPoint2.x(), aPoint2.y(), aPoint2.z()); | |
152 | ||
153 | Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) aViewport[0], | |
154 | (Standard_ShortReal) (aViewport[1] + aViewport[3]), | |
155 | 0.0f, | |
156 | aModelMatrix, aProjMatrix, aViewport, | |
157 | aPoint3.x(), aPoint3.y(), aPoint3.z()); | |
a79f67f8 | 158 | |
159 | const OpenGl_Vec3 aD1 = aPoint3 - aPoint1; | |
160 | const OpenGl_Vec3 aD2 = aPoint2 - aPoint1; | |
161 | theNormal = OpenGl_Vec3::Cross (aD1, aD2); | |
162 | ||
163 | // Distance corresponding to 1 pixel | |
164 | return aD2.Modulus() / (float) aViewport[2]; | |
a174a3c5 | 165 | } |
166 | ||
a79f67f8 | 167 | // ======================================================================= |
168 | // method : getDistancetoCorner | |
169 | // purpose : | |
170 | // ======================================================================= | |
171 | Standard_ShortReal OpenGl_GraduatedTrihedron::getDistanceToCorner (const OpenGl_Vec3& theNormal, | |
172 | const OpenGl_Vec3& theCenter, | |
173 | const Standard_ShortReal theX, | |
174 | const Standard_ShortReal theY, | |
175 | const Standard_ShortReal theZ) const | |
a174a3c5 | 176 | { |
a79f67f8 | 177 | return theNormal.x() * (theX - theCenter.x()) |
178 | + theNormal.y() * (theY - theCenter.y()) | |
179 | + theNormal.z() * (theZ - theCenter.z()); | |
2166f0fa | 180 | } |
13a22457 | 181 | |
a79f67f8 | 182 | // ======================================================================= |
183 | // method : getGridAxes | |
184 | // purpose : | |
185 | // ======================================================================= | |
186 | Standard_ExtCharacter OpenGl_GraduatedTrihedron::getGridAxes (const Standard_ShortReal theCorners[8], | |
187 | GridAxes& theGridAxes) const | |
2166f0fa | 188 | { |
a79f67f8 | 189 | // Find the farest corner |
190 | Standard_Byte aMaxIndex = 0; | |
191 | Standard_ShortReal aMax = theCorners[aMaxIndex] > 0.0f ? theCorners[aMaxIndex] : 0.0f; | |
192 | ||
193 | for (Standard_Byte anIt = 0; anIt < 8; ++anIt) | |
13a22457 | 194 | { |
a79f67f8 | 195 | if (theCorners[anIt] > aMax) |
13a22457 | 196 | { |
a79f67f8 | 197 | aMax = theCorners[anIt]; |
198 | aMaxIndex = anIt; | |
13a22457 S |
199 | } |
200 | } | |
201 | ||
a79f67f8 | 202 | switch (aMaxIndex) |
13a22457 | 203 | { |
a79f67f8 | 204 | case 0: // (0,0,0) |
13a22457 | 205 | { |
a79f67f8 | 206 | theGridAxes.Origin = OpenGl_Vec3 (myMin.x(), myMin.y(), myMin.z()); |
207 | theGridAxes.Axes[0] = OpenGl_Vec3 (1.0f, 0.0f, 0.0f); | |
208 | theGridAxes.Axes[1] = OpenGl_Vec3 (0.0f, 1.0f, 0.0f); | |
209 | theGridAxes.Axes[2] = OpenGl_Vec3 (0.0f, 0.0f, 1.0f); | |
210 | ||
211 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMax.z()); | |
212 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); | |
213 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); | |
214 | ||
215 | return OOZ_XOZ | OYO_XYO | | |
216 | XOO_XYO | OOZ_OYZ | | |
217 | XOO_XOZ | OYO_OYZ; | |
13a22457 | 218 | } |
a79f67f8 | 219 | case 1: // (0,0,1) |
13a22457 | 220 | { |
a79f67f8 | 221 | theGridAxes.Origin = OpenGl_Vec3 (myMin.x(), myMin.y(), myMax.z()); |
222 | theGridAxes.Axes[0] = OpenGl_Vec3 (1.0f, 0.0f, 0.0f); | |
223 | theGridAxes.Axes[1] = OpenGl_Vec3 (0.0f, 1.0f, 0.0f); | |
224 | theGridAxes.Axes[2] = OpenGl_Vec3 (0.0f, 0.0f, -1.0f); | |
225 | ||
226 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMin.z()); | |
227 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMin.z()); | |
228 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMax.z()); | |
229 | ||
230 | return OOZ_XOZ | OYZ_XYZ | | |
231 | OOZ_OYZ | XOZ_XYZ | | |
232 | XOO_XOZ | OYO_OYZ; | |
13a22457 | 233 | } |
a79f67f8 | 234 | case 2: // (0,1,0) |
13a22457 | 235 | { |
a79f67f8 | 236 | theGridAxes.Origin = OpenGl_Vec3 (myMin.x(), myMax.y(), myMin.z()); |
237 | theGridAxes.Axes[0] = OpenGl_Vec3 (1.0f, 0.0f, 0.0f); | |
238 | theGridAxes.Axes[1] = OpenGl_Vec3 (0.0f, -1.0f, 0.0f); | |
239 | theGridAxes.Axes[2] = OpenGl_Vec3 (0.0f, 0.0f, 1.0f); | |
240 | ||
241 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMin.z()); | |
242 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMax.x(), myMax.y(), myMin.z()); | |
243 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMax.x(), myMax.y(), myMin.z()); | |
244 | ||
245 | return OYO_XYO | OYZ_XYZ | | |
246 | XOO_XYO | OOZ_OYZ | | |
247 | XYO_XYZ | OYO_OYZ; | |
13a22457 | 248 | } |
a79f67f8 | 249 | case 3: // (0,1,1) |
13a22457 | 250 | { |
a79f67f8 | 251 | theGridAxes.Origin = OpenGl_Vec3 (myMin.x(), myMax.y(), myMax.z()); |
252 | theGridAxes.Axes[0] = OpenGl_Vec3 (1.0f, 0.0f, 0.0f); | |
253 | theGridAxes.Axes[1] = OpenGl_Vec3 (0.0f, -1.0f, 0.0f); | |
254 | theGridAxes.Axes[2] = OpenGl_Vec3 (0.0f, 0.0f, -1.0f); | |
255 | ||
256 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMax.z()); | |
257 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMin.x(), myMax.y(), myMin.z()); | |
258 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMax.z()); | |
259 | ||
260 | return OOZ_XOZ | OYZ_XYZ | OYO_XYO | | |
261 | OOZ_OYZ | XOZ_XYZ | | |
262 | OYO_OYZ | XYO_XYZ; | |
13a22457 | 263 | } |
a79f67f8 | 264 | case 4: // (1,0,0) |
13a22457 | 265 | { |
a79f67f8 | 266 | theGridAxes.Origin = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); |
267 | theGridAxes.Axes[0] = OpenGl_Vec3 (-1, 0, 0); | |
268 | theGridAxes.Axes[1] = OpenGl_Vec3 (0, 1, 0); | |
269 | theGridAxes.Axes[2] = OpenGl_Vec3 (0, 0, 1); | |
270 | ||
271 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMax.z()); | |
272 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMin.z()); | |
273 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMin.z()); | |
274 | ||
275 | return OOZ_XOZ | OYO_XYO | | |
276 | XOO_XYO | XOZ_XYZ | | |
277 | XOO_XOZ | XYO_XYZ; | |
13a22457 | 278 | } |
a79f67f8 | 279 | case 5: // (1,0,1) |
13a22457 | 280 | { |
a79f67f8 | 281 | theGridAxes.Origin = OpenGl_Vec3 (myMax.x(), myMin.y(), myMax.z()); |
282 | theGridAxes.Axes[0] = OpenGl_Vec3 (-1, 0, 0); | |
283 | theGridAxes.Axes[1] = OpenGl_Vec3 (0, 1, 0); | |
284 | theGridAxes.Axes[2] = OpenGl_Vec3 (0, 0, -1); | |
285 | ||
286 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); | |
287 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); | |
288 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMin.x(), myMin.y(), myMax.z()); | |
289 | ||
290 | return OOZ_XOZ | OYZ_XYZ | | |
291 | XOO_XYO | XOZ_XYZ | OOZ_OYZ | | |
292 | XOO_XOZ | XYO_XYZ; | |
13a22457 | 293 | } |
a79f67f8 | 294 | case 6: // (1,1,0) |
13a22457 | 295 | { |
a79f67f8 | 296 | theGridAxes.Origin = OpenGl_Vec3 (myMax.x(), myMax.y(), myMin.z()); |
297 | theGridAxes.Axes[0] = OpenGl_Vec3 (-1, 0, 0); | |
298 | theGridAxes.Axes[1] = OpenGl_Vec3 (0, -1, 0); | |
299 | theGridAxes.Axes[2] = OpenGl_Vec3 (0, 0, 1); | |
300 | ||
301 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); | |
302 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMin.x(), myMax.y(), myMin.z()); | |
303 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMin.z()); | |
304 | ||
305 | return OYO_XYO | OYZ_XYZ | | |
306 | XOO_XYO | XOZ_XYZ | | |
307 | XOO_XOZ | XYO_XYZ | OYO_OYZ; | |
13a22457 | 308 | } |
a79f67f8 | 309 | case 7: // (1,1,1) |
310 | default: | |
13a22457 | 311 | { |
a79f67f8 | 312 | theGridAxes.Origin = OpenGl_Vec3 (myMax.x(), myMax.y(), myMax.z()); |
313 | theGridAxes.Axes[0] = OpenGl_Vec3 (-1, 0, 0); | |
314 | theGridAxes.Axes[1] = OpenGl_Vec3 (0, -1, 0); | |
315 | theGridAxes.Axes[2] = OpenGl_Vec3 (0, 0, -1); | |
316 | ||
317 | theGridAxes.Ticks[0] = OpenGl_Vec3 (myMax.x(), myMax.y(), myMin.z()); | |
318 | theGridAxes.Ticks[1] = OpenGl_Vec3 (myMax.x(), myMax.y(), myMin.z()); | |
319 | theGridAxes.Ticks[2] = OpenGl_Vec3 (myMax.x(), myMin.y(), myMax.z()); | |
320 | ||
321 | return OYO_XYO | OYZ_XYZ | OOZ_XOZ | | |
322 | XOO_XYO | XOZ_XYZ | OOZ_OYZ | | |
323 | XOO_XOZ | XYO_XYZ | OYO_OYZ; | |
13a22457 | 324 | } |
a79f67f8 | 325 | } |
326 | } | |
327 | ||
328 | // ======================================================================= | |
329 | // function : renderLine | |
330 | // purpose : | |
331 | // ======================================================================= | |
536d98e2 | 332 | void OpenGl_GraduatedTrihedron::renderLine (const OpenGl_PrimitiveArray& theLine, |
a79f67f8 | 333 | const Handle(OpenGl_Workspace)& theWorkspace, |
334 | const OpenGl_Mat4& theMat, | |
335 | const Standard_ShortReal theXt, | |
336 | const Standard_ShortReal theYt, | |
337 | const Standard_ShortReal theZt) const | |
338 | { | |
339 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); | |
340 | OpenGl_Mat4 aMat (theMat); | |
825aa485 | 341 | Graphic3d_TransformUtils::Translate (aMat, theXt, theYt, theZt); |
a79f67f8 | 342 | aContext->WorldViewState.SetCurrent (aMat); |
343 | aContext->ApplyWorldViewMatrix(); | |
536d98e2 | 344 | theLine.Render (theWorkspace); |
a79f67f8 | 345 | } |
346 | ||
347 | // ======================================================================= | |
348 | // function : renderGridPlane | |
349 | // purpose : | |
350 | // ======================================================================= | |
351 | void OpenGl_GraduatedTrihedron::renderGridPlane (const Handle(OpenGl_Workspace)& theWorkspace, | |
352 | const Standard_Integer& theIndex, | |
353 | const GridAxes& theGridAxes, | |
354 | OpenGl_Mat4& theMat) const | |
355 | { | |
356 | const Graphic3d_AxisAspect& aCurAspect = myData.AxisAspect (theIndex); | |
536d98e2 | 357 | if (aCurAspect.TickmarksNumber() <= 0) |
a79f67f8 | 358 | { |
359 | return; | |
360 | } | |
361 | ||
362 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); | |
363 | ||
364 | Standard_ShortReal aStep = theGridAxes.Axes[theIndex].GetData()[theIndex] | |
536d98e2 | 365 | * (myMax.GetData()[theIndex] - myMin.GetData()[theIndex]) / aCurAspect.TickmarksNumber(); |
13a22457 | 366 | |
a79f67f8 | 367 | // NOTE: |
536d98e2 | 368 | // Get two other axes directions and draw lines Axis.TickmarksNumber times. |
a79f67f8 | 369 | // Combining together from three axes, these lines will make a grid. |
370 | for (Standard_Integer anIter = 1; anIter <= 2; ++anIter) | |
371 | { | |
372 | OpenGl_Mat4 aMat (theMat); | |
373 | const Standard_Integer anIndex = (theIndex + anIter) % 3; | |
374 | const Axis& anAxis = myAxes[anIndex]; | |
375 | OpenGl_Vec3 aStart (theGridAxes.Origin); | |
376 | if (theGridAxes.Axes[anIndex].GetData()[anIndex] < 0.0) | |
13a22457 | 377 | { |
a79f67f8 | 378 | aStart.ChangeData()[anIndex] = myMin.GetData()[anIndex]; |
13a22457 | 379 | } |
a79f67f8 | 380 | |
825aa485 | 381 | Graphic3d_TransformUtils::Translate (aMat, aStart.x(), aStart.y(), aStart.z()); |
a79f67f8 | 382 | aContext->WorldViewState.SetCurrent (aMat); |
383 | aContext->ApplyWorldViewMatrix(); | |
384 | ||
385 | const OpenGl_Vec3 aStepVec (myAxes[theIndex].Direction * aStep); | |
536d98e2 | 386 | for (Standard_Integer anIt = myData.ToDrawAxes() ? 1 : 0; anIt < aCurAspect.TickmarksNumber(); ++anIt) |
13a22457 | 387 | { |
825aa485 | 388 | Graphic3d_TransformUtils::Translate (aMat, aStepVec.x(), aStepVec.y(), aStepVec.z()); |
a79f67f8 | 389 | aContext->WorldViewState.SetCurrent (aMat); |
390 | aContext->ApplyWorldViewMatrix(); | |
536d98e2 | 391 | anAxis.Line.Render (theWorkspace); |
13a22457 | 392 | } |
a79f67f8 | 393 | } |
394 | } | |
395 | ||
396 | // ======================================================================= | |
397 | // function : renderAxis | |
398 | // purpose : | |
399 | // ======================================================================= | |
400 | void OpenGl_GraduatedTrihedron::renderAxis (const Handle(OpenGl_Workspace)& theWorkspace, | |
401 | const Standard_Integer& theIndex, | |
402 | const OpenGl_Mat4& theMat) const | |
403 | { | |
404 | const Axis& anAxis = myAxes[theIndex]; | |
405 | ||
bf5f0ca2 | 406 | theWorkspace->SetAspects (&anAxis.LineAspect); |
a79f67f8 | 407 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); |
408 | ||
409 | // Reset transformations | |
410 | aContext->WorldViewState.SetCurrent (theMat); | |
411 | aContext->ApplyWorldViewMatrix(); | |
412 | ||
413 | // Render arrow | |
a79f67f8 | 414 | OpenGl_Vec3 anArrowVec = myMin + anAxis.Direction * (myMax - myMin); |
a79f67f8 | 415 | |
778cd667 | 416 | Graphic3d_TransformPers aTransMode (Graphic3d_TMF_ZoomPers, gp_Pnt (Standard_Real(anArrowVec.x()), |
417 | Standard_Real(anArrowVec.y()), | |
418 | Standard_Real(anArrowVec.z()))); | |
825aa485 | 419 | const OpenGl_Mat4& aProjection = aContext->ProjectionState.Current(); |
420 | const OpenGl_Mat4& aWorldView = aContext->WorldViewState.Current(); | |
421 | const Standard_Integer aWidth = theWorkspace->Width(); | |
422 | const Standard_Integer aHeight = theWorkspace->Height(); | |
a79f67f8 | 423 | |
a79f67f8 | 424 | // Take into account Transform Persistence |
3fe9ce0e | 425 | aContext->ModelWorldState.SetCurrent (aTransMode.Compute (theWorkspace->View()->Camera(), aProjection, aWorldView, aWidth, aHeight)); |
a79f67f8 | 426 | aContext->ApplyModelViewMatrix(); |
427 | ||
825aa485 | 428 | anAxis.Arrow.Render (theWorkspace); |
429 | ||
a79f67f8 | 430 | // Get current Model-View and Projection states |
431 | OpenGl_Mat4 aModelMat; | |
432 | OpenGl_Mat4 aProjMat; | |
825aa485 | 433 | aModelMat.Convert (aContext->WorldViewState.Current() * aContext->ModelWorldState.Current()); |
a79f67f8 | 434 | aProjMat .Convert (aContext->ProjectionState.Current()); |
435 | ||
825aa485 | 436 | // Get the window's (fixed) coordinates for before matrices modifications |
536d98e2 | 437 | OpenGl_Vec3 aEndPoint = -anAxis.Direction * myData.ArrowsLength(); |
a79f67f8 | 438 | OpenGl_Vec3 aWinPoint; |
825aa485 | 439 | Graphic3d_TransformUtils::Project<Standard_ShortReal> (aEndPoint.x(), aEndPoint.y(), aEndPoint.z(), |
3bffef55 | 440 | aModelMat, aProjMat, aContext->Viewport(), |
825aa485 | 441 | aWinPoint.x(), aWinPoint.y(), aWinPoint.z()); |
a79f67f8 | 442 | |
825aa485 | 443 | aContext->ModelWorldState.SetIdentity(); |
444 | aModelMat.Convert (aContext->WorldViewState.Current()); | |
a79f67f8 | 445 | aProjMat .Convert (aContext->ProjectionState.Current()); |
446 | ||
447 | // Get start point of zoom persistent arrow | |
448 | OpenGl_Vec3 anArrowStart; | |
825aa485 | 449 | Graphic3d_TransformUtils::UnProject<Standard_ShortReal> (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(), |
3bffef55 | 450 | aModelMat, aProjMat, aContext->Viewport(), |
825aa485 | 451 | anArrowStart.x(), anArrowStart.y(), anArrowStart.z()); |
a79f67f8 | 452 | // Render axis line |
a79f67f8 | 453 | aModelMat = theMat; |
825aa485 | 454 | Graphic3d_TransformUtils::Translate (aModelMat, myMin.x(), myMin.y(), myMin.z()); |
a79f67f8 | 455 | |
456 | Standard_ShortReal aScaleFactor = ( (anArrowStart - myMin)*anAxis.Direction ).Modulus() | |
457 | / (anAxis.Direction * (myMax - myMin) ).Modulus(); | |
458 | OpenGl_Vec3 aScaleAxes = anAxis.Direction * aScaleFactor; | |
825aa485 | 459 | Graphic3d_TransformUtils::Scale (aModelMat, aScaleAxes.x(), aScaleAxes.y(), aScaleAxes.z()); |
a79f67f8 | 460 | |
461 | aContext->WorldViewState.SetCurrent (aModelMat); | |
462 | aContext->ApplyWorldViewMatrix(); | |
536d98e2 | 463 | anAxis.Line.Render (theWorkspace); |
a79f67f8 | 464 | } |
465 | ||
466 | // ======================================================================= | |
467 | // function : renderTickmarkTextLabels | |
468 | // purpose : | |
469 | // ======================================================================= | |
470 | void OpenGl_GraduatedTrihedron::renderTickmarkLabels (const Handle(OpenGl_Workspace)& theWorkspace, | |
471 | const OpenGl_Mat4& theMat, | |
472 | const Standard_Integer theIndex, | |
473 | const GridAxes& theGridAxes, | |
474 | const Standard_ShortReal theDpix) const | |
475 | { | |
476 | const Graphic3d_AxisAspect& aCurAspect = myData.AxisAspect (theIndex); | |
477 | if (!aCurAspect.ToDrawName() && !aCurAspect.ToDrawValues()) | |
478 | { | |
479 | return; | |
480 | } | |
481 | ||
482 | Standard_Character aTextValue[128]; | |
483 | const Axis& anAxis = myAxes[theIndex]; | |
484 | const OpenGl_Vec3 aSizeVec (myMax - myMin); | |
485 | Standard_ShortReal aStep = theGridAxes.Axes[theIndex].GetData()[theIndex] | |
536d98e2 | 486 | * (myMax.GetData()[theIndex] - myMin.GetData()[theIndex]) / aCurAspect.TickmarksNumber(); |
a79f67f8 | 487 | |
488 | OpenGl_Vec3 aDir = (theGridAxes.Ticks[theIndex] - theGridAxes.Origin).Normalized(); | |
489 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); | |
490 | ||
536d98e2 | 491 | if (aCurAspect.ToDrawTickmarks() && aCurAspect.TickmarksNumber() > 0) |
a79f67f8 | 492 | { |
bf5f0ca2 | 493 | theWorkspace->SetAspects (&myGridLineAspect); |
a79f67f8 | 494 | |
495 | OpenGl_Mat4 aModelMat (theMat); | |
496 | ||
536d98e2 | 497 | anAxis.InitTickmark (aContext, aDir * (Standard_ShortReal) aCurAspect.TickmarksLength() * theDpix); |
825aa485 | 498 | Graphic3d_TransformUtils::Translate (aModelMat, theGridAxes.Ticks[theIndex].x(), |
499 | theGridAxes.Ticks[theIndex].y(), | |
500 | theGridAxes.Ticks[theIndex].z()); | |
a79f67f8 | 501 | aContext->WorldViewState.SetCurrent (aModelMat); |
502 | aContext->ApplyWorldViewMatrix(); | |
503 | OpenGl_Vec3 aStepVec = anAxis.Direction * aStep; | |
536d98e2 | 504 | for (Standard_Integer anIter = 0; anIter <= aCurAspect.TickmarksNumber(); ++anIter) |
13a22457 | 505 | { |
536d98e2 | 506 | anAxis.Tickmark.Render (theWorkspace); |
825aa485 | 507 | Graphic3d_TransformUtils::Translate (aModelMat, aStepVec.x(), aStepVec.y(), aStepVec.z()); |
a79f67f8 | 508 | aContext->WorldViewState.SetCurrent (aModelMat); |
509 | aContext->ApplyWorldViewMatrix(); | |
13a22457 S |
510 | } |
511 | } | |
512 | ||
a79f67f8 | 513 | // Restore matrix |
514 | aContext->WorldViewState.SetCurrent (theMat); | |
515 | aContext->ApplyWorldViewMatrix(); | |
516 | ||
517 | if (aCurAspect.ToDrawName()) | |
13a22457 | 518 | { |
536d98e2 | 519 | Standard_Real anOffset = aCurAspect.NameOffset() + aCurAspect.TickmarksLength(); |
13a22457 | 520 | |
a79f67f8 | 521 | OpenGl_Vec3 aMiddle (theGridAxes.Ticks[theIndex] + aSizeVec * theGridAxes.Axes[theIndex] * 0.5f + aDir * (Standard_ShortReal)(theDpix * anOffset)); |
13a22457 | 522 | |
b6472664 | 523 | myAspectLabels.Aspect()->SetColor (anAxis.NameColor); |
bf5f0ca2 | 524 | theWorkspace->SetAspects (&myAspectLabels); |
a79f67f8 | 525 | anAxis.Label.SetPosition (aMiddle); |
526 | anAxis.Label.Render (theWorkspace); | |
13a22457 S |
527 | } |
528 | ||
536d98e2 | 529 | if (aCurAspect.ToDrawValues() && aCurAspect.TickmarksNumber() > 0) |
13a22457 | 530 | { |
b6472664 | 531 | myAspectValues.Aspect()->SetColor (anAxis.LineAspect.Aspect()->Color()); |
bf5f0ca2 | 532 | theWorkspace->SetAspects (&myAspectValues); |
536d98e2 | 533 | Standard_Real anOffset = aCurAspect.ValuesOffset() + aCurAspect.TickmarksLength(); |
a79f67f8 | 534 | |
536d98e2 | 535 | for (Standard_Integer anIt = 0; anIt <= aCurAspect.TickmarksNumber(); ++anIt) |
7fd59977 | 536 | { |
a79f67f8 | 537 | sprintf (aTextValue, "%g", theGridAxes.Ticks[theIndex].GetData()[theIndex] + anIt * aStep); |
538 | OpenGl_Vec3 aPos (theGridAxes.Ticks[theIndex] + anAxis.Direction* (Standard_ShortReal) (anIt * aStep) + aDir * (Standard_ShortReal) (theDpix * anOffset)); | |
539 | myLabelValues.Init (theWorkspace->GetGlContext(), aTextValue, aPos); | |
540 | myLabelValues.Render (theWorkspace); | |
7fd59977 | 541 | } |
a79f67f8 | 542 | } |
543 | } | |
544 | ||
545 | // ======================================================================= | |
546 | // function : Render | |
547 | // purpose : call_graduatedtrihedron_redraw | |
548 | // ======================================================================= | |
549 | void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const | |
550 | { | |
551 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); | |
c357e426 | 552 | if (!myIsInitialized) |
553 | { | |
554 | initGlResources (theWorkspace->GetGlContext()); | |
555 | myIsInitialized = Standard_True; | |
556 | } | |
a79f67f8 | 557 | |
558 | // Update boundary box | |
559 | OpenGl_Vec3 anOldMin = myMin; | |
560 | OpenGl_Vec3 anOldMax = myMax; | |
561 | ||
562 | if (myData.CubicAxesCallback) | |
563 | { | |
c357e426 | 564 | myData.CubicAxesCallback (myData.PtrView); |
536d98e2 | 565 | if (!myAxes[0].Line.IsInitialized() |
566 | || !myAxes[1].Line.IsInitialized() | |
567 | || !myAxes[2].Line.IsInitialized() | |
568 | || OpenGl_Vec3 (anOldMin - myMin).Modulus() > Precision::Confusion() | |
569 | || OpenGl_Vec3 (anOldMax - myMax).Modulus() > Precision::Confusion()) | |
13a22457 | 570 | { |
536d98e2 | 571 | myAxes[0].InitLine (aContext, OpenGl_Vec3 (myMax.x() - myMin.x(), 0.0f, 0.0f)); |
572 | myAxes[1].InitLine (aContext, OpenGl_Vec3 (0.0f, myMax.y() - myMin.y(), 0.0f)); | |
573 | myAxes[2].InitLine (aContext, OpenGl_Vec3 (0.0f, 0.0f, myMax.z() - myMin.z())); | |
13a22457 | 574 | } |
a79f67f8 | 575 | } |
576 | ||
577 | // Find the farest point of bounding box | |
578 | ||
579 | // Get normal of the view out of user and distance corresponding to 1 pixel | |
580 | OpenGl_Vec3 aNormal; | |
581 | Standard_ShortReal aDpix = getNormal (aContext, aNormal); | |
582 | aNormal.Normalize(); | |
583 | ||
584 | // Get central point of bounding box | |
585 | OpenGl_Vec3 aCenter; | |
586 | aCenter = (myMin + myMax) * 0.5f; | |
587 | ||
588 | // Check distance to corners of bounding box along the normal | |
589 | Standard_ShortReal aCorners[8]; | |
590 | aCorners[0] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMin.y(), myMin.z()); | |
591 | aCorners[1] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMin.y(), myMax.z()); | |
592 | aCorners[2] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMax.y(), myMin.z()); | |
593 | aCorners[3] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMax.y(), myMax.z()); | |
594 | aCorners[4] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMin.y(), myMin.z()); | |
595 | aCorners[5] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMin.y(), myMax.z()); | |
596 | aCorners[6] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMax.y(), myMin.z()); | |
597 | aCorners[7] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMax.y(), myMax.z()); | |
598 | ||
599 | // NOTE: | |
600 | // (0, 0, 1), (0, 1, 0) and (0, 0, 1) directions from (myMin.x(), Ymin, Zmin) point | |
601 | // are reserved for trihedron axes. | |
602 | // So for the grid here are 9 edges of cube, | |
603 | // and, depending on the farest point, 2 or 3 of them may not be drawn | |
604 | // if they overlap displayed model. | |
605 | ||
606 | // Write an axes state what axes of bounding box are to be drawn | |
607 | GridAxes aGridAxes; | |
608 | Standard_ExtCharacter anAxesState = getGridAxes (aCorners, aGridAxes); | |
609 | ||
610 | // Remember current aspects | |
bf5f0ca2 | 611 | const OpenGl_Aspects* anOldAspectLine = theWorkspace->Aspects(); |
a79f67f8 | 612 | |
613 | OpenGl_Mat4 aModelMatrix; | |
614 | aModelMatrix.Convert (aContext->WorldViewState.Current()); | |
615 | ||
616 | // Remember model-view matrix | |
617 | aContext->WorldViewState.Push(); | |
618 | aContext->WorldViewState.SetCurrent (aModelMatrix); | |
619 | aContext->ApplyWorldViewMatrix(); | |
620 | ||
621 | if (myData.ToDrawGrid()) | |
622 | { | |
bf5f0ca2 | 623 | theWorkspace->SetAspects (&myGridLineAspect); |
7fd59977 | 624 | |
a79f67f8 | 625 | // render grid edges |
626 | if (anAxesState & XOO_XYO) | |
13a22457 | 627 | { |
a79f67f8 | 628 | renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMin.z()); |
13a22457 | 629 | } |
7fd59977 | 630 | |
a79f67f8 | 631 | if (anAxesState & XOO_XOZ) |
7fd59977 | 632 | { |
a79f67f8 | 633 | renderLine (myAxes[2].Line,theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMin.z()); |
13a22457 S |
634 | } |
635 | ||
a79f67f8 | 636 | if (anAxesState & OYO_OYZ) |
13a22457 | 637 | { |
a79f67f8 | 638 | renderLine (myAxes[2].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMin.z()); |
13a22457 | 639 | } |
13a22457 | 640 | |
a79f67f8 | 641 | if (anAxesState & OYO_XYO) |
13a22457 | 642 | { |
a79f67f8 | 643 | renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMin.z()); |
13a22457 | 644 | } |
a79f67f8 | 645 | |
646 | if (anAxesState & OOZ_XOZ) | |
13a22457 | 647 | { |
a79f67f8 | 648 | renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.z(), myMin.y(), myMax.z()); |
13a22457 S |
649 | } |
650 | ||
a79f67f8 | 651 | if (anAxesState & OOZ_OYZ) |
652 | { | |
653 | renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMin.x(), myMin.y(), myMax.z()); | |
654 | } | |
7fd59977 | 655 | |
a79f67f8 | 656 | if (anAxesState & OYZ_XYZ) |
13a22457 | 657 | { |
a79f67f8 | 658 | renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMax.z()); |
659 | } | |
a174a3c5 | 660 | |
a79f67f8 | 661 | if (anAxesState & XOZ_XYZ) |
662 | { | |
663 | renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMax.z()); | |
7fd59977 | 664 | } |
665 | ||
a79f67f8 | 666 | if (anAxesState & XYO_XYZ) |
7fd59977 | 667 | { |
a79f67f8 | 668 | renderLine (myAxes[2].Line, theWorkspace, aModelMatrix, myMax.x(), myMax.y(), myMin.z()); |
7fd59977 | 669 | } |
7fd59977 | 670 | |
a79f67f8 | 671 | for (Standard_Integer anIter = 0 ; anIter < 3; ++anIter) |
13a22457 | 672 | { |
a79f67f8 | 673 | renderGridPlane (theWorkspace, anIter, aGridAxes, aModelMatrix); |
13a22457 S |
674 | } |
675 | } | |
676 | ||
a79f67f8 | 677 | // Axes (arrows) |
678 | if (myData.ToDrawAxes()) | |
13a22457 | 679 | { |
a79f67f8 | 680 | for (Standard_Integer anIter = 0; anIter < 3; ++anIter) |
13a22457 | 681 | { |
a79f67f8 | 682 | renderAxis (theWorkspace, anIter, aModelMatrix); |
7fd59977 | 683 | } |
a79f67f8 | 684 | } |
7fd59977 | 685 | |
a79f67f8 | 686 | // Names of axes & values |
687 | for (Standard_Integer anIter = 0; anIter < 3; ++anIter) | |
688 | { | |
689 | // Restore current matrix | |
690 | aContext->WorldViewState.SetCurrent (aModelMatrix); | |
691 | aContext->ApplyWorldViewMatrix(); | |
692 | renderTickmarkLabels (theWorkspace, aModelMatrix, anIter, aGridAxes, aDpix); | |
693 | } | |
13a22457 | 694 | |
bf5f0ca2 | 695 | theWorkspace->SetAspects (anOldAspectLine); |
a174a3c5 | 696 | |
a79f67f8 | 697 | aContext->WorldViewState.Pop(); |
698 | aContext->ApplyWorldViewMatrix(); | |
699 | } | |
7fd59977 | 700 | |
a79f67f8 | 701 | // ======================================================================= |
702 | // method : SetMinMax | |
703 | // purpose : | |
704 | // ======================================================================= | |
705 | void OpenGl_GraduatedTrihedron::SetMinMax (const OpenGl_Vec3& theMin, const OpenGl_Vec3& theMax) | |
706 | { | |
707 | myMin = theMin; | |
708 | myMax = theMax; | |
709 | } | |
7fd59977 | 710 | |
a79f67f8 | 711 | // ======================================================================= |
712 | // method : OpenGl_GraduatedTrihedron::Axis constructor | |
536d98e2 | 713 | // purpose : |
a79f67f8 | 714 | // ======================================================================= |
715 | OpenGl_GraduatedTrihedron::Axis::Axis (const Graphic3d_AxisAspect& theAspect, | |
536d98e2 | 716 | const OpenGl_Vec3& theDirection) |
a79f67f8 | 717 | : Direction (theDirection), |
536d98e2 | 718 | Label (NCollection_String ((Standard_Utf16Char* )theAspect.Name().ToExtString()).ToCString(), theDirection, THE_LABEL_PARAMS), |
719 | Tickmark (NULL), | |
720 | Line (NULL), | |
721 | Arrow (NULL) | |
a79f67f8 | 722 | { |
b6472664 | 723 | NameColor = theAspect.NameColor(); |
724 | LineAspect.Aspect()->SetColor (theAspect.Color()); | |
a79f67f8 | 725 | } |
726 | ||
727 | // ======================================================================= | |
536d98e2 | 728 | // method : OpenGl_GraduatedTrihedron::Axis::~Axis |
729 | // purpose : | |
a79f67f8 | 730 | // ======================================================================= |
536d98e2 | 731 | OpenGl_GraduatedTrihedron::Axis::~Axis() |
a79f67f8 | 732 | { |
536d98e2 | 733 | // |
734 | } | |
735 | ||
736 | // ======================================================================= | |
737 | // method : OpenGl_GraduatedTrihedron::Axis operator= | |
738 | // purpose : | |
739 | // ======================================================================= | |
740 | OpenGl_GraduatedTrihedron::Axis& OpenGl_GraduatedTrihedron::Axis::operator= (const Axis& theOther) | |
741 | { | |
742 | Direction = theOther.Direction; | |
743 | NameColor = theOther.NameColor; | |
a79f67f8 | 744 | LineAspect = theOther.LineAspect; |
536d98e2 | 745 | Label = theOther.Label; |
a79f67f8 | 746 | |
536d98e2 | 747 | Line .InitBuffers (NULL, Graphic3d_TOPA_SEGMENTS, theOther.Line.Indices(), theOther.Line.Attributes(), theOther.Line.Bounds()); |
748 | Tickmark.InitBuffers (NULL, Graphic3d_TOPA_SEGMENTS, theOther.Tickmark.Indices(), theOther.Tickmark.Attributes(), theOther.Tickmark.Bounds()); | |
749 | Arrow .InitBuffers (NULL, Graphic3d_TOPA_POLYLINES, theOther.Arrow.Indices(), theOther.Arrow.Attributes(), theOther.Arrow.Bounds()); | |
a79f67f8 | 750 | return *this; |
751 | } | |
752 | ||
753 | // ======================================================================= | |
754 | // method : InitArrow | |
536d98e2 | 755 | // purpose : |
a79f67f8 | 756 | // ======================================================================= |
757 | void OpenGl_GraduatedTrihedron::Axis::InitArrow (const Handle(OpenGl_Context)& theContext, | |
758 | const Standard_ShortReal theLength, | |
759 | const OpenGl_Vec3& theNormal) const | |
760 | { | |
761 | // Draw from the end point of the aris | |
762 | OpenGl_Vec3 aLengthVec = -Direction * theLength; | |
763 | ||
764 | // Radial direction to the arrow | |
765 | OpenGl_Vec3 aRadial = OpenGl_Vec3::Cross (this->Direction, theNormal); | |
766 | if (aRadial.Modulus() < (Standard_ShortReal) Precision::Confusion()) | |
767 | { | |
768 | return; | |
13a22457 | 769 | } |
a79f67f8 | 770 | aRadial = aRadial.Normalized() * theLength * 0.2f; |
771 | ||
772 | // Initialize arrow primitive array | |
773 | // Make loop from polyline | |
774 | const OpenGl_Vec3 aPoint1 = aRadial + aLengthVec; | |
775 | const OpenGl_Vec3 aPoint2 (0.0f, 0.0f, 0.0f); | |
776 | const OpenGl_Vec3 aPoint3 = -aRadial + aLengthVec; | |
777 | ||
778 | Handle(Graphic3d_ArrayOfPolylines) anArray = new Graphic3d_ArrayOfPolylines (4); | |
779 | anArray->AddVertex (aPoint1); | |
780 | anArray->AddVertex (aPoint2); | |
781 | anArray->AddVertex (aPoint3); | |
782 | anArray->AddVertex (aPoint1); | |
783 | ||
536d98e2 | 784 | Arrow.InitBuffers (theContext, Graphic3d_TOPA_POLYLINES, |
785 | anArray->Indices(), anArray->Attributes(), anArray->Bounds()); | |
a79f67f8 | 786 | } |
13a22457 | 787 | |
a79f67f8 | 788 | // ======================================================================= |
789 | // function : InitTickmark | |
790 | // purpose : | |
791 | // ======================================================================= | |
792 | void OpenGl_GraduatedTrihedron::Axis::InitTickmark (const Handle(OpenGl_Context)& theContext, | |
793 | const OpenGl_Vec3& theDir) const | |
794 | { | |
795 | ||
796 | Handle(Graphic3d_ArrayOfSegments) anArray = new Graphic3d_ArrayOfSegments (2); | |
797 | anArray->AddVertex (0.0f, 0.0f, 0.0f); | |
798 | anArray->AddVertex (theDir); | |
536d98e2 | 799 | Tickmark.InitBuffers (theContext, Graphic3d_TOPA_SEGMENTS, |
800 | anArray->Indices(), anArray->Attributes(), anArray->Bounds()); | |
2166f0fa | 801 | |
7fd59977 | 802 | } |
803 | ||
a79f67f8 | 804 | // ======================================================================= |
805 | // function : InitLine | |
806 | // purpose : | |
807 | // ======================================================================= | |
808 | void OpenGl_GraduatedTrihedron::Axis::InitLine (const Handle(OpenGl_Context)& theContext, | |
809 | const OpenGl_Vec3& theDir) const | |
810 | { | |
811 | ||
812 | Handle(Graphic3d_ArrayOfSegments) anArray = new Graphic3d_ArrayOfSegments (2); | |
813 | anArray->AddVertex (0.0f, 0.0f, 0.0f); | |
814 | anArray->AddVertex (theDir); | |
815 | ||
536d98e2 | 816 | Line.InitBuffers (theContext, Graphic3d_TOPA_SEGMENTS, |
817 | anArray->Indices(), anArray->Attributes(), anArray->Bounds()); | |
a79f67f8 | 818 | } |
819 | ||
820 | // ======================================================================= | |
821 | // function : Release | |
822 | // purpose : | |
823 | // ======================================================================= | |
824 | void OpenGl_GraduatedTrihedron::Axis::Release (OpenGl_Context* theCtx) | |
7fd59977 | 825 | { |
536d98e2 | 826 | Label .Release (theCtx); |
827 | Tickmark.Release (theCtx); | |
828 | Line .Release (theCtx); | |
829 | Arrow .Release (theCtx); | |
13a22457 | 830 | } |