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