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