1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2013 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GlCore11.hxx>
18 #include <OpenGl_GraduatedTrihedron.hxx>
20 #include <Graphic3d_ArrayOfPolylines.hxx>
21 #include <Graphic3d_ArrayOfSegments.hxx>
22 #include <Graphic3d_GraphicDriver.hxx>
23 #include <Graphic3d_TransformPers.hxx>
24 #include <Graphic3d_TransformUtils.hxx>
26 #include <OpenGl_AspectLine.hxx>
27 #include <OpenGl_Workspace.hxx>
28 #include <OpenGl_View.hxx>
29 #include <OpenGl_Cylinder.hxx>
30 #include <Precision.hxx>
38 static const OpenGl_TextParam THE_LABEL_PARAMS =
40 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
44 // =======================================================================
45 // function : Constructor
47 // =======================================================================
48 OpenGl_GraduatedTrihedron::OpenGl_GraduatedTrihedron()
49 : myMin (0.0f, 0.0f, 0.0f),
50 myMax (100.0f, 100.0f, 100.0f),
51 myIsInitialized (Standard_False)
56 // =======================================================================
57 // function : SetValues
59 // =======================================================================
60 void OpenGl_GraduatedTrihedron::SetValues (const Graphic3d_GraduatedTrihedron& theData)
63 myIsInitialized = Standard_False;
66 // =======================================================================
67 // function : Destructor
69 // =======================================================================
70 OpenGl_GraduatedTrihedron::~OpenGl_GraduatedTrihedron()
75 // =======================================================================
78 // =======================================================================
79 void OpenGl_GraduatedTrihedron::Release (OpenGl_Context* theCtx)
81 myAxes[0].Release (theCtx);
82 myAxes[1].Release (theCtx);
83 myAxes[2].Release (theCtx);
84 myLabelValues.Release (theCtx);
87 // =======================================================================
88 // function : initResources
90 // =======================================================================
91 void OpenGl_GraduatedTrihedron::initGlResources (const Handle(OpenGl_Context)& theCtx) const
93 myAxes[0].Release (theCtx.operator->());
94 myAxes[1].Release (theCtx.operator->());
95 myAxes[2].Release (theCtx.operator->());
96 myLabelValues.Release (theCtx.operator->());
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));
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)
109 myAxes[anIt].Label.SetFontSize (theCtx, myData.NamesSize());
112 myLabelValues.SetFontSize (theCtx, myData.ValuesSize());
114 myAspectLabels.Aspect()->SetTextFontAspect (myData.NamesFontAspect());
115 myAspectLabels.Aspect()->SetFont (myData.NamesFont());
117 myAspectValues.Aspect()->SetTextFontAspect (myData.ValuesFontAspect());
118 myAspectValues.Aspect()->SetFont (myData.ValuesFont());
121 myGridLineAspect.Aspect()->SetColor (myData.GridColor());
124 // =======================================================================
125 // method : getNormal
126 // purpose : Normal of the view (not normalized!)
127 // =======================================================================
128 Standard_ShortReal OpenGl_GraduatedTrihedron::getNormal (const Handle(OpenGl_Context)& theContext,
129 OpenGl_Vec3& theNormal) const
131 const Standard_Integer* aViewport = theContext->Viewport();
133 OpenGl_Mat4 aModelMatrix;
134 OpenGl_Mat4 aProjMatrix;
135 aModelMatrix.Convert (theContext->ModelWorldState.Current() * theContext->WorldViewState.Current());
136 aProjMatrix .Convert (theContext->ProjectionState.Current());
138 OpenGl_Vec3 aPoint1, aPoint2, aPoint3;
139 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) aViewport[0],
140 (Standard_ShortReal) aViewport[1],
142 aModelMatrix, aProjMatrix, aViewport,
143 aPoint1.x(), aPoint1.y(), aPoint1.z());
145 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) (aViewport[0] + aViewport[2]),
146 (Standard_ShortReal) aViewport[1],
148 aModelMatrix, aProjMatrix, aViewport,
149 aPoint2.x(), aPoint2.y(), aPoint2.z());
151 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) aViewport[0],
152 (Standard_ShortReal) (aViewport[1] + aViewport[3]),
154 aModelMatrix, aProjMatrix, aViewport,
155 aPoint3.x(), aPoint3.y(), aPoint3.z());
157 const OpenGl_Vec3 aD1 = aPoint3 - aPoint1;
158 const OpenGl_Vec3 aD2 = aPoint2 - aPoint1;
159 theNormal = OpenGl_Vec3::Cross (aD1, aD2);
161 // Distance corresponding to 1 pixel
162 return aD2.Modulus() / (float) aViewport[2];
165 // =======================================================================
166 // method : getDistancetoCorner
168 // =======================================================================
169 Standard_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
175 return theNormal.x() * (theX - theCenter.x())
176 + theNormal.y() * (theY - theCenter.y())
177 + theNormal.z() * (theZ - theCenter.z());
180 // =======================================================================
181 // method : getGridAxes
183 // =======================================================================
184 Standard_ExtCharacter OpenGl_GraduatedTrihedron::getGridAxes (const Standard_ShortReal theCorners[8],
185 GridAxes& theGridAxes) const
187 // Find the farest corner
188 Standard_Byte aMaxIndex = 0;
189 Standard_ShortReal aMax = theCorners[aMaxIndex] > 0.0f ? theCorners[aMaxIndex] : 0.0f;
191 for (Standard_Byte anIt = 0; anIt < 8; ++anIt)
193 if (theCorners[anIt] > aMax)
195 aMax = theCorners[anIt];
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);
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());
213 return OOZ_XOZ | OYO_XYO |
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);
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());
228 return OOZ_XOZ | OYZ_XYZ |
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);
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());
243 return OYO_XYO | OYZ_XYZ |
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);
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());
258 return OOZ_XOZ | OYZ_XYZ | OYO_XYO |
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);
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());
273 return OOZ_XOZ | OYO_XYO |
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);
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());
288 return OOZ_XOZ | OYZ_XYZ |
289 XOO_XYO | XOZ_XYZ | OOZ_OYZ |
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);
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());
303 return OYO_XYO | OYZ_XYZ |
305 XOO_XOZ | XYO_XYZ | OYO_OYZ;
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);
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());
319 return OYO_XYO | OYZ_XYZ | OOZ_XOZ |
320 XOO_XYO | XOZ_XYZ | OOZ_OYZ |
321 XOO_XOZ | XYO_XYZ | OYO_OYZ;
326 // =======================================================================
327 // function : renderLine
329 // =======================================================================
330 void OpenGl_GraduatedTrihedron::renderLine (const OpenGl_PrimitiveArray& theLine,
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
337 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
338 OpenGl_Mat4 aMat (theMat);
339 Graphic3d_TransformUtils::Translate (aMat, theXt, theYt, theZt);
340 aContext->WorldViewState.SetCurrent (aMat);
341 aContext->ApplyWorldViewMatrix();
342 theLine.Render (theWorkspace);
345 // =======================================================================
346 // function : renderGridPlane
348 // =======================================================================
349 void OpenGl_GraduatedTrihedron::renderGridPlane (const Handle(OpenGl_Workspace)& theWorkspace,
350 const Standard_Integer& theIndex,
351 const GridAxes& theGridAxes,
352 OpenGl_Mat4& theMat) const
354 const Graphic3d_AxisAspect& aCurAspect = myData.AxisAspect (theIndex);
355 if (aCurAspect.TickmarksNumber() <= 0)
360 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
362 Standard_ShortReal aStep = theGridAxes.Axes[theIndex].GetData()[theIndex]
363 * (myMax.GetData()[theIndex] - myMin.GetData()[theIndex]) / aCurAspect.TickmarksNumber();
366 // Get two other axes directions and draw lines Axis.TickmarksNumber times.
367 // Combining together from three axes, these lines will make a grid.
368 for (Standard_Integer anIter = 1; anIter <= 2; ++anIter)
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)
376 aStart.ChangeData()[anIndex] = myMin.GetData()[anIndex];
379 Graphic3d_TransformUtils::Translate (aMat, aStart.x(), aStart.y(), aStart.z());
380 aContext->WorldViewState.SetCurrent (aMat);
381 aContext->ApplyWorldViewMatrix();
383 const OpenGl_Vec3 aStepVec (myAxes[theIndex].Direction * aStep);
384 for (Standard_Integer anIt = myData.ToDrawAxes() ? 1 : 0; anIt < aCurAspect.TickmarksNumber(); ++anIt)
386 Graphic3d_TransformUtils::Translate (aMat, aStepVec.x(), aStepVec.y(), aStepVec.z());
387 aContext->WorldViewState.SetCurrent (aMat);
388 aContext->ApplyWorldViewMatrix();
389 anAxis.Line.Render (theWorkspace);
394 // =======================================================================
395 // function : renderAxis
397 // =======================================================================
398 void OpenGl_GraduatedTrihedron::renderAxis (const Handle(OpenGl_Workspace)& theWorkspace,
399 const Standard_Integer& theIndex,
400 const OpenGl_Mat4& theMat) const
402 const Axis& anAxis = myAxes[theIndex];
404 theWorkspace->SetAspectLine (&anAxis.LineAspect);
405 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
407 // Reset transformations
408 aContext->WorldViewState.SetCurrent (theMat);
409 aContext->ApplyWorldViewMatrix();
412 OpenGl_Vec3 anArrowVec = myMin + anAxis.Direction * (myMax - myMin);
414 Graphic3d_TransformPers aTransMode;
415 aTransMode.Flags = Graphic3d_TMF_ZoomPers;
416 aTransMode.Point.x() = anArrowVec.x();
417 aTransMode.Point.y() = anArrowVec.y();
418 aTransMode.Point.z() = anArrowVec.z();
420 const OpenGl_Mat4& aProjection = aContext->ProjectionState.Current();
421 const OpenGl_Mat4& aWorldView = aContext->WorldViewState.Current();
422 const Standard_Integer aWidth = theWorkspace->Width();
423 const Standard_Integer aHeight = theWorkspace->Height();
425 // Take into account Transform Persistence
426 aContext->ModelWorldState.SetCurrent (aTransMode.Compute (theWorkspace->View()->Camera(), aProjection, aWorldView, aWidth, aHeight));
427 aContext->ApplyModelViewMatrix();
429 anAxis.Arrow.Render (theWorkspace);
431 // Get current Model-View and Projection states
432 OpenGl_Mat4 aModelMat;
433 OpenGl_Mat4 aProjMat;
434 aModelMat.Convert (aContext->WorldViewState.Current() * aContext->ModelWorldState.Current());
435 aProjMat .Convert (aContext->ProjectionState.Current());
437 // Get the window's (fixed) coordinates for before matrices modifications
438 OpenGl_Vec3 aEndPoint = -anAxis.Direction * myData.ArrowsLength();
439 OpenGl_Vec3 aWinPoint;
440 Graphic3d_TransformUtils::Project<Standard_ShortReal> (aEndPoint.x(), aEndPoint.y(), aEndPoint.z(),
441 aModelMat, aProjMat, aContext->Viewport(),
442 aWinPoint.x(), aWinPoint.y(), aWinPoint.z());
444 aContext->ModelWorldState.SetIdentity();
445 aModelMat.Convert (aContext->WorldViewState.Current());
446 aProjMat .Convert (aContext->ProjectionState.Current());
448 // Get start point of zoom persistent arrow
449 OpenGl_Vec3 anArrowStart;
450 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(),
451 aModelMat, aProjMat, aContext->Viewport(),
452 anArrowStart.x(), anArrowStart.y(), anArrowStart.z());
455 Graphic3d_TransformUtils::Translate (aModelMat, myMin.x(), myMin.y(), myMin.z());
457 Standard_ShortReal aScaleFactor = ( (anArrowStart - myMin)*anAxis.Direction ).Modulus()
458 / (anAxis.Direction * (myMax - myMin) ).Modulus();
459 OpenGl_Vec3 aScaleAxes = anAxis.Direction * aScaleFactor;
460 Graphic3d_TransformUtils::Scale (aModelMat, aScaleAxes.x(), aScaleAxes.y(), aScaleAxes.z());
462 aContext->WorldViewState.SetCurrent (aModelMat);
463 aContext->ApplyWorldViewMatrix();
464 anAxis.Line.Render (theWorkspace);
467 // =======================================================================
468 // function : renderTickmarkTextLabels
470 // =======================================================================
471 void OpenGl_GraduatedTrihedron::renderTickmarkLabels (const Handle(OpenGl_Workspace)& theWorkspace,
472 const OpenGl_Mat4& theMat,
473 const Standard_Integer theIndex,
474 const GridAxes& theGridAxes,
475 const Standard_ShortReal theDpix) const
477 const Graphic3d_AxisAspect& aCurAspect = myData.AxisAspect (theIndex);
478 if (!aCurAspect.ToDrawName() && !aCurAspect.ToDrawValues())
483 Standard_Character aTextValue[128];
484 const Axis& anAxis = myAxes[theIndex];
485 const OpenGl_Vec3 aSizeVec (myMax - myMin);
486 Standard_ShortReal aStep = theGridAxes.Axes[theIndex].GetData()[theIndex]
487 * (myMax.GetData()[theIndex] - myMin.GetData()[theIndex]) / aCurAspect.TickmarksNumber();
489 OpenGl_Vec3 aDir = (theGridAxes.Ticks[theIndex] - theGridAxes.Origin).Normalized();
490 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
492 if (aCurAspect.ToDrawTickmarks() && aCurAspect.TickmarksNumber() > 0)
494 theWorkspace->SetAspectLine (&myGridLineAspect);
496 OpenGl_Mat4 aModelMat (theMat);
498 anAxis.InitTickmark (aContext, aDir * (Standard_ShortReal) aCurAspect.TickmarksLength() * theDpix);
499 Graphic3d_TransformUtils::Translate (aModelMat, theGridAxes.Ticks[theIndex].x(),
500 theGridAxes.Ticks[theIndex].y(),
501 theGridAxes.Ticks[theIndex].z());
502 aContext->WorldViewState.SetCurrent (aModelMat);
503 aContext->ApplyWorldViewMatrix();
504 OpenGl_Vec3 aStepVec = anAxis.Direction * aStep;
505 for (Standard_Integer anIter = 0; anIter <= aCurAspect.TickmarksNumber(); ++anIter)
507 anAxis.Tickmark.Render (theWorkspace);
508 Graphic3d_TransformUtils::Translate (aModelMat, aStepVec.x(), aStepVec.y(), aStepVec.z());
509 aContext->WorldViewState.SetCurrent (aModelMat);
510 aContext->ApplyWorldViewMatrix();
515 aContext->WorldViewState.SetCurrent (theMat);
516 aContext->ApplyWorldViewMatrix();
518 if (aCurAspect.ToDrawName())
520 Standard_Real anOffset = aCurAspect.NameOffset() + aCurAspect.TickmarksLength();
522 OpenGl_Vec3 aMiddle (theGridAxes.Ticks[theIndex] + aSizeVec * theGridAxes.Axes[theIndex] * 0.5f + aDir * (Standard_ShortReal)(theDpix * anOffset));
524 myAspectLabels.Aspect()->SetColor (anAxis.NameColor);
525 theWorkspace->SetAspectText (&myAspectLabels);
526 anAxis.Label.SetPosition (aMiddle);
527 anAxis.Label.Render (theWorkspace);
530 if (aCurAspect.ToDrawValues() && aCurAspect.TickmarksNumber() > 0)
532 myAspectValues.Aspect()->SetColor (anAxis.LineAspect.Aspect()->Color());
533 theWorkspace->SetAspectText (&myAspectValues);
534 Standard_Real anOffset = aCurAspect.ValuesOffset() + aCurAspect.TickmarksLength();
536 for (Standard_Integer anIt = 0; anIt <= aCurAspect.TickmarksNumber(); ++anIt)
538 sprintf (aTextValue, "%g", theGridAxes.Ticks[theIndex].GetData()[theIndex] + anIt * aStep);
539 OpenGl_Vec3 aPos (theGridAxes.Ticks[theIndex] + anAxis.Direction* (Standard_ShortReal) (anIt * aStep) + aDir * (Standard_ShortReal) (theDpix * anOffset));
540 myLabelValues.Init (theWorkspace->GetGlContext(), aTextValue, aPos);
541 myLabelValues.Render (theWorkspace);
546 // =======================================================================
548 // purpose : call_graduatedtrihedron_redraw
549 // =======================================================================
550 void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
552 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
553 if (!myIsInitialized)
555 initGlResources (theWorkspace->GetGlContext());
556 myIsInitialized = Standard_True;
559 // Update boundary box
560 OpenGl_Vec3 anOldMin = myMin;
561 OpenGl_Vec3 anOldMax = myMax;
563 if (myData.CubicAxesCallback)
565 myData.CubicAxesCallback (myData.PtrView);
566 if (!myAxes[0].Line.IsInitialized()
567 || !myAxes[1].Line.IsInitialized()
568 || !myAxes[2].Line.IsInitialized()
569 || OpenGl_Vec3 (anOldMin - myMin).Modulus() > Precision::Confusion()
570 || OpenGl_Vec3 (anOldMax - myMax).Modulus() > Precision::Confusion())
572 myAxes[0].InitLine (aContext, OpenGl_Vec3 (myMax.x() - myMin.x(), 0.0f, 0.0f));
573 myAxes[1].InitLine (aContext, OpenGl_Vec3 (0.0f, myMax.y() - myMin.y(), 0.0f));
574 myAxes[2].InitLine (aContext, OpenGl_Vec3 (0.0f, 0.0f, myMax.z() - myMin.z()));
578 // Find the farest point of bounding box
580 // Get normal of the view out of user and distance corresponding to 1 pixel
582 Standard_ShortReal aDpix = getNormal (aContext, aNormal);
585 // Get central point of bounding box
587 aCenter = (myMin + myMax) * 0.5f;
589 // Check distance to corners of bounding box along the normal
590 Standard_ShortReal aCorners[8];
591 aCorners[0] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMin.y(), myMin.z());
592 aCorners[1] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMin.y(), myMax.z());
593 aCorners[2] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMax.y(), myMin.z());
594 aCorners[3] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMax.y(), myMax.z());
595 aCorners[4] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMin.y(), myMin.z());
596 aCorners[5] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMin.y(), myMax.z());
597 aCorners[6] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMax.y(), myMin.z());
598 aCorners[7] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMax.y(), myMax.z());
601 // (0, 0, 1), (0, 1, 0) and (0, 0, 1) directions from (myMin.x(), Ymin, Zmin) point
602 // are reserved for trihedron axes.
603 // So for the grid here are 9 edges of cube,
604 // and, depending on the farest point, 2 or 3 of them may not be drawn
605 // if they overlap displayed model.
607 // Write an axes state what axes of bounding box are to be drawn
609 Standard_ExtCharacter anAxesState = getGridAxes (aCorners, aGridAxes);
611 // Remember current aspects
612 const OpenGl_AspectLine* anOldAspectLine = theWorkspace->AspectLine();
613 const OpenGl_AspectText* anOldAspectText = theWorkspace->AspectText();
615 OpenGl_Mat4 aModelMatrix;
616 aModelMatrix.Convert (aContext->WorldViewState.Current());
618 // Remember model-view matrix
619 aContext->WorldViewState.Push();
620 aContext->WorldViewState.SetCurrent (aModelMatrix);
621 aContext->ApplyWorldViewMatrix();
623 if (myData.ToDrawGrid())
625 theWorkspace->SetAspectLine (&myGridLineAspect);
628 if (anAxesState & XOO_XYO)
630 renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMin.z());
633 if (anAxesState & XOO_XOZ)
635 renderLine (myAxes[2].Line,theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMin.z());
638 if (anAxesState & OYO_OYZ)
640 renderLine (myAxes[2].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMin.z());
643 if (anAxesState & OYO_XYO)
645 renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMin.z());
648 if (anAxesState & OOZ_XOZ)
650 renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.z(), myMin.y(), myMax.z());
653 if (anAxesState & OOZ_OYZ)
655 renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMin.x(), myMin.y(), myMax.z());
658 if (anAxesState & OYZ_XYZ)
660 renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMax.z());
663 if (anAxesState & XOZ_XYZ)
665 renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMax.z());
668 if (anAxesState & XYO_XYZ)
670 renderLine (myAxes[2].Line, theWorkspace, aModelMatrix, myMax.x(), myMax.y(), myMin.z());
673 for (Standard_Integer anIter = 0 ; anIter < 3; ++anIter)
675 renderGridPlane (theWorkspace, anIter, aGridAxes, aModelMatrix);
680 if (myData.ToDrawAxes())
682 for (Standard_Integer anIter = 0; anIter < 3; ++anIter)
684 renderAxis (theWorkspace, anIter, aModelMatrix);
688 // Names of axes & values
689 for (Standard_Integer anIter = 0; anIter < 3; ++anIter)
691 // Restore current matrix
692 aContext->WorldViewState.SetCurrent (aModelMatrix);
693 aContext->ApplyWorldViewMatrix();
694 renderTickmarkLabels (theWorkspace, aModelMatrix, anIter, aGridAxes, aDpix);
697 theWorkspace->SetAspectLine (anOldAspectLine);
698 theWorkspace->SetAspectText (anOldAspectText);
700 aContext->WorldViewState.Pop();
701 aContext->ApplyWorldViewMatrix();
704 // =======================================================================
705 // method : SetMinMax
707 // =======================================================================
708 void OpenGl_GraduatedTrihedron::SetMinMax (const OpenGl_Vec3& theMin, const OpenGl_Vec3& theMax)
714 // =======================================================================
715 // method : OpenGl_GraduatedTrihedron::Axis constructor
717 // =======================================================================
718 OpenGl_GraduatedTrihedron::Axis::Axis (const Graphic3d_AxisAspect& theAspect,
719 const OpenGl_Vec3& theDirection)
720 : Direction (theDirection),
721 Label (NCollection_String ((Standard_Utf16Char* )theAspect.Name().ToExtString()).ToCString(), theDirection, THE_LABEL_PARAMS),
726 NameColor = theAspect.NameColor();
727 LineAspect.Aspect()->SetColor (theAspect.Color());
730 // =======================================================================
731 // method : OpenGl_GraduatedTrihedron::Axis::~Axis
733 // =======================================================================
734 OpenGl_GraduatedTrihedron::Axis::~Axis()
739 // =======================================================================
740 // method : OpenGl_GraduatedTrihedron::Axis operator=
742 // =======================================================================
743 OpenGl_GraduatedTrihedron::Axis& OpenGl_GraduatedTrihedron::Axis::operator= (const Axis& theOther)
745 Direction = theOther.Direction;
746 NameColor = theOther.NameColor;
747 LineAspect = theOther.LineAspect;
748 Label = theOther.Label;
750 Line .InitBuffers (NULL, Graphic3d_TOPA_SEGMENTS, theOther.Line.Indices(), theOther.Line.Attributes(), theOther.Line.Bounds());
751 Tickmark.InitBuffers (NULL, Graphic3d_TOPA_SEGMENTS, theOther.Tickmark.Indices(), theOther.Tickmark.Attributes(), theOther.Tickmark.Bounds());
752 Arrow .InitBuffers (NULL, Graphic3d_TOPA_POLYLINES, theOther.Arrow.Indices(), theOther.Arrow.Attributes(), theOther.Arrow.Bounds());
756 // =======================================================================
757 // method : InitArrow
759 // =======================================================================
760 void OpenGl_GraduatedTrihedron::Axis::InitArrow (const Handle(OpenGl_Context)& theContext,
761 const Standard_ShortReal theLength,
762 const OpenGl_Vec3& theNormal) const
764 // Draw from the end point of the aris
765 OpenGl_Vec3 aLengthVec = -Direction * theLength;
767 // Radial direction to the arrow
768 OpenGl_Vec3 aRadial = OpenGl_Vec3::Cross (this->Direction, theNormal);
769 if (aRadial.Modulus() < (Standard_ShortReal) Precision::Confusion())
773 aRadial = aRadial.Normalized() * theLength * 0.2f;
775 // Initialize arrow primitive array
776 // Make loop from polyline
777 const OpenGl_Vec3 aPoint1 = aRadial + aLengthVec;
778 const OpenGl_Vec3 aPoint2 (0.0f, 0.0f, 0.0f);
779 const OpenGl_Vec3 aPoint3 = -aRadial + aLengthVec;
781 Handle(Graphic3d_ArrayOfPolylines) anArray = new Graphic3d_ArrayOfPolylines (4);
782 anArray->AddVertex (aPoint1);
783 anArray->AddVertex (aPoint2);
784 anArray->AddVertex (aPoint3);
785 anArray->AddVertex (aPoint1);
787 Arrow.InitBuffers (theContext, Graphic3d_TOPA_POLYLINES,
788 anArray->Indices(), anArray->Attributes(), anArray->Bounds());
791 // =======================================================================
792 // function : InitTickmark
794 // =======================================================================
795 void OpenGl_GraduatedTrihedron::Axis::InitTickmark (const Handle(OpenGl_Context)& theContext,
796 const OpenGl_Vec3& theDir) const
799 Handle(Graphic3d_ArrayOfSegments) anArray = new Graphic3d_ArrayOfSegments (2);
800 anArray->AddVertex (0.0f, 0.0f, 0.0f);
801 anArray->AddVertex (theDir);
802 Tickmark.InitBuffers (theContext, Graphic3d_TOPA_SEGMENTS,
803 anArray->Indices(), anArray->Attributes(), anArray->Bounds());
807 // =======================================================================
808 // function : InitLine
810 // =======================================================================
811 void OpenGl_GraduatedTrihedron::Axis::InitLine (const Handle(OpenGl_Context)& theContext,
812 const OpenGl_Vec3& theDir) const
815 Handle(Graphic3d_ArrayOfSegments) anArray = new Graphic3d_ArrayOfSegments (2);
816 anArray->AddVertex (0.0f, 0.0f, 0.0f);
817 anArray->AddVertex (theDir);
819 Line.InitBuffers (theContext, Graphic3d_TOPA_SEGMENTS,
820 anArray->Indices(), anArray->Attributes(), anArray->Bounds());
823 // =======================================================================
824 // function : Release
826 // =======================================================================
827 void OpenGl_GraduatedTrihedron::Axis::Release (OpenGl_Context* theCtx)
829 Label .Release (theCtx);
830 Tickmark.Release (theCtx);
831 Line .Release (theCtx);
832 Arrow .Release (theCtx);