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_Text.hxx>
24 #include <Graphic3d_TransformPers.hxx>
25 #include <Graphic3d_TransformUtils.hxx>
27 #include <OpenGl_Workspace.hxx>
28 #include <OpenGl_View.hxx>
29 #include <Precision.hxx>
37 static Standard_ShortReal THE_LABEL_HEIGHT = 16;
38 static Graphic3d_HorizontalTextAlignment THE_LABEL_HALIGH = Graphic3d_HTA_LEFT;
39 static Graphic3d_VerticalTextAlignment THE_LABEL_VALIGH = Graphic3d_VTA_BOTTOM;
42 // =======================================================================
43 // function : Constructor
45 // =======================================================================
46 OpenGl_GraduatedTrihedron::OpenGl_GraduatedTrihedron()
47 : myMin (0.0f, 0.0f, 0.0f),
48 myMax (100.0f, 100.0f, 100.0f),
49 myIsInitialized (Standard_False)
54 // =======================================================================
55 // function : SetValues
57 // =======================================================================
58 void OpenGl_GraduatedTrihedron::SetValues (const Graphic3d_GraduatedTrihedron& theData)
61 myIsInitialized = Standard_False;
64 // =======================================================================
65 // function : Destructor
67 // =======================================================================
68 OpenGl_GraduatedTrihedron::~OpenGl_GraduatedTrihedron()
73 // =======================================================================
76 // =======================================================================
77 void OpenGl_GraduatedTrihedron::Release (OpenGl_Context* theCtx)
79 myAxes[0].Release (theCtx);
80 myAxes[1].Release (theCtx);
81 myAxes[2].Release (theCtx);
82 myLabelValues.Release (theCtx);
85 // =======================================================================
86 // function : initResources
88 // =======================================================================
89 void OpenGl_GraduatedTrihedron::initGlResources (const Handle(OpenGl_Context)& theCtx) const
91 myAxes[0].Release (theCtx.operator->());
92 myAxes[1].Release (theCtx.operator->());
93 myAxes[2].Release (theCtx.operator->());
94 myLabelValues.Release (theCtx.operator->());
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));
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)
107 myAxes[anIt].Label.SetFontSize (theCtx, myData.NamesSize());
110 myLabelValues.SetFontSize (theCtx, myData.ValuesSize());
112 myAspectLabels.Aspect()->SetTextFontAspect (myData.NamesFontAspect());
113 myAspectLabels.Aspect()->SetTextFont (!myData.NamesFont().IsEmpty()
114 ? new TCollection_HAsciiString (myData.NamesFont())
115 : Handle(TCollection_HAsciiString )());
117 myAspectValues.Aspect()->SetTextFontAspect (myData.ValuesFontAspect());
118 myAspectValues.Aspect()->SetTextFont (!myData.ValuesFont().IsEmpty()
119 ? new TCollection_HAsciiString (myData.ValuesFont())
120 : Handle(TCollection_HAsciiString )());
123 myGridLineAspect.Aspect()->SetColor (myData.GridColor());
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
133 const Standard_Integer* aViewport = theContext->Viewport();
135 OpenGl_Mat4 aModelMatrix;
136 OpenGl_Mat4 aProjMatrix;
137 aModelMatrix.Convert (theContext->ModelWorldState.Current() * theContext->WorldViewState.Current());
138 aProjMatrix .Convert (theContext->ProjectionState.Current());
140 OpenGl_Vec3 aPoint1, aPoint2, aPoint3;
141 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) aViewport[0],
142 (Standard_ShortReal) aViewport[1],
144 aModelMatrix, aProjMatrix, aViewport,
145 aPoint1.x(), aPoint1.y(), aPoint1.z());
147 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) (aViewport[0] + aViewport[2]),
148 (Standard_ShortReal) aViewport[1],
150 aModelMatrix, aProjMatrix, aViewport,
151 aPoint2.x(), aPoint2.y(), aPoint2.z());
153 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> ((Standard_ShortReal) aViewport[0],
154 (Standard_ShortReal) (aViewport[1] + aViewport[3]),
156 aModelMatrix, aProjMatrix, aViewport,
157 aPoint3.x(), aPoint3.y(), aPoint3.z());
159 const OpenGl_Vec3 aD1 = aPoint3 - aPoint1;
160 const OpenGl_Vec3 aD2 = aPoint2 - aPoint1;
161 theNormal = OpenGl_Vec3::Cross (aD1, aD2);
163 // Distance corresponding to 1 pixel
164 return aD2.Modulus() / (float) aViewport[2];
167 // =======================================================================
168 // method : getDistancetoCorner
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
177 return theNormal.x() * (theX - theCenter.x())
178 + theNormal.y() * (theY - theCenter.y())
179 + theNormal.z() * (theZ - theCenter.z());
182 // =======================================================================
183 // method : getGridAxes
185 // =======================================================================
186 Standard_ExtCharacter OpenGl_GraduatedTrihedron::getGridAxes (const Standard_ShortReal theCorners[8],
187 GridAxes& theGridAxes) const
189 // Find the farest corner
190 Standard_Byte aMaxIndex = 0;
191 Standard_ShortReal aMax = theCorners[aMaxIndex] > 0.0f ? theCorners[aMaxIndex] : 0.0f;
193 for (Standard_Byte anIt = 0; anIt < 8; ++anIt)
195 if (theCorners[anIt] > aMax)
197 aMax = theCorners[anIt];
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);
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());
215 return OOZ_XOZ | OYO_XYO |
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);
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());
230 return OOZ_XOZ | OYZ_XYZ |
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);
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());
245 return OYO_XYO | OYZ_XYZ |
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);
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());
260 return OOZ_XOZ | OYZ_XYZ | OYO_XYO |
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);
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());
275 return OOZ_XOZ | OYO_XYO |
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);
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());
290 return OOZ_XOZ | OYZ_XYZ |
291 XOO_XYO | XOZ_XYZ | OOZ_OYZ |
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);
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());
305 return OYO_XYO | OYZ_XYZ |
307 XOO_XOZ | XYO_XYZ | OYO_OYZ;
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);
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());
321 return OYO_XYO | OYZ_XYZ | OOZ_XOZ |
322 XOO_XYO | XOZ_XYZ | OOZ_OYZ |
323 XOO_XOZ | XYO_XYZ | OYO_OYZ;
328 // =======================================================================
329 // function : renderLine
331 // =======================================================================
332 void OpenGl_GraduatedTrihedron::renderLine (const OpenGl_PrimitiveArray& theLine,
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
339 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
340 OpenGl_Mat4 aMat (theMat);
341 Graphic3d_TransformUtils::Translate (aMat, theXt, theYt, theZt);
342 aContext->WorldViewState.SetCurrent (aMat);
343 aContext->ApplyWorldViewMatrix();
344 theLine.Render (theWorkspace);
347 // =======================================================================
348 // function : renderGridPlane
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
356 const Graphic3d_AxisAspect& aCurAspect = myData.AxisAspect (theIndex);
357 if (aCurAspect.TickmarksNumber() <= 0)
362 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
364 Standard_ShortReal aStep = theGridAxes.Axes[theIndex].GetData()[theIndex]
365 * (myMax.GetData()[theIndex] - myMin.GetData()[theIndex]) / aCurAspect.TickmarksNumber();
368 // Get two other axes directions and draw lines Axis.TickmarksNumber times.
369 // Combining together from three axes, these lines will make a grid.
370 for (Standard_Integer anIter = 1; anIter <= 2; ++anIter)
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)
378 aStart.ChangeData()[anIndex] = myMin.GetData()[anIndex];
381 Graphic3d_TransformUtils::Translate (aMat, aStart.x(), aStart.y(), aStart.z());
382 aContext->WorldViewState.SetCurrent (aMat);
383 aContext->ApplyWorldViewMatrix();
385 const OpenGl_Vec3 aStepVec (myAxes[theIndex].Direction * aStep);
386 for (Standard_Integer anIt = myData.ToDrawAxes() ? 1 : 0; anIt < aCurAspect.TickmarksNumber(); ++anIt)
388 Graphic3d_TransformUtils::Translate (aMat, aStepVec.x(), aStepVec.y(), aStepVec.z());
389 aContext->WorldViewState.SetCurrent (aMat);
390 aContext->ApplyWorldViewMatrix();
391 anAxis.Line.Render (theWorkspace);
396 // =======================================================================
397 // function : renderAxis
399 // =======================================================================
400 void OpenGl_GraduatedTrihedron::renderAxis (const Handle(OpenGl_Workspace)& theWorkspace,
401 const Standard_Integer& theIndex,
402 const OpenGl_Mat4& theMat) const
404 const Axis& anAxis = myAxes[theIndex];
406 theWorkspace->SetAspects (&anAxis.LineAspect);
407 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
409 // Reset transformations
410 aContext->WorldViewState.SetCurrent (theMat);
411 aContext->ApplyWorldViewMatrix();
414 OpenGl_Vec3 anArrowVec = myMin + anAxis.Direction * (myMax - myMin);
416 Graphic3d_TransformPers aTransMode (Graphic3d_TMF_ZoomPers, gp_Pnt (Standard_Real(anArrowVec.x()),
417 Standard_Real(anArrowVec.y()),
418 Standard_Real(anArrowVec.z())));
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();
424 // Take into account Transform Persistence
425 aContext->ModelWorldState.SetCurrent (aTransMode.Compute (theWorkspace->View()->Camera(), aProjection, aWorldView, aWidth, aHeight));
426 aContext->ApplyModelViewMatrix();
428 anAxis.Arrow.Render (theWorkspace);
430 // Get current Model-View and Projection states
431 OpenGl_Mat4 aModelMat;
432 OpenGl_Mat4 aProjMat;
433 aModelMat.Convert (aContext->WorldViewState.Current() * aContext->ModelWorldState.Current());
434 aProjMat .Convert (aContext->ProjectionState.Current());
436 // Get the window's (fixed) coordinates for before matrices modifications
437 OpenGl_Vec3 aEndPoint = -anAxis.Direction * myData.ArrowsLength();
438 OpenGl_Vec3 aWinPoint;
439 Graphic3d_TransformUtils::Project<Standard_ShortReal> (aEndPoint.x(), aEndPoint.y(), aEndPoint.z(),
440 aModelMat, aProjMat, aContext->Viewport(),
441 aWinPoint.x(), aWinPoint.y(), aWinPoint.z());
443 aContext->ModelWorldState.SetIdentity();
444 aModelMat.Convert (aContext->WorldViewState.Current());
445 aProjMat .Convert (aContext->ProjectionState.Current());
447 // Get start point of zoom persistent arrow
448 OpenGl_Vec3 anArrowStart;
449 Graphic3d_TransformUtils::UnProject<Standard_ShortReal> (aWinPoint.x(), aWinPoint.y(), aWinPoint.z(),
450 aModelMat, aProjMat, aContext->Viewport(),
451 anArrowStart.x(), anArrowStart.y(), anArrowStart.z());
454 Graphic3d_TransformUtils::Translate (aModelMat, myMin.x(), myMin.y(), myMin.z());
456 Standard_ShortReal aScaleFactor = ( (anArrowStart - myMin)*anAxis.Direction ).Modulus()
457 / (anAxis.Direction * (myMax - myMin) ).Modulus();
458 OpenGl_Vec3 aScaleAxes = anAxis.Direction * aScaleFactor;
459 Graphic3d_TransformUtils::Scale (aModelMat, aScaleAxes.x(), aScaleAxes.y(), aScaleAxes.z());
461 aContext->WorldViewState.SetCurrent (aModelMat);
462 aContext->ApplyWorldViewMatrix();
463 anAxis.Line.Render (theWorkspace);
466 // =======================================================================
467 // function : renderTickmarkTextLabels
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
476 const Graphic3d_AxisAspect& aCurAspect = myData.AxisAspect (theIndex);
477 if (!aCurAspect.ToDrawName() && !aCurAspect.ToDrawValues())
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]
486 * (myMax.GetData()[theIndex] - myMin.GetData()[theIndex]) / aCurAspect.TickmarksNumber();
488 OpenGl_Vec3 aDir = (theGridAxes.Ticks[theIndex] - theGridAxes.Origin).Normalized();
489 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
491 if (aCurAspect.ToDrawTickmarks() && aCurAspect.TickmarksNumber() > 0)
493 theWorkspace->SetAspects (&myGridLineAspect);
495 OpenGl_Mat4 aModelMat (theMat);
497 anAxis.InitTickmark (aContext, aDir * (Standard_ShortReal) aCurAspect.TickmarksLength() * theDpix);
498 Graphic3d_TransformUtils::Translate (aModelMat, theGridAxes.Ticks[theIndex].x(),
499 theGridAxes.Ticks[theIndex].y(),
500 theGridAxes.Ticks[theIndex].z());
501 aContext->WorldViewState.SetCurrent (aModelMat);
502 aContext->ApplyWorldViewMatrix();
503 OpenGl_Vec3 aStepVec = anAxis.Direction * aStep;
504 for (Standard_Integer anIter = 0; anIter <= aCurAspect.TickmarksNumber(); ++anIter)
506 anAxis.Tickmark.Render (theWorkspace);
507 Graphic3d_TransformUtils::Translate (aModelMat, aStepVec.x(), aStepVec.y(), aStepVec.z());
508 aContext->WorldViewState.SetCurrent (aModelMat);
509 aContext->ApplyWorldViewMatrix();
514 aContext->WorldViewState.SetCurrent (theMat);
515 aContext->ApplyWorldViewMatrix();
517 if (aCurAspect.ToDrawName())
519 Standard_Real anOffset = aCurAspect.NameOffset() + aCurAspect.TickmarksLength();
521 OpenGl_Vec3 aMiddle (theGridAxes.Ticks[theIndex] + aSizeVec * theGridAxes.Axes[theIndex] * 0.5f + aDir * (Standard_ShortReal)(theDpix * anOffset));
523 myAspectLabels.Aspect()->SetColor (anAxis.NameColor);
524 theWorkspace->SetAspects (&myAspectLabels);
525 anAxis.Label.Text()->SetPosition (gp_Pnt (aMiddle.x(), aMiddle.y(), aMiddle.z()));
526 anAxis.Label.Render (theWorkspace);
529 if (aCurAspect.ToDrawValues() && aCurAspect.TickmarksNumber() > 0)
531 myAspectValues.Aspect()->SetColor (anAxis.LineAspect.Aspect()->Color());
532 theWorkspace->SetAspects (&myAspectValues);
533 Standard_Real anOffset = aCurAspect.ValuesOffset() + aCurAspect.TickmarksLength();
535 for (Standard_Integer anIt = 0; anIt <= aCurAspect.TickmarksNumber(); ++anIt)
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));
540 Handle(Graphic3d_Text) aText = myLabelValues.Text();
541 aText->SetText (aTextValue);
542 aText->SetPosition (gp_Pnt(aPos.x(), aPos.y(), aPos.z()));
544 myLabelValues.Reset (theWorkspace->GetGlContext());
545 myLabelValues.Render (theWorkspace);
550 // =======================================================================
552 // purpose : call_graduatedtrihedron_redraw
553 // =======================================================================
554 void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
556 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
557 if (!myIsInitialized)
559 initGlResources (theWorkspace->GetGlContext());
560 myIsInitialized = Standard_True;
563 // Update boundary box
564 OpenGl_Vec3 anOldMin = myMin;
565 OpenGl_Vec3 anOldMax = myMax;
567 if (myData.CubicAxesCallback)
569 myData.CubicAxesCallback (myData.PtrView);
570 if (!myAxes[0].Line.IsInitialized()
571 || !myAxes[1].Line.IsInitialized()
572 || !myAxes[2].Line.IsInitialized()
573 || OpenGl_Vec3 (anOldMin - myMin).Modulus() > Precision::Confusion()
574 || OpenGl_Vec3 (anOldMax - myMax).Modulus() > Precision::Confusion())
576 myAxes[0].InitLine (aContext, OpenGl_Vec3 (myMax.x() - myMin.x(), 0.0f, 0.0f));
577 myAxes[1].InitLine (aContext, OpenGl_Vec3 (0.0f, myMax.y() - myMin.y(), 0.0f));
578 myAxes[2].InitLine (aContext, OpenGl_Vec3 (0.0f, 0.0f, myMax.z() - myMin.z()));
582 // Find the farest point of bounding box
584 // Get normal of the view out of user and distance corresponding to 1 pixel
586 Standard_ShortReal aDpix = getNormal (aContext, aNormal);
589 // Get central point of bounding box
591 aCenter = (myMin + myMax) * 0.5f;
593 // Check distance to corners of bounding box along the normal
594 Standard_ShortReal aCorners[8];
595 aCorners[0] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMin.y(), myMin.z());
596 aCorners[1] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMin.y(), myMax.z());
597 aCorners[2] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMax.y(), myMin.z());
598 aCorners[3] = getDistanceToCorner (aNormal, aCenter, myMin.x(), myMax.y(), myMax.z());
599 aCorners[4] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMin.y(), myMin.z());
600 aCorners[5] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMin.y(), myMax.z());
601 aCorners[6] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMax.y(), myMin.z());
602 aCorners[7] = getDistanceToCorner (aNormal, aCenter, myMax.x(), myMax.y(), myMax.z());
605 // (0, 0, 1), (0, 1, 0) and (0, 0, 1) directions from (myMin.x(), Ymin, Zmin) point
606 // are reserved for trihedron axes.
607 // So for the grid here are 9 edges of cube,
608 // and, depending on the farest point, 2 or 3 of them may not be drawn
609 // if they overlap displayed model.
611 // Write an axes state what axes of bounding box are to be drawn
613 Standard_ExtCharacter anAxesState = getGridAxes (aCorners, aGridAxes);
615 // Remember current aspects
616 const OpenGl_Aspects* anOldAspectLine = theWorkspace->Aspects();
618 OpenGl_Mat4 aModelMatrix;
619 aModelMatrix.Convert (aContext->WorldViewState.Current());
621 // Remember model-view matrix
622 aContext->WorldViewState.Push();
623 aContext->WorldViewState.SetCurrent (aModelMatrix);
624 aContext->ApplyWorldViewMatrix();
626 if (myData.ToDrawGrid())
628 theWorkspace->SetAspects (&myGridLineAspect);
631 if (anAxesState & XOO_XYO)
633 renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMin.z());
636 if (anAxesState & XOO_XOZ)
638 renderLine (myAxes[2].Line,theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMin.z());
641 if (anAxesState & OYO_OYZ)
643 renderLine (myAxes[2].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMin.z());
646 if (anAxesState & OYO_XYO)
648 renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMin.z());
651 if (anAxesState & OOZ_XOZ)
653 renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.z(), myMin.y(), myMax.z());
656 if (anAxesState & OOZ_OYZ)
658 renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMin.x(), myMin.y(), myMax.z());
661 if (anAxesState & OYZ_XYZ)
663 renderLine (myAxes[0].Line, theWorkspace, aModelMatrix, myMin.x(), myMax.y(), myMax.z());
666 if (anAxesState & XOZ_XYZ)
668 renderLine (myAxes[1].Line, theWorkspace, aModelMatrix, myMax.x(), myMin.y(), myMax.z());
671 if (anAxesState & XYO_XYZ)
673 renderLine (myAxes[2].Line, theWorkspace, aModelMatrix, myMax.x(), myMax.y(), myMin.z());
676 for (Standard_Integer anIter = 0 ; anIter < 3; ++anIter)
678 renderGridPlane (theWorkspace, anIter, aGridAxes, aModelMatrix);
683 if (myData.ToDrawAxes())
685 for (Standard_Integer anIter = 0; anIter < 3; ++anIter)
687 renderAxis (theWorkspace, anIter, aModelMatrix);
691 // Names of axes & values
692 for (Standard_Integer anIter = 0; anIter < 3; ++anIter)
694 // Restore current matrix
695 aContext->WorldViewState.SetCurrent (aModelMatrix);
696 aContext->ApplyWorldViewMatrix();
697 renderTickmarkLabels (theWorkspace, aModelMatrix, anIter, aGridAxes, aDpix);
700 theWorkspace->SetAspects (anOldAspectLine);
702 aContext->WorldViewState.Pop();
703 aContext->ApplyWorldViewMatrix();
706 // =======================================================================
707 // method : SetMinMax
709 // =======================================================================
710 void OpenGl_GraduatedTrihedron::SetMinMax (const OpenGl_Vec3& theMin, const OpenGl_Vec3& theMax)
716 // =======================================================================
717 // method : OpenGl_GraduatedTrihedron::Axis constructor
719 // =======================================================================
720 OpenGl_GraduatedTrihedron::Axis::Axis (const Graphic3d_AxisAspect& theAspect,
721 const OpenGl_Vec3& theDirection)
722 : Direction (theDirection),
727 Handle(Graphic3d_Text) aText = new Graphic3d_Text (THE_LABEL_HEIGHT);
728 aText->SetText ((Standard_Utf16Char* )theAspect.Name().ToExtString());
729 aText->SetPosition (gp_Pnt (theDirection.x(), theDirection.y(), theDirection.z()));
730 aText->SetHorizontalAlignment (THE_LABEL_HALIGH);
731 aText->SetVerticalAlignment (THE_LABEL_VALIGH);
732 Label = OpenGl_Text (aText);
733 NameColor = theAspect.NameColor();
734 LineAspect.Aspect()->SetColor (theAspect.Color());
737 // =======================================================================
738 // method : OpenGl_GraduatedTrihedron::Axis::~Axis
740 // =======================================================================
741 OpenGl_GraduatedTrihedron::Axis::~Axis()
746 // =======================================================================
747 // method : OpenGl_GraduatedTrihedron::Axis operator=
749 // =======================================================================
750 OpenGl_GraduatedTrihedron::Axis& OpenGl_GraduatedTrihedron::Axis::operator= (const Axis& theOther)
752 Direction = theOther.Direction;
753 NameColor = theOther.NameColor;
754 LineAspect = theOther.LineAspect;
755 Label = theOther.Label;
757 Line .InitBuffers (NULL, Graphic3d_TOPA_SEGMENTS, theOther.Line.Indices(), theOther.Line.Attributes(), theOther.Line.Bounds());
758 Tickmark.InitBuffers (NULL, Graphic3d_TOPA_SEGMENTS, theOther.Tickmark.Indices(), theOther.Tickmark.Attributes(), theOther.Tickmark.Bounds());
759 Arrow .InitBuffers (NULL, Graphic3d_TOPA_POLYLINES, theOther.Arrow.Indices(), theOther.Arrow.Attributes(), theOther.Arrow.Bounds());
763 // =======================================================================
764 // method : InitArrow
766 // =======================================================================
767 void OpenGl_GraduatedTrihedron::Axis::InitArrow (const Handle(OpenGl_Context)& theContext,
768 const Standard_ShortReal theLength,
769 const OpenGl_Vec3& theNormal) const
771 // Draw from the end point of the aris
772 OpenGl_Vec3 aLengthVec = -Direction * theLength;
774 // Radial direction to the arrow
775 OpenGl_Vec3 aRadial = OpenGl_Vec3::Cross (this->Direction, theNormal);
776 if (aRadial.Modulus() < (Standard_ShortReal) Precision::Confusion())
780 aRadial = aRadial.Normalized() * theLength * 0.2f;
782 // Initialize arrow primitive array
783 // Make loop from polyline
784 const OpenGl_Vec3 aPoint1 = aRadial + aLengthVec;
785 const OpenGl_Vec3 aPoint2 (0.0f, 0.0f, 0.0f);
786 const OpenGl_Vec3 aPoint3 = -aRadial + aLengthVec;
788 Handle(Graphic3d_ArrayOfPolylines) anArray = new Graphic3d_ArrayOfPolylines (4);
789 anArray->AddVertex (aPoint1);
790 anArray->AddVertex (aPoint2);
791 anArray->AddVertex (aPoint3);
792 anArray->AddVertex (aPoint1);
794 Arrow.InitBuffers (theContext, Graphic3d_TOPA_POLYLINES,
795 anArray->Indices(), anArray->Attributes(), anArray->Bounds());
798 // =======================================================================
799 // function : InitTickmark
801 // =======================================================================
802 void OpenGl_GraduatedTrihedron::Axis::InitTickmark (const Handle(OpenGl_Context)& theContext,
803 const OpenGl_Vec3& theDir) const
806 Handle(Graphic3d_ArrayOfSegments) anArray = new Graphic3d_ArrayOfSegments (2);
807 anArray->AddVertex (0.0f, 0.0f, 0.0f);
808 anArray->AddVertex (theDir);
809 Tickmark.InitBuffers (theContext, Graphic3d_TOPA_SEGMENTS,
810 anArray->Indices(), anArray->Attributes(), anArray->Bounds());
814 // =======================================================================
815 // function : InitLine
817 // =======================================================================
818 void OpenGl_GraduatedTrihedron::Axis::InitLine (const Handle(OpenGl_Context)& theContext,
819 const OpenGl_Vec3& theDir) const
822 Handle(Graphic3d_ArrayOfSegments) anArray = new Graphic3d_ArrayOfSegments (2);
823 anArray->AddVertex (0.0f, 0.0f, 0.0f);
824 anArray->AddVertex (theDir);
826 Line.InitBuffers (theContext, Graphic3d_TOPA_SEGMENTS,
827 anArray->Indices(), anArray->Attributes(), anArray->Bounds());
830 // =======================================================================
831 // function : Release
833 // =======================================================================
834 void OpenGl_GraduatedTrihedron::Axis::Release (OpenGl_Context* theCtx)
836 Label .Release (theCtx);
837 Tickmark.Release (theCtx);
838 Line .Release (theCtx);
839 Arrow .Release (theCtx);