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