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