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