Increment OCCT version up to 7.4.0
[occt.git] / src / V3d / V3d_View.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
3bffef55 14#include <V3d_View.hxx>
7fd59977 15
42cf5bc1 16#include <Aspect_GradientBackground.hxx>
17#include <Aspect_Grid.hxx>
18#include <Aspect_Window.hxx>
19#include <Bnd_Box.hxx>
20#include <gp_Ax3.hxx>
7fd59977 21#include <gp_Dir.hxx>
b5ac8292 22#include <gp_Pln.hxx>
42cf5bc1 23#include <Graphic3d_AspectMarker3d.hxx>
24#include <Graphic3d_GraphicDriver.hxx>
25#include <Graphic3d_Group.hxx>
b5ac8292 26#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
27#include <Graphic3d_MapOfStructure.hxx>
42cf5bc1 28#include <Graphic3d_Structure.hxx>
b5ac8292 29#include <Graphic3d_TextureEnv.hxx>
42cf5bc1 30#include <Image_AlienPixMap.hxx>
3bffef55 31#include <Message.hxx>
32#include <Message_Messenger.hxx>
42cf5bc1 33#include <NCollection_Array1.hxx>
34#include <Precision.hxx>
35#include <Quantity_Color.hxx>
36#include <Standard_Assert.hxx>
37#include <Standard_DivideByZero.hxx>
38#include <Standard_ErrorHandler.hxx>
39#include <Standard_MultiplyDefined.hxx>
40#include <Standard_ShortReal.hxx>
41#include <Standard_Type.hxx>
42#include <Standard_TypeMismatch.hxx>
c357e426 43#include <TColgp_Array1OfPnt.hxx>
42cf5bc1 44#include <TColStd_Array2OfReal.hxx>
45#include <TColStd_HSequenceOfInteger.hxx>
46#include <V3d.hxx>
47#include <V3d_BadValue.hxx>
42cf5bc1 48#include <V3d_Light.hxx>
49#include <V3d_StereoDumpOptions.hxx>
50#include <V3d_UnMapped.hxx>
42cf5bc1 51#include <V3d_Viewer.hxx>
7fd59977 52
25e59720 53IMPLEMENT_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
92efcf78 54
c6541a0c 55#define DEUXPI (2. * M_PI)
7fd59977 56
4af098ba 57namespace
58{
59 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
60}
61
197ac94e 62//=============================================================================
63//function : Constructor
64//purpose :
65//=============================================================================
c357e426 66V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
49582f9d 67: myIsInvalidatedImmediate (Standard_True),
68 MyViewer (theViewer.operator->()),
c357e426 69 SwitchSetFront (Standard_False),
016e5959 70 myZRotation (Standard_False),
caf231b0 71 myTrihedron (new V3d_Trihedron()),
6bc6a6fc 72 MyTrsf (1, 4, 1, 4)
7fd59977 73{
c357e426 74 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
7fd59977 75
c357e426 76 myView->SetBackground (theViewer->GetBackgroundColor());
77 myView->SetGradientBackground (theViewer->GetGradientBackground());
7fd59977 78
832ae82d 79 ChangeRenderingParams() = theViewer->DefaultRenderingParams();
80
b5ac8292 81 // camera init
82 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
83 aCamera->SetFOVy (45.0);
84 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
85 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
c357e426 86 aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
87 ? Graphic3d_Camera::Projection_Orthographic
88 : Graphic3d_Camera::Projection_Perspective);
b5ac8292 89
c357e426 90 myDefaultCamera = new Graphic3d_Camera();
91
92 myImmediateUpdate = Standard_False;
c357e426 93 SetAutoZFitMode (Standard_True, 1.0);
94 SetBackFacingModel (V3d_TOBM_AUTOMATIC);
95 SetCamera (aCamera);
b5ac8292 96 SetAxis (0.,0.,0.,1.,1.,1.);
c357e426 97 SetVisualization (theViewer->DefaultVisualization());
98 SetShadingModel (theViewer->DefaultShadingModel());
b5ac8292 99 SetTwist (0.);
100 SetAt (0.,0.,0.);
c357e426 101 SetProj (theViewer->DefaultViewProj());
102 SetSize (theViewer->DefaultViewSize());
103 Standard_Real zsize = theViewer->DefaultViewSize();
b5ac8292 104 SetZSize (2.*zsize);
c357e426 105 SetDepth (theViewer->DefaultViewSize() / 2.0);
7fd59977 106 SetViewMappingDefault();
fc8eab5e 107 SetViewOrientationDefault();
c357e426 108 theViewer->AddView (this);
7fd59977 109 Init();
110 myImmediateUpdate = Standard_True;
7fd59977 111}
112
197ac94e 113//=============================================================================
114//function : Constructor
115//purpose :
116//=============================================================================
c357e426 117V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
49582f9d 118: myIsInvalidatedImmediate (Standard_True),
119 MyViewer (theViewer.operator->()),
197ac94e 120 SwitchSetFront(Standard_False),
016e5959 121 myZRotation (Standard_False),
197ac94e 122 MyTrsf (1, 4, 1, 4)
7fd59977 123{
c357e426 124 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
7fd59977 125
c357e426 126 myView->CopySettings (theView->View());
9e04ccdc 127 myDefaultViewPoint = theView->myDefaultViewPoint;
128 myDefaultViewAxis = theView->myDefaultViewAxis;
7fd59977 129
9e04ccdc 130 myDefaultCamera = new Graphic3d_Camera (theView->DefaultCamera());
b5ac8292 131
c357e426 132 myImmediateUpdate = Standard_False;
133 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
c357e426 134 theViewer->AddView (this);
7fd59977 135 Init();
136 myImmediateUpdate = Standard_True;
7fd59977 137}
138
197ac94e 139//=============================================================================
c357e426 140//function : Destructor
197ac94e 141//purpose :
142//=============================================================================
c357e426 143V3d_View::~V3d_View()
144{
145 if (!myView->IsRemoved())
146 {
147 myView->Remove();
7fd59977 148 }
7fd59977 149}
150
197ac94e 151//=============================================================================
c357e426 152//function : SetMagnify
197ac94e 153//purpose :
154//=============================================================================
c357e426 155void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
156 const Handle(V3d_View)& thePreviousView,
157 const Standard_Integer theX1,
158 const Standard_Integer theY1,
159 const Standard_Integer theX2,
160 const Standard_Integer theY2)
7fd59977 161{
c357e426 162 if (!myView->IsRemoved() && !myView->IsDefined())
163 {
164 Standard_Real aU1, aV1, aU2, aV2;
165 thePreviousView->Convert (theX1, theY1, aU1, aV1);
166 thePreviousView->Convert (theX2, theY2, aU2, aV2);
167 myView->SetWindow (theWindow);
434ffc09 168 FitAll (aU1, aV1, aU2, aV2);
c357e426 169 MyViewer->SetViewOn (this);
170 MyWindow = theWindow;
171 SetRatio();
172 Redraw();
173 SetViewMappingDefault();
174 }
7fd59977 175}
176
197ac94e 177//=============================================================================
178//function : SetWindow
179//purpose :
180//=============================================================================
a521d90d 181void V3d_View::SetWindow (const Handle(Aspect_Window)& theWindow,
182 const Aspect_RenderingContext theContext)
7fd59977 183{
c357e426 184 if (myView->IsRemoved())
185 {
186 return;
187 }
188
05e2200b 189 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
c357e426 190 MyWindow = theWindow;
a521d90d 191 myView->SetWindow (theWindow, theContext);
c357e426 192 MyViewer->SetViewOn (this);
193 SetRatio();
39235bed 194 if (myImmediateUpdate)
195 {
196 Redraw();
197 }
7fd59977 198}
7fd59977 199
197ac94e 200//=============================================================================
201//function : Remove
202//purpose :
203//=============================================================================
5e27df78 204void V3d_View::Remove() const
205{
475c2302 206 if (!MyGrid.IsNull())
207 {
208 MyGrid->Erase();
209 }
210 if (!myTrihedron.IsNull())
211 {
212 myTrihedron->Erase();
213 }
214
5e27df78 215 MyViewer->DelView (this);
c357e426 216 myView->Remove();
5e27df78 217 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
218 aWin.Nullify();
7fd59977 219}
220
197ac94e 221//=============================================================================
222//function : Update
223//purpose :
224//=============================================================================
b8ddfc2f 225void V3d_View::Update() const
226{
c357e426 227 if (!myView->IsDefined()
228 || !myView->IsActive())
229 {
230 return;
231 }
232
49582f9d 233 myIsInvalidatedImmediate = Standard_False;
cfece3ef 234 myView->Update();
235 myView->Compute();
236 myView->Redraw();
7fd59977 237}
238
197ac94e 239//=============================================================================
240//function : Redraw
241//purpose :
242//=============================================================================
b8ddfc2f 243void V3d_View::Redraw() const
244{
c357e426 245 if (!myView->IsDefined()
246 || !myView->IsActive())
247 {
248 return;
249 }
250
49582f9d 251 myIsInvalidatedImmediate = Standard_False;
c357e426 252 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
253 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
254 {
851dacdb 255 if (aStructureMgr->IsDeviceLost())
c357e426 256 {
257 aStructureMgr->RecomputeStructures();
c357e426 258 }
259
260 AutoZFit();
261
262 myView->Redraw();
263
851dacdb 264 if (!aStructureMgr->IsDeviceLost())
c357e426 265 {
266 return;
267 }
268 }
7fd59977 269}
b8ddfc2f 270
197ac94e 271//=============================================================================
679ecdee 272//function : RedrawImmediate
273//purpose :
274//=============================================================================
275void V3d_View::RedrawImmediate() const
276{
c357e426 277 if (!myView->IsDefined()
278 || !myView->IsActive())
679ecdee 279 {
c357e426 280 return;
679ecdee 281 }
c357e426 282
49582f9d 283 myIsInvalidatedImmediate = Standard_False;
c357e426 284 myView->RedrawImmediate();
679ecdee 285}
286
287//=============================================================================
288//function : Invalidate
289//purpose :
290//=============================================================================
291void V3d_View::Invalidate() const
292{
c357e426 293 if (!myView->IsDefined())
679ecdee 294 {
c357e426 295 return;
679ecdee 296 }
c357e426 297
298 myView->Invalidate();
679ecdee 299}
300
301//=============================================================================
62e1beed 302//function : IsInvalidated
303//purpose :
304//=============================================================================
305Standard_Boolean V3d_View::IsInvalidated() const
306{
c357e426 307 return !myView->IsDefined()
308 || myView->IsInvalidated();
62e1beed 309}
310
c357e426 311// ========================================================================
312// function : SetAutoZFitMode
313// purpose :
314// ========================================================================
315void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
316 const Standard_Real theScaleFactor)
317{
318 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
319 myAutoZFitScaleFactor = theScaleFactor;
320 myAutoZFitIsOn = theIsOn;
321}
322
6bc6a6fc 323//=============================================================================
c357e426 324//function : AutoZFit
6bc6a6fc 325//purpose :
326//=============================================================================
c357e426 327void V3d_View::AutoZFit() const
6bc6a6fc 328{
c357e426 329 if (!AutoZFitMode())
330 {
331 return;
332 }
333
334 ZFitAll (myAutoZFitScaleFactor);
6bc6a6fc 335}
336
337//=============================================================================
c357e426 338//function : ZFitAll
197ac94e 339//purpose :
340//=============================================================================
c357e426 341void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
7fd59977 342{
c357e426 343 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
344 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
345
346 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
7fd59977 347}
348
197ac94e 349//=============================================================================
350//function : IsEmpty
351//purpose :
352//=============================================================================
b8ddfc2f 353Standard_Boolean V3d_View::IsEmpty() const
354{
7fd59977 355 Standard_Boolean TheStatus = Standard_True ;
c357e426 356 if( myView->IsDefined() ) {
357 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
7fd59977 358 if( Nstruct > 0 ) TheStatus = Standard_False ;
359 }
360 return (TheStatus) ;
7fd59977 361}
362
197ac94e 363//=============================================================================
364//function : UpdateLights
365//purpose :
366//=============================================================================
b8ddfc2f 367void V3d_View::UpdateLights() const
368{
992ed6b3 369 Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
6a24c6de 370 for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
c357e426 371 {
992ed6b3 372 aLights->Add (anActiveLightIter.Value());
c357e426 373 }
c357e426 374 myView->SetLights (aLights);
7fd59977 375}
376
197ac94e 377//=============================================================================
378//function : DoMapping
379//purpose :
380//=============================================================================
b8ddfc2f 381void V3d_View::DoMapping()
382{
c357e426 383 if (!myView->IsDefined())
384 {
385 return;
7fd59977 386 }
c357e426 387
388 myView->Window()->DoMapping();
7fd59977 389}
390
197ac94e 391//=============================================================================
392//function : MustBeResized
393//purpose :
394//=============================================================================
b8ddfc2f 395void V3d_View::MustBeResized()
396{
c357e426 397 if (!myView->IsDefined())
398 {
399 return;
7fd59977 400 }
c357e426 401
402 myView->Resized();
403
404 SetRatio();
39235bed 405 if (myImmediateUpdate)
406 {
407 Redraw();
408 }
7fd59977 409}
410
197ac94e 411//=============================================================================
412//function : SetBackgroundColor
413//purpose :
414//=============================================================================
c357e426 415void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
416 const Standard_Real theV1,
417 const Standard_Real theV2,
418 const Standard_Real theV3)
7fd59977 419{
c357e426 420 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
421 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
422 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
7fd59977 423
c357e426 424 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
7fd59977 425}
426
197ac94e 427//=============================================================================
428//function : SetBackgroundColor
429//purpose :
430//=============================================================================
c357e426 431void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
7fd59977 432{
c357e426 433 myView->SetBackground (Aspect_Background (theColor));
434
435 if (myImmediateUpdate)
436 {
437 Redraw();
438 }
7fd59977 439}
7fd59977 440
197ac94e 441//=============================================================================
197ac94e 442//function : SetBgGradientColors
443//purpose :
444//=============================================================================
c357e426 445void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
446 const Quantity_Color& theColor2,
447 const Aspect_GradientFillMethod theFillStyle,
448 const Standard_Boolean theToUpdate)
7fd59977 449{
c357e426 450 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
451
452 myView->SetGradientBackground (aGradientBg);
453
454 if (myImmediateUpdate || theToUpdate)
455 {
456 Redraw();
457 }
7fd59977 458}
459
197ac94e 460//=============================================================================
197ac94e 461//function : SetBgGradientStyle
462//purpose :
463//=============================================================================
c357e426 464void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
7fd59977 465{
c357e426 466 Quantity_Color aColor1;
467 Quantity_Color aColor2;
468 GradientBackground().Colors (aColor1, aColor2);
469
470 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
7fd59977 471}
472
197ac94e 473//=============================================================================
474//function : SetBackgroundImage
475//purpose :
476//=============================================================================
c357e426 477void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
478 const Aspect_FillMethod theFillStyle,
479 const Standard_Boolean theToUpdate)
7fd59977 480{
c357e426 481 myView->SetBackgroundImage (theFileName);
482 myView->SetBackgroundImageStyle (theFillStyle);
483
484 if (myImmediateUpdate || theToUpdate)
485 {
486 Redraw();
487 }
7fd59977 488}
489
197ac94e 490//=============================================================================
491//function : SetBgImageStyle
492//purpose :
493//=============================================================================
c357e426 494void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
7fd59977 495{
c357e426 496 myView->SetBackgroundImageStyle (theFillStyle);
497
498 if (myImmediateUpdate || theToUpdate)
499 {
500 Redraw();
501 }
7fd59977 502}
503
197ac94e 504//=============================================================================
077a220c 505//function : SetBackgroundCubeMap
506//purpose :
507//=============================================================================
508void V3d_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
509 Standard_Boolean theToUpdate)
510{
511 myView->SetBackgroundCubeMap (theCubeMap);
512
513 if (myImmediateUpdate || theToUpdate)
514 {
515 Redraw();
516 }
517}
518
519//=============================================================================
197ac94e 520//function : SetAxis
521//purpose :
522//=============================================================================
21b2385f 523void V3d_View::SetAxis (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
524 const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
b8ddfc2f 525{
21b2385f 526 myDefaultViewPoint.SetCoord (theX, theY, theZ);
527 myDefaultViewAxis.SetCoord (theVx, theVy, theVz);
7fd59977 528}
529
197ac94e 530//=============================================================================
531//function : SetShadingModel
532//purpose :
533//=============================================================================
dc89236f 534void V3d_View::SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel)
b8ddfc2f 535{
dc89236f 536 myView->SetShadingModel (theShadingModel);
7fd59977 537}
538
197ac94e 539//=============================================================================
197ac94e 540//function : SetTextureEnv
541//purpose :
542//=============================================================================
c357e426 543void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
b8ddfc2f 544{
c357e426 545 myView->SetTextureEnv (theTexture);
546
547 if (myImmediateUpdate)
548 {
549 Redraw();
550 }
7fd59977 551}
552
197ac94e 553//=============================================================================
554//function : SetVisualization
555//purpose :
556//=============================================================================
c357e426 557void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
b8ddfc2f 558{
c357e426 559 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
560
561 if (myImmediateUpdate)
562 {
563 Redraw();
564 }
7fd59977 565}
566
197ac94e 567//=============================================================================
568//function : SetFront
569//purpose :
570//=============================================================================
b8ddfc2f 571void V3d_View::SetFront()
572{
7fd59977 573 gp_Ax3 a = MyViewer->PrivilegedPlane();
b5ac8292 574 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
7fd59977 575
576 a.Direction().Coord(vx,vy,vz);
577 a.YDirection().Coord(xu,yu,zu);
578 a.Location().Coord(xo,yo,zo);
579
c357e426 580 Handle(Graphic3d_Camera) aCamera = Camera();
581
582 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
583
7fd59977 584 if(SwitchSetFront)
c357e426 585 {
586 aCamera->SetDirection (gp_Dir (vx, vy, vz));
587 }
7fd59977 588 else
c357e426 589 {
590 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
591 }
592
593 aCamera->SetUp (gp_Dir (xu, yu, zu));
7fd59977 594
c357e426 595 AutoZFit();
7fd59977 596
b5ac8292 597 SwitchSetFront = !SwitchSetFront;
7fd59977 598
599 ImmediateUpdate();
7fd59977 600}
601
197ac94e 602//=============================================================================
603//function : Rotate
604//purpose :
605//=============================================================================
b5ac8292 606void V3d_View::Rotate (const Standard_Real ax,
607 const Standard_Real ay,
608 const Standard_Real az,
609 const Standard_Boolean Start)
b8ddfc2f 610{
b5ac8292 611 Standard_Real Ax = ax;
612 Standard_Real Ay = ay;
613 Standard_Real Az = az;
7fd59977 614
b5ac8292 615 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
616 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
617 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
618 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
619 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
620 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
621
c357e426 622 Handle(Graphic3d_Camera) aCamera = Camera();
623
b5ac8292 624 if (Start)
625 {
c357e426 626 myCamStartOpUp = aCamera->Up();
607e5e62 627 myCamStartOpDir = aCamera->Direction();
c357e426 628 myCamStartOpEye = aCamera->Eye();
629 myCamStartOpCenter = aCamera->Center();
b5ac8292 630 }
631
607e5e62 632 aCamera->SetUp (myCamStartOpUp);
633 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
634 aCamera->SetDirectionFromEye (myCamStartOpDir);
b5ac8292 635
636 // rotate camera around 3 initial axes
607e5e62 637 gp_Dir aBackDir = -myCamStartOpDir;
b5ac8292 638 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
639 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
640 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
641
642 gp_Trsf aRot[3], aTrsf;
643 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
644 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
645 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
646 aTrsf.Multiply (aRot[0]);
647 aTrsf.Multiply (aRot[1]);
648 aTrsf.Multiply (aRot[2]);
649
c357e426 650 aCamera->Transform (aTrsf);
b5ac8292 651
c357e426 652 AutoZFit();
7fd59977 653
7fd59977 654 ImmediateUpdate();
7fd59977 655}
656
197ac94e 657//=============================================================================
658//function : Rotate
659//purpose :
660//=============================================================================
7fd59977 661void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
662 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
663{
b5ac8292 664
7fd59977 665 Standard_Real Ax = ax ;
666 Standard_Real Ay = ay ;
667 Standard_Real Az = az ;
7fd59977 668
669 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
670 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
671 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
672 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
673 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
674 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
675
c357e426 676 Handle(Graphic3d_Camera) aCamera = Camera();
677
b5ac8292 678 if (Start)
679 {
680 myGravityReferencePoint.SetCoord (X, Y, Z);
c357e426 681 myCamStartOpUp = aCamera->Up();
607e5e62 682 myCamStartOpDir = aCamera->Direction();
c357e426 683 myCamStartOpEye = aCamera->Eye();
684 myCamStartOpCenter = aCamera->Center();
b5ac8292 685 }
686
687 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
688
607e5e62 689 aCamera->SetUp (myCamStartOpUp);
690 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
691 aCamera->SetDirectionFromEye (myCamStartOpDir);
b5ac8292 692
693 // rotate camera around 3 initial axes
694 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
695
c357e426 696 gp_Dir aZAxis (aCamera->Direction().Reversed());
697 gp_Dir aYAxis (aCamera->Up());
b5ac8292 698 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
699
700 gp_Trsf aRot[3], aTrsf;
701 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
702 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
703 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
704 aTrsf.Multiply (aRot[0]);
705 aTrsf.Multiply (aRot[1]);
706 aTrsf.Multiply (aRot[2]);
707
c357e426 708 aCamera->Transform (aTrsf);
b5ac8292 709
c357e426 710 AutoZFit();
b5ac8292 711
7fd59977 712 ImmediateUpdate();
7fd59977 713}
714
197ac94e 715//=============================================================================
716//function : Rotate
717//purpose :
718//=============================================================================
b8ddfc2f 719void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
720{
7fd59977 721 switch (Axe) {
722 case V3d_X :
723 Rotate(angle,0.,0.,Start);
724 break ;
725 case V3d_Y :
726 Rotate(0.,angle,0.,Start);
727 break ;
728 case V3d_Z :
729 Rotate(0.,0.,angle,Start);
730 break ;
731 }
7fd59977 732}
733
197ac94e 734//=============================================================================
735//function : Rotate
736//purpose :
737//=============================================================================
21b2385f 738void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
739 const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ, const Standard_Boolean theStart)
7fd59977 740{
21b2385f 741 Standard_Real anAngle = theAngle;
7fd59977 742
21b2385f 743 if (anAngle > 0.0) while (anAngle > DEUXPI) anAngle -= DEUXPI;
744 else if (anAngle < 0.0) while (anAngle < -DEUXPI) anAngle += DEUXPI;
7fd59977 745
c357e426 746 Handle(Graphic3d_Camera) aCamera = Camera();
747
21b2385f 748 if (theStart)
b5ac8292 749 {
21b2385f 750 myGravityReferencePoint.SetCoord (theX, theY, theZ);
c357e426 751 myCamStartOpUp = aCamera->Up();
607e5e62 752 myCamStartOpDir = aCamera->Direction();
c357e426 753 myCamStartOpEye = aCamera->Eye();
754 myCamStartOpCenter = aCamera->Center();
21b2385f 755 switch (theAxe)
756 {
757 case V3d_X: myViewAxis = gp::DX(); break;
758 case V3d_Y: myViewAxis = gp::DY(); break;
759 case V3d_Z: myViewAxis = gp::DZ(); break;
7fd59977 760 }
761 }
762
b5ac8292 763 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
764
607e5e62 765 aCamera->SetUp (myCamStartOpUp);
766 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
767 aCamera->SetDirectionFromEye (myCamStartOpDir);
b5ac8292 768
769 // rotate camera around passed axis
770 gp_Trsf aRotation;
771 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
21b2385f 772 gp_Dir aRAxis ((theAxe == V3d_X) ? 1.0 : 0.0,
773 (theAxe == V3d_Y) ? 1.0 : 0.0,
774 (theAxe == V3d_Z) ? 1.0 : 0.0);
b5ac8292 775
21b2385f 776 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), anAngle);
b5ac8292 777
c357e426 778 aCamera->Transform (aRotation);
779
780 AutoZFit();
b5ac8292 781
7fd59977 782 ImmediateUpdate();
7fd59977 783}
784
197ac94e 785//=============================================================================
786//function : Rotate
787//purpose :
788//=============================================================================
b8ddfc2f 789void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
790{
b5ac8292 791 Standard_Real Angle = angle;
7fd59977 792
793 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
794 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
795
c357e426 796 Handle(Graphic3d_Camera) aCamera = Camera();
797
607e5e62 798 if (Start)
799 {
c357e426 800 myCamStartOpUp = aCamera->Up();
607e5e62 801 myCamStartOpDir = aCamera->Direction();
c357e426 802 myCamStartOpEye = aCamera->Eye();
803 myCamStartOpCenter = aCamera->Center();
7fd59977 804 }
805
607e5e62 806 aCamera->SetUp (myCamStartOpUp);
807 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
808 aCamera->SetDirectionFromEye (myCamStartOpDir);
b5ac8292 809
810 gp_Trsf aRotation;
21b2385f 811 gp_Pnt aRCenter (myDefaultViewPoint);
812 gp_Dir aRAxis (myDefaultViewAxis);
b5ac8292 813 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
b5ac8292 814
c357e426 815 aCamera->Transform (aRotation);
816
817 AutoZFit();
b5ac8292 818
7fd59977 819 ImmediateUpdate();
7fd59977 820}
821
197ac94e 822//=============================================================================
823//function : Turn
824//purpose :
825//=============================================================================
7fd59977 826void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
827{
b5ac8292 828 Standard_Real Ax = ax;
829 Standard_Real Ay = ay;
830 Standard_Real Az = az;
7fd59977 831
832 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
833 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
834 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
835 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
836 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
837 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
838
c357e426 839 Handle(Graphic3d_Camera) aCamera = Camera();
840
607e5e62 841 if (Start)
842 {
c357e426 843 myCamStartOpUp = aCamera->Up();
607e5e62 844 myCamStartOpDir = aCamera->Direction();
c357e426 845 myCamStartOpEye = aCamera->Eye();
846 myCamStartOpCenter = aCamera->Center();
b5ac8292 847 }
848
607e5e62 849 aCamera->SetUp (myCamStartOpUp);
850 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
851 aCamera->SetDirectionFromEye (myCamStartOpDir);
b5ac8292 852
853 // rotate camera around 3 initial axes
c357e426 854 gp_Pnt aRCenter = aCamera->Eye();
855 gp_Dir aZAxis (aCamera->Direction().Reversed());
856 gp_Dir aYAxis (aCamera->Up());
b5ac8292 857 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
858
859 gp_Trsf aRot[3], aTrsf;
860 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
861 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
862 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
863 aTrsf.Multiply (aRot[0]);
864 aTrsf.Multiply (aRot[1]);
865 aTrsf.Multiply (aRot[2]);
866
c357e426 867 aCamera->Transform (aTrsf);
b5ac8292 868
c357e426 869 AutoZFit();
b5ac8292 870
871 ImmediateUpdate();
7fd59977 872}
873
197ac94e 874//=============================================================================
875//function : Turn
876//purpose :
877//=============================================================================
7fd59977 878void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
879{
7fd59977 880 switch (Axe) {
881 case V3d_X :
882 Turn(angle,0.,0.,Start);
883 break ;
884 case V3d_Y :
885 Turn(0.,angle,0.,Start);
886 break ;
887 case V3d_Z :
888 Turn(0.,0.,angle,Start);
889 break ;
890 }
891}
892
197ac94e 893//=============================================================================
894//function : Turn
895//purpose :
896//=============================================================================
b8ddfc2f 897void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
898{
7fd59977 899 Standard_Real Angle = angle ;
7fd59977 900
901 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
902 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
903
c357e426 904 Handle(Graphic3d_Camera) aCamera = Camera();
905
607e5e62 906 if (Start)
907 {
c357e426 908 myCamStartOpUp = aCamera->Up();
607e5e62 909 myCamStartOpDir = aCamera->Direction();
c357e426 910 myCamStartOpEye = aCamera->Eye();
911 myCamStartOpCenter = aCamera->Center();
b5ac8292 912 }
913
607e5e62 914 aCamera->SetUp (myCamStartOpUp);
915 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
916 aCamera->SetDirectionFromEye (myCamStartOpDir);
b5ac8292 917
b5ac8292 918 gp_Trsf aRotation;
c357e426 919 gp_Pnt aRCenter = aCamera->Eye();
21b2385f 920 gp_Dir aRAxis (myDefaultViewAxis);
b5ac8292 921 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
b5ac8292 922
c357e426 923 aCamera->Transform (aRotation);
924
925 AutoZFit();
b5ac8292 926
927 ImmediateUpdate();
7fd59977 928}
929
197ac94e 930//=============================================================================
931//function : SetTwist
932//purpose :
933//=============================================================================
b8ddfc2f 934void V3d_View::SetTwist(const Standard_Real angle)
935{
7fd59977 936 Standard_Real Angle = angle ;
7fd59977 937
938 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
939 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
940
c357e426 941 Handle(Graphic3d_Camera) aCamera = Camera();
942
21b2385f 943 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
944 if (!screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
945 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
946 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
947 {
948 throw V3d_BadValue ("V3d_ViewSetTwist, alignment of Eye,At,Up,");
7fd59977 949 }
b5ac8292 950
c357e426 951 gp_Pnt aRCenter = aCamera->Center();
952 gp_Dir aZAxis (aCamera->Direction().Reversed());
b5ac8292 953
954 gp_Trsf aTrsf;
955 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
956
21b2385f 957 aCamera->SetUp (gp_Dir (myYscreenAxis));
c357e426 958 aCamera->Transform (aTrsf);
b5ac8292 959
c357e426 960 AutoZFit();
7fd59977 961
7fd59977 962 ImmediateUpdate();
7fd59977 963}
964
197ac94e 965//=============================================================================
197ac94e 966//function : SetEye
967//purpose :
968//=============================================================================
969void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
970{
971 Standard_Real aTwistBefore = Twist();
7fd59977 972
197ac94e 973 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
b5ac8292 974
c357e426 975 Handle(Graphic3d_Camera) aCamera = Camera();
976
977 aCamera->SetEye (gp_Pnt (X, Y, Z));
978
197ac94e 979 SetTwist (aTwistBefore);
b5ac8292 980
c357e426 981 AutoZFit();
b5ac8292 982
197ac94e 983 SetImmediateUpdate (wasUpdateEnabled);
984
b5ac8292 985 ImmediateUpdate();
7fd59977 986}
987
197ac94e 988//=============================================================================
989//function : SetDepth
990//purpose :
991//=============================================================================
b8ddfc2f 992void V3d_View::SetDepth(const Standard_Real Depth)
993{
b5ac8292 994 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
7fd59977 995
c357e426 996 Handle(Graphic3d_Camera) aCamera = Camera();
997
7fd59977 998 if( Depth > 0. )
7fd59977 999 {
b5ac8292 1000 // Move eye using center (target) as anchor.
c357e426 1001 aCamera->SetDistance (Depth);
b5ac8292 1002 }
1003 else
197ac94e 1004 {
b5ac8292 1005 // Move the view ref point instead of the eye.
c357e426 1006 gp_Vec aDir (aCamera->Direction());
1007 gp_Pnt aCameraEye = aCamera->Eye();
197ac94e 1008 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1009
c357e426 1010 aCamera->SetCenter (aCameraCenter);
7fd59977 1011 }
7fd59977 1012
c357e426 1013 AutoZFit();
b5ac8292 1014
1015 ImmediateUpdate();
7fd59977 1016}
1017
197ac94e 1018//=============================================================================
1019//function : SetProj
1020//purpose :
1021//=============================================================================
7fd59977 1022void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1023{
6942f04a 1024 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
7fd59977 1025 "V3d_View::SetProj, null projection vector");
1026
197ac94e 1027 Standard_Real aTwistBefore = Twist();
b5ac8292 1028
197ac94e 1029 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
b5ac8292 1030
c357e426 1031 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
b5ac8292 1032
1521659a 1033 SetTwist(aTwistBefore);
b5ac8292 1034
c357e426 1035 AutoZFit();
b5ac8292 1036
197ac94e 1037 SetImmediateUpdate (wasUpdateEnabled);
1038
7fd59977 1039 ImmediateUpdate();
7fd59977 1040}
1041
197ac94e 1042//=============================================================================
1043//function : SetProj
1044//purpose :
1045//=============================================================================
fc552d84 1046void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
1047 const Standard_Boolean theIsYup)
b8ddfc2f 1048{
fc552d84 1049 Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
1050 if (theIsYup)
1051 {
1052 if (theOrientation == V3d_Ypos
1053 || theOrientation == V3d_Yneg)
1054 {
1055 anUp.SetValues (0.0, 0.0, -1.0);
1056 }
1057 }
1058 else
1059 {
1060 if (theOrientation == V3d_Zpos)
1061 {
1062 anUp.SetValues (0.0, 1.0, 0.0);
1063 }
1064 else if (theOrientation == V3d_Zneg)
1065 {
1066 anUp.SetValues (0.0, -1.0, 0.0);
1067 }
7fd59977 1068 }
b5ac8292 1069
fc552d84 1070 const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
197ac94e 1071
1072 // retain camera panning from origin when switching projection
fc552d84 1073 const Handle(Graphic3d_Camera)& aCamera = Camera();
1074 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
197ac94e 1075
607e5e62 1076 const Standard_Real aNewDist = aCamera->Eye().Distance (gp_Pnt (0, 0, 0));
1077 aCamera->SetEyeAndCenter (gp_XYZ (0, 0, 0) + aBck.XYZ() * aNewDist,
1078 gp_XYZ (0, 0, 0));
1079 aCamera->SetDirectionFromEye (-aBck);
fc552d84 1080 aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
c357e426 1081 aCamera->OrthogonalizeUp();
197ac94e 1082
fc552d84 1083 Panning (anOriginVCS.X(), anOriginVCS.Y());
b5ac8292 1084
c357e426 1085 AutoZFit();
b5ac8292 1086
7fd59977 1087 ImmediateUpdate();
7fd59977 1088}
1089
197ac94e 1090//=============================================================================
1091//function : SetAt
1092//purpose :
1093//=============================================================================
b8ddfc2f 1094void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1095{
197ac94e 1096 Standard_Real aTwistBefore = Twist();
b5ac8292 1097
197ac94e 1098 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
b5ac8292 1099
c357e426 1100 Camera()->SetCenter (gp_Pnt (X, Y, Z));
b5ac8292 1101
197ac94e 1102 SetTwist (aTwistBefore);
b5ac8292 1103
c357e426 1104 AutoZFit();
b5ac8292 1105
197ac94e 1106 SetImmediateUpdate (wasUpdateEnabled);
1107
7fd59977 1108 ImmediateUpdate();
7fd59977 1109}
1110
197ac94e 1111//=============================================================================
1112//function : SetUp
1113//purpose :
1114//=============================================================================
21b2385f 1115void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
b8ddfc2f 1116{
c357e426 1117 Handle(Graphic3d_Camera) aCamera = Camera();
1118
21b2385f 1119 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1120 const gp_Dir anUp (theVx, theVy, theVz);
1121 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1122 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1123 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1124 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1125 {
1126 throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
7fd59977 1127 }
b5ac8292 1128
21b2385f 1129 aCamera->SetUp (gp_Dir (myYscreenAxis));
197ac94e 1130
c357e426 1131 AutoZFit();
b5ac8292 1132
7fd59977 1133 ImmediateUpdate();
7fd59977 1134}
1135
197ac94e 1136//=============================================================================
1137//function : SetUp
1138//purpose :
1139//=============================================================================
21b2385f 1140void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
b8ddfc2f 1141{
c357e426 1142 Handle(Graphic3d_Camera) aCamera = Camera();
1143
21b2385f 1144 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1145 const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1146 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1147 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1148 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1149 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1150 {
1151 throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
7fd59977 1152 }
b5ac8292 1153
21b2385f 1154 aCamera->SetUp (gp_Dir (myYscreenAxis));
197ac94e 1155
c357e426 1156 AutoZFit();
7fd59977 1157
7fd59977 1158 ImmediateUpdate();
1159}
1160
197ac94e 1161//=============================================================================
1162//function : SetViewOrientationDefault
1163//purpose :
1164//=============================================================================
b8ddfc2f 1165void V3d_View::SetViewOrientationDefault()
1166{
c357e426 1167 myDefaultCamera->CopyOrientationData (Camera());
1168}
b5ac8292 1169
c357e426 1170//=======================================================================
1171//function : SetViewMappingDefault
1172//purpose :
1173//=======================================================================
1174void V3d_View::SetViewMappingDefault()
1175{
1176 myDefaultCamera->CopyMappingData (Camera());
7fd59977 1177}
1178
197ac94e 1179//=============================================================================
1180//function : ResetViewOrientation
1181//purpose :
1182//=============================================================================
b8ddfc2f 1183void V3d_View::ResetViewOrientation()
1184{
c357e426 1185 Camera()->CopyOrientationData (myDefaultCamera);
1186
1187 AutoZFit();
1188
1189 ImmediateUpdate();
1190}
1191
1192//=======================================================================
1193//function : ResetViewMapping
1194//purpose :
1195//=======================================================================
1196void V3d_View::ResetViewMapping()
1197{
1198 Camera()->CopyMappingData (myDefaultCamera);
1199
1200 AutoZFit();
b5ac8292 1201
7fd59977 1202 ImmediateUpdate();
1203}
1204
197ac94e 1205//=============================================================================
1206//function : Reset
1207//purpose :
1208//=============================================================================
c357e426 1209void V3d_View::Reset (const Standard_Boolean theToUpdate)
b8ddfc2f 1210{
c357e426 1211 Camera()->Copy (myDefaultCamera);
197ac94e 1212
c357e426 1213 AutoZFit();
7fd59977 1214
7fd59977 1215 SwitchSetFront = Standard_False;
b5ac8292 1216
c357e426 1217 if (myImmediateUpdate || theToUpdate)
1218 {
1219 Update();
1220 }
7fd59977 1221}
1222
197ac94e 1223//=======================================================================
1224//function : SetCenter
1225//purpose :
1226//=======================================================================
1227void V3d_View::SetCenter (const Standard_Integer theXp,
1228 const Standard_Integer theYp)
b8ddfc2f 1229{
197ac94e 1230 Standard_Real aXv, aYv;
1231 Convert (theXp, theYp, aXv, aYv);
c357e426 1232 Translate (Camera(), aXv, aYv);
7fd59977 1233
7fd59977 1234 ImmediateUpdate();
7fd59977 1235}
1236
197ac94e 1237//=============================================================================
1238//function : SetSize
1239//purpose :
1240//=============================================================================
3dfe95cd 1241void V3d_View::SetSize (const Standard_Real theSize)
7fd59977 1242{
3dfe95cd 1243 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
7fd59977 1244
c357e426 1245 Handle(Graphic3d_Camera) aCamera = Camera();
1246
1247 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
197ac94e 1248
c357e426 1249 AutoZFit();
7fd59977 1250
7fd59977 1251 ImmediateUpdate();
7fd59977 1252}
1253
197ac94e 1254//=============================================================================
1255//function : SetZSize
1256//purpose :
1257//=============================================================================
c357e426 1258void V3d_View::SetZSize (const Standard_Real theSize)
7fd59977 1259{
c357e426 1260 Handle(Graphic3d_Camera) aCamera = Camera();
7fd59977 1261
c357e426 1262 Standard_Real Zmax = theSize / 2.;
b5ac8292 1263
c357e426 1264 Standard_Real aDistance = aCamera->Distance();
1265
1266 if (theSize <= 0.)
1267 {
b5ac8292 1268 Zmax = aDistance;
7fd59977 1269 }
7fd59977 1270
197ac94e 1271 // ShortReal precision factor used to add meaningful tolerance to
1272 // ZNear, ZFar values in order to avoid equality after type conversion
1273 // to ShortReal matrices type.
1274 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1275
1276 Standard_Real aZFar = Zmax + aDistance * 2.0;
1277 Standard_Real aZNear = -Zmax + aDistance;
1278 aZNear -= Abs (aZNear) * aPrecision;
1279 aZFar += Abs (aZFar) * aPrecision;
1280
c357e426 1281 if (!aCamera->IsOrthographic())
197ac94e 1282 {
1283 if (aZFar < aPrecision)
1284 {
1285 // Invalid case when both values are negative
1286 aZNear = aPrecision;
1287 aZFar = aPrecision * 2.0;
1288 }
1289 else if (aZNear < Abs (aZFar) * aPrecision)
1290 {
1291 // Z is less than 0.0, try to fix it using any appropriate z-scale
1292 aZNear = Abs (aZFar) * aPrecision;
1293 }
1294 }
1295
1296 // If range is too small
1297 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1298 {
1299 aZFar = aZNear + Abs (aZFar) * aPrecision;
1300 }
1301
c357e426 1302 aCamera->SetZRange (aZNear, aZFar);
7fd59977 1303
c357e426 1304 if (myImmediateUpdate)
b8ddfc2f 1305 {
c357e426 1306 Redraw();
b8ddfc2f 1307 }
7fd59977 1308}
1309
197ac94e 1310//=============================================================================
1311//function : SetZoom
1312//purpose :
1313//=============================================================================
e44b0af4 1314void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
7fd59977 1315{
e44b0af4 1316 V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
7fd59977 1317
c357e426 1318 Handle(Graphic3d_Camera) aCamera = Camera();
1319
e44b0af4 1320 if (theToStart)
b5ac8292 1321 {
c357e426 1322 myCamStartOpEye = aCamera->Eye();
1323 myCamStartOpCenter = aCamera->Center();
7fd59977 1324 }
1325
c357e426 1326 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1327 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
b5ac8292 1328
7fd59977 1329 // ensure that zoom will not be too small or too big
e44b0af4 1330 Standard_Real aCoef = theCoef;
1331 if (aViewWidth < aCoef * Precision::Confusion())
b5ac8292 1332 {
e44b0af4 1333 aCoef = aViewWidth / Precision::Confusion();
b5ac8292 1334 }
e44b0af4 1335 else if (aViewWidth > aCoef * 1e12)
b5ac8292 1336 {
e44b0af4 1337 aCoef = aViewWidth / 1e12;
b5ac8292 1338 }
e44b0af4 1339 if (aViewHeight < aCoef * Precision::Confusion())
b5ac8292 1340 {
e44b0af4 1341 aCoef = aViewHeight / Precision::Confusion();
b5ac8292 1342 }
e44b0af4 1343 else if (aViewHeight > aCoef * 1e12)
b5ac8292 1344 {
e44b0af4 1345 aCoef = aViewHeight / 1e12;
b5ac8292 1346 }
1347
c357e426 1348 aCamera->SetEye (myCamStartOpEye);
1349 aCamera->SetCenter (myCamStartOpCenter);
e44b0af4 1350 aCamera->SetScale (aCamera->Scale() / aCoef);
c357e426 1351
1352 AutoZFit();
b5ac8292 1353
7fd59977 1354 ImmediateUpdate();
1355}
1356
197ac94e 1357//=============================================================================
1358//function : SetScale
1359//purpose :
1360//=============================================================================
b8ddfc2f 1361void V3d_View::SetScale( const Standard_Real Coef )
1362{
6942f04a 1363 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
7fd59977 1364
c357e426 1365 Handle(Graphic3d_Camera) aCamera = Camera();
b5ac8292 1366
c357e426 1367 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1368 aCamera->SetAspect (myDefaultCamera->Aspect());
1369 aCamera->SetScale (aDefaultScale / Coef);
b5ac8292 1370
c357e426 1371 AutoZFit();
b5ac8292 1372
7fd59977 1373 ImmediateUpdate();
7fd59977 1374}
1375
197ac94e 1376//=============================================================================
1377//function : SetAxialScale
1378//purpose :
1379//=============================================================================
b8ddfc2f 1380void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1381{
6942f04a 1382 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
7fd59977 1383
c357e426 1384 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1385
1386 AutoZFit();
1387}
1388
1389//=============================================================================
1390//function : SetRatio
1391//purpose :
1392//=============================================================================
1393void V3d_View::SetRatio()
1394{
1395 if (MyWindow.IsNull())
1396 {
1397 return;
1398 }
1399
1400 Standard_Integer aWidth = 0;
1401 Standard_Integer aHeight = 0;
1402 MyWindow->Size (aWidth, aHeight);
1403 if (aWidth > 0 && aHeight > 0)
1404 {
1405 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1406 static_cast<Standard_Real> (aHeight);
1407
1408 Camera() ->SetAspect (aRatio);
1409 myDefaultCamera->SetAspect (aRatio);
1410 }
7fd59977 1411}
1412
197ac94e 1413//=============================================================================
1414//function : FitAll
1415//purpose :
1416//=============================================================================
ee2be2a8 1417void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
7fd59977 1418{
c357e426 1419 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
b586500b 1420}
1421
1422//=============================================================================
1423//function : FitAll
1424//purpose :
1425//=============================================================================
ee2be2a8 1426void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
b586500b 1427{
1428 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
197ac94e 1429
c357e426 1430 if (myView->NumberOfDisplayedStructures() == 0)
197ac94e 1431 {
1432 return;
1433 }
35617823 1434
c357e426 1435 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
35617823 1436 {
35617823
K
1437 return;
1438 }
7fd59977 1439
c357e426 1440 AutoZFit();
b5ac8292 1441
197ac94e 1442 if (myImmediateUpdate || theToUpdate)
35617823 1443 {
b5ac8292 1444 Update();
35617823 1445 }
b5ac8292 1446}
35617823 1447
197ac94e 1448//=============================================================================
197ac94e 1449//function : DepthFitAll
1450//purpose :
1451//=============================================================================
ee2be2a8 1452void V3d_View::DepthFitAll(const Standard_Real Aspect,
1453 const Standard_Real Margin)
7fd59977 1454{
1455 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1456 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
b5ac8292 1457 Standard_Real Dx,Dy,Dz,Size;
7fd59977 1458
c357e426 1459 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
7fd59977 1460
b5ac8292 1461 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
7fd59977 1462 ImmediateUpdate();
1463 return ;
1464 }
1465
c357e426 1466 Bnd_Box aBox = myView->MinMaxValues();
ed063270 1467 if (aBox.IsVoid())
1468 {
1469 ImmediateUpdate();
1470 return ;
1471 }
1472 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
c357e426 1473 Project (Xmin,Ymin,Zmin,U,V,W) ;
1474 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
7fd59977 1475 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1476 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1477 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
c357e426 1478 Project (Xmin,Ymin,Zmax,U,V,W) ;
7fd59977 1479 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1480 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1481 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1482 Project (Xmax,Ymin,Zmax,U,V,W) ;
7fd59977 1483 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1484 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1485 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1486 Project (Xmax,Ymin,Zmin,U,V,W) ;
7fd59977 1487 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1488 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1489 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1490 Project (Xmax,Ymax,Zmin,U,V,W) ;
7fd59977 1491 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1492 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1493 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1494 Project (Xmin,Ymax,Zmax,U,V,W) ;
7fd59977 1495 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1496 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1497 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1498 Project (Xmin,Ymax,Zmin,U,V,W) ;
7fd59977 1499 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1500 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1501 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1502
1503 // Adjust Z size
1504 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1505 Dz = 2.*Wmax + Margin * Wmax;
1506
1507 // Compute depth value
1508 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1509 Dx += Margin * Dx; Dy += Margin * Dy;
1510 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1511 if( Size > 0. ) {
1512 SetZSize(Size) ;
1513 SetDepth( Aspect * Size / 2.);
1514 }
1515
1516 ImmediateUpdate();
1517}
1518
197ac94e 1519//=======================================================================
1520//function : WindowFit
1521//purpose :
1522//=======================================================================
1523void V3d_View::WindowFit (const Standard_Integer theMinXp,
1524 const Standard_Integer theMinYp,
1525 const Standard_Integer theMaxXp,
1526 const Standard_Integer theMaxYp)
b8ddfc2f 1527{
197ac94e 1528 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1529
c357e426 1530 Handle(Graphic3d_Camera) aCamera = Camera();
1531
1532 if (!aCamera->IsOrthographic())
b5ac8292 1533 {
ab1c121b 1534 // normalize view coordinates
b5ac8292 1535 Standard_Integer aWinWidth, aWinHeight;
1536 MyWindow->Size (aWinWidth, aWinHeight);
7fd59977 1537
b5ac8292 1538 // z coordinate of camera center
c357e426 1539 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
b5ac8292 1540
1541 // camera projection coordinate are in NDC which are normalized [-1, 1]
197ac94e 1542 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1543 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1544 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1545 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
b5ac8292 1546
1547 // compute camera panning
1548 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1549 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
c357e426 1550 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1551 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
b5ac8292 1552 gp_Vec aPanVec (aPanFrom, aPanTo);
1553
b5ac8292 1554 // compute section size
1555 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1556 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
c357e426 1557 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1558 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
b5ac8292 1559
1560 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1561 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1562
c357e426 1563 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1564 Scale (aCamera, aUSize, aVSize);
1565 AutoZFit();
b5ac8292 1566 }
1567 else
1568 {
197ac94e 1569 Standard_Real aX1, aY1, aX2, aY2;
1570 Convert (theMinXp, theMinYp, aX1, aY1);
1571 Convert (theMaxXp, theMaxYp, aX2, aY2);
1572 FitAll (aX1, aY1, aX2, aY2);
b5ac8292 1573 }
197ac94e 1574
1575 SetImmediateUpdate (wasUpdateEnabled);
1576
1577 ImmediateUpdate();
7fd59977 1578}
1579
197ac94e 1580//=======================================================================
197ac94e 1581//function : ConvertToGrid
1582//purpose :
1583//=======================================================================
1584void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1585 const Standard_Integer Yp,
1586 Standard_Real& Xg,
1587 Standard_Real& Yg,
1588 Standard_Real& Zg) const
b5ac8292 1589{
1590 Graphic3d_Vertex aVrp;
1591 Standard_Real anX, anY, aZ;
1592 Convert (Xp, Yp, anX, anY, aZ);
1593 aVrp.SetCoord (anX, anY, aZ);
1594
1595 if( MyViewer->Grid()->IsActive() ) {
1596 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1597 aNewVrp.Coord (Xg,Yg,Zg) ;
1598 } else
1599 aVrp.Coord (Xg,Yg,Zg) ;
1600}
1601
197ac94e 1602//=======================================================================
1603//function : ConvertToGrid
1604//purpose :
1605//=======================================================================
1606void V3d_View::ConvertToGrid(const Standard_Real X,
1607 const Standard_Real Y,
1608 const Standard_Real Z,
1609 Standard_Real& Xg,
1610 Standard_Real& Yg,
1611 Standard_Real& Zg) const
b5ac8292 1612{
1613 if( MyViewer->Grid()->IsActive() ) {
1614 Graphic3d_Vertex aVrp (X,Y,Z) ;
1615 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1616 aNewVrp.Coord(Xg,Yg,Zg) ;
1617 } else {
1618 Xg = X; Yg = Y; Zg = Z;
1619 }
1620}
1621
197ac94e 1622//=======================================================================
1623//function : Convert
1624//purpose :
1625//=======================================================================
b8ddfc2f 1626Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1627{
b5ac8292 1628 Standard_Integer aDxw, aDyw ;
7fd59977 1629
c357e426 1630 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
7fd59977 1631
b5ac8292 1632 MyWindow->Size (aDxw, aDyw);
1633 Standard_Real aValue;
197ac94e 1634
c357e426 1635 gp_Pnt aViewDims = Camera()->ViewDimensions();
b5ac8292 1636 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
7fd59977 1637
b5ac8292 1638 return aValue;
7fd59977 1639}
1640
197ac94e 1641//=======================================================================
1642//function : Convert
1643//purpose :
1644//=======================================================================
1645void V3d_View::Convert(const Standard_Integer Xp,
1646 const Standard_Integer Yp,
1647 Standard_Real& Xv,
1648 Standard_Real& Yv) const
b8ddfc2f 1649{
b5ac8292 1650 Standard_Integer aDxw, aDyw;
7fd59977 1651
c357e426 1652 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
b5ac8292 1653
1654 MyWindow->Size (aDxw, aDyw);
1655
1656 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
c357e426 1657 aPoint = Camera()->ConvertProj2View (aPoint);
7fd59977 1658
b5ac8292 1659 Xv = aPoint.X();
1660 Yv = aPoint.Y();
7fd59977 1661}
1662
197ac94e 1663//=======================================================================
1664//function : Convert
1665//purpose :
1666//=======================================================================
7fd59977 1667Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1668{
c357e426 1669 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
b5ac8292 1670
1671 Standard_Integer aDxw, aDyw;
1672 MyWindow->Size (aDxw, aDyw);
7fd59977 1673
c357e426 1674 gp_Pnt aViewDims = Camera()->ViewDimensions();
b5ac8292 1675 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
7fd59977 1676
b5ac8292 1677 return aValue;
7fd59977 1678}
1679
197ac94e 1680//=======================================================================
1681//function : Convert
1682//purpose :
1683//=======================================================================
1684void V3d_View::Convert(const Standard_Real Xv,
1685 const Standard_Real Yv,
1686 Standard_Integer& Xp,
1687 Standard_Integer& Yp) const
7fd59977 1688{
c357e426 1689 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
7fd59977 1690
b5ac8292 1691 Standard_Integer aDxw, aDyw;
1692 MyWindow->Size (aDxw, aDyw);
7fd59977 1693
b5ac8292 1694 gp_Pnt aPoint (Xv, Yv, 0.0);
c357e426 1695 aPoint = Camera()->ConvertView2Proj (aPoint);
b5ac8292 1696 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
7fd59977 1697
b5ac8292 1698 Xp = RealToInt (aPoint.X());
1699 Yp = RealToInt (aPoint.Y());
7fd59977 1700}
1701
197ac94e 1702//=======================================================================
1703//function : Convert
1704//purpose :
1705//=======================================================================
1706void V3d_View::Convert(const Standard_Integer Xp,
1707 const Standard_Integer Yp,
1708 Standard_Real& X,
1709 Standard_Real& Y,
1710 Standard_Real& Z) const
b8ddfc2f 1711{
c357e426 1712 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
b5ac8292 1713 Standard_Integer aHeight, aWidth;
1714 MyWindow->Size (aWidth, aHeight);
1715
1716 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1717 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1718 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1719
c357e426 1720 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
b5ac8292 1721
1722 X = aResult.X();
1723 Y = aResult.Y();
1724 Z = aResult.Z();
7fd59977 1725}
1726
197ac94e 1727//=======================================================================
1728//function : ConvertWithProj
1729//purpose :
1730//=======================================================================
3ed88fac 1731void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1732 const Standard_Integer theYp,
1733 Standard_Real& theX,
1734 Standard_Real& theY,
1735 Standard_Real& theZ,
1736 Standard_Real& theDx,
1737 Standard_Real& theDy,
1738 Standard_Real& theDz) const
7fd59977 1739{
c357e426 1740 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
3ed88fac 1741 Standard_Integer aHeight = 0, aWidth = 0;
b5ac8292 1742 MyWindow->Size (aWidth, aHeight);
7fd59977 1743
3ed88fac 1744 const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1745 const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1746 const Standard_Real aZ = 2.0 * 0.0 - 1.0;
b5ac8292 1747
3ed88fac 1748 const Handle(Graphic3d_Camera)& aCamera = Camera();
1749 const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1750 const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
b5ac8292 1751
3ed88fac 1752 theX = aResult1.X();
1753 theY = aResult1.Y();
1754 theZ = aResult1.Z();
1755 Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1756 theY - aResult2.Y(),
1757 theZ - aResult2.Z());
3910bc65 1758 aNormDir.Normalize();
1759
3ed88fac 1760 theDx = aNormDir.x();
1761 theDy = aNormDir.y();
1762 theDz = aNormDir.z();
7fd59977 1763}
7fd59977 1764
197ac94e 1765//=======================================================================
1766//function : Convert
1767//purpose :
1768//=======================================================================
1769void V3d_View::Convert(const Standard_Real X,
1770 const Standard_Real Y,
1771 const Standard_Real Z,
1772 Standard_Integer& Xp,
1773 Standard_Integer& Yp) const
b8ddfc2f 1774{
c357e426 1775 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
b5ac8292 1776 Standard_Integer aHeight, aWidth;
1777 MyWindow->Size (aWidth, aHeight);
1778
c357e426 1779 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
b5ac8292 1780
1781 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
72b11796 1782 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
7fd59977 1783}
1784
197ac94e 1785//=======================================================================
1786//function : Project
1787//purpose :
1788//=======================================================================
c357e426 1789void V3d_View::Project (const Standard_Real theX,
1790 const Standard_Real theY,
1791 const Standard_Real theZ,
1792 Standard_Real& theXp,
1793 Standard_Real& theYp) const
7fd59977 1794{
c357e426 1795 Standard_Real aZp;
1796 Project (theX, theY, theZ, theXp, theYp, aZp);
1797}
1798
1799//=======================================================================
1800//function : Project
1801//purpose :
1802//=======================================================================
1803void V3d_View::Project (const Standard_Real theX,
1804 const Standard_Real theY,
1805 const Standard_Real theZ,
1806 Standard_Real& theXp,
1807 Standard_Real& theYp,
1808 Standard_Real& theZp) const
1809{
1810 Handle(Graphic3d_Camera) aCamera = Camera();
1811
1812 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1813 Standard_Real aXSize = aViewSpaceDimensions.X();
1814 Standard_Real aYSize = aViewSpaceDimensions.Y();
1815 Standard_Real aZSize = aViewSpaceDimensions.Z();
1816
1817 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1818
1819 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1820 theXp = aPoint.X() * aXSize * 0.5;
1821 theYp = aPoint.Y() * aYSize * 0.5;
1822 theZp = aPoint.Z() * aZSize * 0.5;
7fd59977 1823}
1824
197ac94e 1825//=======================================================================
1826//function : BackgroundColor
1827//purpose :
1828//=======================================================================
1829void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1830 Standard_Real& V1,
1831 Standard_Real& V2,
1832 Standard_Real& V3) const
b8ddfc2f 1833{
7fd59977 1834 Quantity_Color C = BackgroundColor() ;
7fd59977 1835 C.Values(V1,V2,V3,Type) ;
1836}
1837
197ac94e 1838//=======================================================================
1839//function : BackgroundColor
1840//purpose :
1841//=======================================================================
b8ddfc2f 1842Quantity_Color V3d_View::BackgroundColor() const
1843{
c357e426 1844 return myView->Background().Color() ;
7fd59977 1845}
7fd59977 1846
197ac94e 1847//=======================================================================
1848//function : GradientBackgroundColors
1849//purpose :
1850//=======================================================================
c357e426 1851void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
b8ddfc2f 1852{
c357e426 1853 myView->GradientBackground().Colors (theColor1, theColor2);
7fd59977 1854}
1855
197ac94e 1856//=======================================================================
1857//function : GradientBackground
1858//purpose :
1859//=======================================================================
b8ddfc2f 1860Aspect_GradientBackground V3d_View::GradientBackground() const
1861{
c357e426 1862 return myView->GradientBackground();
7fd59977 1863}
1864
197ac94e 1865//=======================================================================
1866//function : Scale
1867//purpose :
1868//=======================================================================
b8ddfc2f 1869Standard_Real V3d_View::Scale() const
1870{
c357e426 1871 return myDefaultCamera->Scale() / Camera()->Scale();
7fd59977 1872}
1873
197ac94e 1874//=======================================================================
1875//function : AxialScale
1876//purpose :
1877//=======================================================================
b8ddfc2f 1878void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1879{
c357e426 1880 gp_Pnt anAxialScale = Camera()->AxialScale();
b5ac8292 1881 Sx = anAxialScale.X();
1882 Sy = anAxialScale.Y();
1883 Sz = anAxialScale.Z();
7fd59977 1884}
1885
197ac94e 1886//=======================================================================
1887//function : Size
1888//purpose :
1889//=======================================================================
b8ddfc2f 1890void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1891{
c357e426 1892 gp_Pnt aViewDims = Camera()->ViewDimensions();
7fd59977 1893
b5ac8292 1894 Width = aViewDims.X();
1895 Height = aViewDims.Y();
7fd59977 1896}
1897
197ac94e 1898//=======================================================================
1899//function : ZSize
1900//purpose :
1901//=======================================================================
b8ddfc2f 1902Standard_Real V3d_View::ZSize() const
1903{
c357e426 1904 gp_Pnt aViewDims = Camera()->ViewDimensions();
7fd59977 1905
b5ac8292 1906 return aViewDims.Z();
7fd59977 1907}
1908
197ac94e 1909//=======================================================================
1910//function : MinMax
1911//purpose :
1912//=======================================================================
1913Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1914 Standard_Real& Vmin,
1915 Standard_Real& Umax,
1916 Standard_Real& Vmax) const
b8ddfc2f 1917{
7fd59977 1918 Standard_Real Wmin,Wmax,U,V,W ;
1919 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1920 // CAL 6/11/98
c357e426 1921 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
7fd59977 1922
1923 if( Nstruct ) {
c357e426 1924 Bnd_Box aBox = myView->MinMaxValues();
ed063270 1925 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
c357e426 1926 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1927 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1928 Project (Xmin,Ymin,Zmax,U,V,W) ;
7fd59977 1929 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1930 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1931 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1932 Project (Xmax,Ymin,Zmax,U,V,W) ;
7fd59977 1933 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1934 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1935 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1936 Project (Xmax,Ymin,Zmin,U,V,W) ;
7fd59977 1937 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1938 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1939 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1940 Project (Xmax,Ymax,Zmin,U,V,W) ;
7fd59977 1941 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1942 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1943 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1944 Project (Xmin,Ymax,Zmax,U,V,W) ;
7fd59977 1945 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1946 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1947 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
c357e426 1948 Project (Xmin,Ymax,Zmin,U,V,W) ;
7fd59977 1949 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1950 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1951 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1952 }
1953 return Nstruct ;
1954}
1955
197ac94e 1956//=======================================================================
1957//function : MinMax
1958//purpose :
1959//=======================================================================
1960Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1961 Standard_Real& Ymin,
1962 Standard_Real& Zmin,
1963 Standard_Real& Xmax,
1964 Standard_Real& Ymax,
1965 Standard_Real& Zmax) const
b8ddfc2f 1966{
7fd59977 1967 // CAL 6/11/98
1968 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
c357e426 1969 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
7fd59977 1970
1971 if( Nstruct ) {
c357e426 1972 Bnd_Box aBox = myView->MinMaxValues();
ed063270 1973 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
7fd59977 1974 }
1975 return Nstruct ;
1976}
1977
197ac94e 1978//=======================================================================
49582f9d 1979//function : GravityPoint
197ac94e 1980//purpose :
1981//=======================================================================
49582f9d 1982gp_Pnt V3d_View::GravityPoint() const
b8ddfc2f 1983{
4af098ba 1984 Graphic3d_MapOfStructure aSetOfStructures;
c357e426 1985 myView->DisplayedStructures (aSetOfStructures);
4af098ba 1986
1987 Standard_Boolean hasSelection = Standard_False;
1988 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1989 aStructIter.More(); aStructIter.Next())
1990 {
1991 if (aStructIter.Key()->IsHighlighted()
1992 && aStructIter.Key()->IsVisible())
1993 {
1994 hasSelection = Standard_True;
1995 break;
1996 }
1997 }
7fd59977 1998
4af098ba 1999 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2000 Standard_Integer aNbPoints = 0;
2001 gp_XYZ aResult (0.0, 0.0, 0.0);
2002 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2003 aStructIter.More(); aStructIter.Next())
2004 {
2005 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2006 if (!aStruct->IsVisible()
770fa4d4 2007 || aStruct->IsInfinite()
2008 || (hasSelection && !aStruct->IsHighlighted()))
4af098ba 2009 {
2010 continue;
2011 }
2012
7c3ef2f7 2013 const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
770fa4d4 2014 if (!aBox.IsValid())
2015 {
2016 continue;
2017 }
2018
2019 // skip transformation-persistent objects
778cd667 2020 if (!aStruct->TransformPersistence().IsNull())
4af098ba 2021 {
2022 continue;
2023 }
2024
2025 // use camera projection to find gravity point
7c3ef2f7 2026 Xmin = aBox.CornerMin().x();
2027 Ymin = aBox.CornerMin().y();
2028 Zmin = aBox.CornerMin().z();
2029 Xmax = aBox.CornerMax().x();
2030 Ymax = aBox.CornerMax().y();
2031 Zmax = aBox.CornerMax().z();
4af098ba 2032 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2033 {
2034 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2035 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2036 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2037 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2038 };
7fd59977 2039
4af098ba 2040 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2041 {
2042 const gp_Pnt& aBndPnt = aPnts[aPntIt];
c357e426 2043 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
4af098ba 2044 if (Abs (aProjected.X()) <= 1.0
2045 && Abs (aProjected.Y()) <= 1.0)
2046 {
2047 aResult += aBndPnt.XYZ();
2048 ++aNbPoints;
2049 }
2050 }
2051 }
7fd59977 2052
4af098ba 2053 if (aNbPoints == 0)
b5ac8292 2054 {
770fa4d4 2055 // fallback - just use bounding box of entire scene
3fe9ce0e 2056 Bnd_Box aBox = myView->MinMaxValues();
770fa4d4 2057 if (!aBox.IsVoid())
b5ac8292 2058 {
4af098ba 2059 aBox.Get (Xmin, Ymin, Zmin,
2060 Xmax, Ymax, Zmax);
2061 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2062 {
b5ac8292 2063 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2064 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2065 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
4af098ba 2066 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2067 };
b5ac8292 2068
4af098ba 2069 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
b5ac8292 2070 {
2071 const gp_Pnt& aBndPnt = aPnts[aPntIt];
4af098ba 2072 aResult += aBndPnt.XYZ();
2073 ++aNbPoints;
b5ac8292 2074 }
7fd59977 2075 }
2076 }
7fd59977 2077
4af098ba 2078 if (aNbPoints > 0)
2079 {
2080 aResult /= aNbPoints;
2081 }
49582f9d 2082
2083 return aResult;
7fd59977 2084}
2085
197ac94e 2086//=======================================================================
2087//function : Eye
2088//purpose :
2089//=======================================================================
b8ddfc2f 2090void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2091{
c357e426 2092 gp_Pnt aCameraEye = Camera()->Eye();
b5ac8292 2093 X = aCameraEye.X();
2094 Y = aCameraEye.Y();
2095 Z = aCameraEye.Z();
7fd59977 2096}
2097
197ac94e 2098//=============================================================================
197ac94e 2099//function : ProjReferenceAxe
2100//purpose :
2101//=============================================================================
2102void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2103 const Standard_Integer Ypix,
2104 Standard_Real& XP,
2105 Standard_Real& YP,
2106 Standard_Real& ZP,
2107 Standard_Real& VX,
2108 Standard_Real& VY,
2109 Standard_Real& VZ) const
b8ddfc2f 2110{
7fd59977 2111 Standard_Real Xo,Yo,Zo;
2112
b5ac8292 2113 Convert (Xpix, Ypix, XP, YP, ZP);
2114 if ( Type() == V3d_PERSPECTIVE )
2115 {
2116 FocalReferencePoint (Xo,Yo,Zo);
7fd59977 2117 VX = Xo - XP;
2118 VY = Yo - YP;
2119 VZ = Zo - ZP;
2120 }
b5ac8292 2121 else
2122 {
2123 Proj (VX,VY,VZ);
7fd59977 2124 }
2125}
2126
197ac94e 2127//=============================================================================
2128//function : Depth
2129//purpose :
2130//=============================================================================
b8ddfc2f 2131Standard_Real V3d_View::Depth() const
2132{
c357e426 2133 return Camera()->Distance();
7fd59977 2134}
2135
197ac94e 2136//=============================================================================
2137//function : Proj
2138//purpose :
2139//=============================================================================
b8ddfc2f 2140void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2141{
c357e426 2142 gp_Dir aCameraDir = Camera()->Direction().Reversed();
b5ac8292 2143 Dx = aCameraDir.X();
2144 Dy = aCameraDir.Y();
2145 Dz = aCameraDir.Z();
7fd59977 2146}
2147
197ac94e 2148//=============================================================================
2149//function : At
2150//purpose :
2151//=============================================================================
b8ddfc2f 2152void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2153{
c357e426 2154 gp_Pnt aCameraCenter = Camera()->Center();
b5ac8292 2155 X = aCameraCenter.X();
2156 Y = aCameraCenter.Y();
2157 Z = aCameraCenter.Z();
7fd59977 2158}
2159
197ac94e 2160//=============================================================================
2161//function : Up
2162//purpose :
2163//=============================================================================
b8ddfc2f 2164void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2165{
c357e426 2166 gp_Dir aCameraUp = Camera()->Up();
b5ac8292 2167 Vx = aCameraUp.X();
2168 Vy = aCameraUp.Y();
2169 Vz = aCameraUp.Z();
7fd59977 2170}
2171
197ac94e 2172//=============================================================================
2173//function : Twist
2174//purpose :
2175//=============================================================================
b8ddfc2f 2176Standard_Real V3d_View::Twist() const
2177{
21b2385f 2178 gp_Vec Xaxis, Yaxis, Zaxis;
2179 const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2180 if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2181 && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2182 && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2183 {
2184 //
2185 }
7fd59977 2186
21b2385f 2187 // Compute Cross Vector From Up & Origin
2188 const gp_Dir aCameraUp = Camera()->Up();
2189 const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
b5ac8292 2190
21b2385f 2191 // compute Angle
2192 Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2193 if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2194 {
2195 anAngle = M_PI - anAngle;
7fd59977 2196 }
21b2385f 2197 if (anAngle > 0.0
2198 && anAngle < M_PI)
2199 {
2200 const gp_Dir aProjDir = Camera()->Direction().Reversed();
2201 if (aP.Dot (aProjDir.XYZ()) < 0.0)
2202 {
2203 anAngle = DEUXPI - anAngle;
2204 }
7fd59977 2205 }
21b2385f 2206 return anAngle;
7fd59977 2207}
2208
197ac94e 2209//=============================================================================
2210//function : ShadingModel
2211//purpose :
2212//=============================================================================
dc89236f 2213Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
b8ddfc2f 2214{
dc89236f 2215 return myView->ShadingModel();
7fd59977 2216}
2217
197ac94e 2218//=============================================================================
197ac94e 2219//function : TextureEnv
2220//purpose :
2221//=============================================================================
857ffd5e 2222Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
b8ddfc2f 2223{
c357e426 2224 return myView->TextureEnv();
7fd59977 2225}
2226
197ac94e 2227//=============================================================================
2228//function : Visualization
2229//purpose :
2230//=============================================================================
b8ddfc2f 2231V3d_TypeOfVisualization V3d_View::Visualization() const
2232{
c357e426 2233 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
7fd59977 2234}
2235
197ac94e 2236//=============================================================================
197ac94e 2237//function : IfWindow
2238//purpose :
2239//=============================================================================
b8ddfc2f 2240Standard_Boolean V3d_View::IfWindow() const
2241{
c357e426 2242 return myView->IsDefined();
7fd59977 2243}
2244
197ac94e 2245//=============================================================================
197ac94e 2246//function : Type
2247//purpose :
2248//=============================================================================
b8ddfc2f 2249V3d_TypeOfView V3d_View::Type() const
2250{
c357e426 2251 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
7fd59977 2252}
2253
197ac94e 2254//=============================================================================
2255//function : SetFocale
2256//purpose :
2257//=============================================================================
b8ddfc2f 2258void V3d_View::SetFocale( const Standard_Real focale )
2259{
c357e426 2260 Handle(Graphic3d_Camera) aCamera = Camera();
2261
2262 if (aCamera->IsOrthographic())
b5ac8292 2263 {
2264 return;
7fd59977 2265 }
b5ac8292 2266
c357e426 2267 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
b5ac8292 2268
c357e426 2269 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
7fd59977 2270
2271 ImmediateUpdate();
2272}
2273
197ac94e 2274//=============================================================================
2275//function : Focale
2276//purpose :
2277//=============================================================================
b5ac8292 2278Standard_Real V3d_View::Focale() const
b8ddfc2f 2279{
c357e426 2280 Handle(Graphic3d_Camera) aCamera = Camera();
2281
2282 if (aCamera->IsOrthographic())
b5ac8292 2283 {
2284 return 0.0;
7fd59977 2285 }
b5ac8292 2286
c357e426 2287 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
7fd59977 2288}
2289
197ac94e 2290//=============================================================================
21b2385f 2291//function : screenAxis
197ac94e 2292//purpose :
2293//=============================================================================
21b2385f 2294Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2295 gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
b5ac8292 2296{
21b2385f 2297 theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2298 if (theXaxe.Magnitude() <= gp::Resolution())
2299 {
2300 return Standard_False;
2301 }
2302 theXaxe.Normalize();
b5ac8292 2303
21b2385f 2304 theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2305 if (theYaxe.Magnitude() <= gp::Resolution())
2306 {
2307 return Standard_False;
2308 }
2309 theYaxe.Normalize();
b5ac8292 2310
21b2385f 2311 theZaxe = theVpn.XYZ();
2312 theZaxe.Normalize();
7fd59977 2313 return Standard_True;
2314}
2315
197ac94e 2316//=============================================================================
2317//function : TrsPoint
2318//purpose :
2319//=============================================================================
475c2302 2320gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
b8ddfc2f 2321{
7fd59977 2322 // CAL. S3892
475c2302 2323 const Standard_Integer lr = theMat.LowerRow();
2324 const Standard_Integer ur = theMat.UpperRow();
2325 const Standard_Integer lc = theMat.LowerCol();
2326 const Standard_Integer uc = theMat.UpperCol();
2327 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2328 {
2329 return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2330 }
2331
2332 Standard_Real X, Y, Z;
2333 thePnt.Coord (X,Y,Z);
2334 const Standard_Real XX = (theMat(lr,lc+3) + X*theMat(lr,lc) + Y*theMat(lr,lc+1) + Z*theMat(lr,lc+2)) / theMat(lr+3,lc+3);
2335 const Standard_Real YY = (theMat(lr+1,lc+3) + X*theMat(lr+1,lc) + Y*theMat(lr+1,lc+1) + Z*theMat(lr+1,lc+2))/theMat(lr+3,lc+3);
2336 const Standard_Real ZZ = (theMat(lr+2,lc+3) + X*theMat(lr+2,lc) + Y*theMat(lr+2,lc+1) + Z*theMat(lr+2,lc+2))/theMat(lr+3,lc+3);
2337 return gp_XYZ (XX, YY, ZZ);
7fd59977 2338}
2339
197ac94e 2340//=======================================================================
2341//function : Pan
2342//purpose :
2343//=======================================================================
2344void V3d_View::Pan (const Standard_Integer theDXp,
2345 const Standard_Integer theDYp,
ee2be2a8 2346 const Standard_Real theZoomFactor,
197ac94e 2347 const Standard_Boolean theToStart)
b8ddfc2f 2348{
197ac94e 2349 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
7fd59977 2350}
2351
197ac94e 2352//=======================================================================
2353//function : Panning
2354//purpose :
2355//=======================================================================
2356void V3d_View::Panning (const Standard_Real theDXv,
2357 const Standard_Real theDYv,
ee2be2a8 2358 const Standard_Real theZoomFactor,
197ac94e 2359 const Standard_Boolean theToStart)
7fd59977 2360{
197ac94e 2361 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
7fd59977 2362
c357e426 2363 Handle(Graphic3d_Camera) aCamera = Camera();
2364
197ac94e 2365 if (theToStart)
2366 {
607e5e62 2367 myCamStartOpDir = aCamera->Direction();
c357e426 2368 myCamStartOpEye = aCamera->Eye();
2369 myCamStartOpCenter = aCamera->Center();
7fd59977 2370 }
197ac94e 2371
2372 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2373
c357e426 2374 gp_Pnt aViewDims = aCamera->ViewDimensions();
197ac94e 2375
607e5e62 2376 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
2377 aCamera->SetDirectionFromEye (myCamStartOpDir);
c357e426 2378 Translate (aCamera, -theDXv, -theDYv);
2379 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
197ac94e 2380
2381 SetImmediateUpdate (wasUpdateEnabled);
2382
2383 ImmediateUpdate();
7fd59977 2384}
2385
197ac94e 2386//=======================================================================
2387//function : Zoom
2388//purpose :
2389//=======================================================================
2390void V3d_View::Zoom (const Standard_Integer theXp1,
2391 const Standard_Integer theYp1,
2392 const Standard_Integer theXp2,
2393 const Standard_Integer theYp2)
2394{
2395 Standard_Integer aDx = theXp2 - theXp1;
2396 Standard_Integer aDy = theYp2 - theYp1;
2397 if (aDx != 0 || aDy != 0)
2398 {
2399 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2400 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2401 SetZoom (aCoeff, Standard_True);
2402 }
7fd59977 2403}
2404
197ac94e 2405//=======================================================================
2406//function : StartZoomAtPoint
2407//purpose :
2408//=======================================================================
2409void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2410 const Standard_Integer theYp)
7fd59977 2411{
197ac94e 2412 MyZoomAtPointX = theXp;
2413 MyZoomAtPointY = theYp;
7fd59977 2414}
2415
197ac94e 2416//=======================================================================
2417//function : ZoomAtPoint
2418//purpose :
2419//=======================================================================
2420void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2421 const Standard_Integer theMouseStartY,
2422 const Standard_Integer theMouseEndX,
2423 const Standard_Integer theMouseEndY)
7fd59977 2424{
197ac94e 2425 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
7fd59977 2426
197ac94e 2427 // zoom
2428 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2429 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2430 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
7fd59977 2431
197ac94e 2432 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
7fd59977 2433
c357e426 2434 Handle(Graphic3d_Camera) aCamera = Camera();
2435
2436 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2437 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
7fd59977 2438
197ac94e 2439 // ensure that zoom will not be too small or too big.
2440 Standard_Real aCoef = aDZoom;
2441 if (aViewWidth < aCoef * Precision::Confusion())
2442 {
2443 aCoef = aViewWidth / Precision::Confusion();
2444 }
2445 else if (aViewWidth > aCoef * 1e12)
2446 {
2447 aCoef = aViewWidth / 1e12;
2448 }
2449 if (aViewHeight < aCoef * Precision::Confusion())
2450 {
2451 aCoef = aViewHeight / Precision::Confusion();
2452 }
2453 else if (aViewHeight > aCoef * 1e12)
2454 {
2455 aCoef = aViewHeight / 1e12;
2456 }
7fd59977 2457
197ac94e 2458 Standard_Real aZoomAtPointXv = 0.0;
2459 Standard_Real aZoomAtPointYv = 0.0;
2460 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
7fd59977 2461
ee2be2a8 2462 Standard_Real aDxv = aZoomAtPointXv / aCoef;
2463 Standard_Real aDyv = aZoomAtPointYv / aCoef;
7fd59977 2464
c357e426 2465 aCamera->SetScale (aCamera->Scale() / aCoef);
2466 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
b5ac8292 2467
c357e426 2468 AutoZFit();
b5ac8292 2469
197ac94e 2470 SetImmediateUpdate (wasUpdateEnabled);
7fd59977 2471
197ac94e 2472 ImmediateUpdate();
7fd59977 2473}
2474
197ac94e 2475//=============================================================================
2476//function : AxialScale
2477//purpose :
2478//=============================================================================
7fd59977 2479void V3d_View::AxialScale (const Standard_Integer Dx,
2480 const Standard_Integer Dy,
2481 const V3d_TypeOfAxe Axis)
2482{
2483 if( Dx != 0. || Dy != 0. ) {
2484 Standard_Real Sx, Sy, Sz;
2485 AxialScale( Sx, Sy, Sz );
2486 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2487 dscale = (Dx > 0) ? dscale : 1./dscale;
2488 if( Axis == V3d_X ) Sx = dscale;
2489 if( Axis == V3d_Y ) Sy = dscale;
2490 if( Axis == V3d_Z ) Sz = dscale;
2491 SetAxialScale( Sx, Sy, Sz );
2492 }
2493}
2494
197ac94e 2495//=============================================================================
2496//function : FitAll
2497//purpose :
2498//=============================================================================
434ffc09 2499void V3d_View::FitAll(const Standard_Real theXmin,
2500 const Standard_Real theYmin,
2501 const Standard_Real theXmax,
2502 const Standard_Real theYmax)
7fd59977 2503{
434ffc09 2504 Handle(Graphic3d_Camera) aCamera = Camera();
2505 Standard_Real anAspect = aCamera->Aspect();
7fd59977 2506
434ffc09 2507 Standard_Real aFitSizeU = Abs (theXmax - theXmin);
2508 Standard_Real aFitSizeV = Abs (theYmax - theYmin);
197ac94e 2509 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
434ffc09 2510 if (aFitAspect >= anAspect)
197ac94e 2511 {
434ffc09 2512 aFitSizeV = aFitSizeU / anAspect;
197ac94e 2513 }
2514 else
2515 {
434ffc09 2516 aFitSizeU = aFitSizeV * anAspect;
197ac94e 2517 }
b5ac8292 2518
434ffc09 2519 Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
c357e426 2520 Scale (aCamera, aFitSizeU, aFitSizeV);
2521
2522 AutoZFit();
7fd59977 2523
197ac94e 2524 ImmediateUpdate();
7fd59977 2525}
2526
197ac94e 2527//=============================================================================
2528//function : StartRotation
2529//purpose :
2530//=============================================================================
7fd59977 2531void V3d_View::StartRotation(const Standard_Integer X,
2532 const Standard_Integer Y,
ee2be2a8 2533 const Standard_Real zRotationThreshold)
7fd59977 2534{
7fd59977 2535 sx = X; sy = Y;
2536 Standard_Real x,y;
2537 Size(x,y);
2538 rx = Standard_Real(Convert(x));
2539 ry = Standard_Real(Convert(y));
49582f9d 2540 myRotateGravity = GravityPoint();
2541 Rotate (0.0, 0.0, 0.0,
2542 myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2543 Standard_True);
016e5959 2544 myZRotation = Standard_False;
7fd59977 2545 if( zRotationThreshold > 0. ) {
2546 Standard_Real dx = Abs(sx - rx/2.);
2547 Standard_Real dy = Abs(sy - ry/2.);
016e5959 2548 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
7fd59977 2549 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
016e5959 2550 if( dx > dd || dy > dd ) myZRotation = Standard_True;
7fd59977 2551 }
7fd59977 2552
2553}
2554
197ac94e 2555//=============================================================================
2556//function : Rotation
2557//purpose :
2558//=============================================================================
7fd59977 2559void V3d_View::Rotation(const Standard_Integer X,
2560 const Standard_Integer Y)
2561{
7fd59977 2562 if( rx == 0. || ry == 0. ) {
2563 StartRotation(X,Y);
2564 return;
2565 }
7fd59977 2566 Standard_Real dx=0.,dy=0.,dz=0.;
016e5959 2567 if( myZRotation ) {
7fd59977 2568 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2569 atan2(sx-rx/2.,ry/2.-sy);
2570 } else {
c6541a0c
D
2571 dx = (Standard_Real(X) - sx) * M_PI / rx;
2572 dy = (sy - Standard_Real(Y)) * M_PI / ry;
7fd59977 2573 }
b12a3e54 2574
49582f9d 2575 Rotate (dx, dy, dz,
2576 myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2577 Standard_False);
7fd59977 2578}
2579
197ac94e 2580//=============================================================================
2581//function : SetComputedMode
2582//purpose :
2583//=============================================================================
c357e426 2584void V3d_View::SetComputedMode (const Standard_Boolean theMode)
7fd59977 2585{
c357e426 2586 if (theMode)
197ac94e 2587 {
2588 if (myComputedMode)
2589 {
c357e426 2590 myView->SetComputedMode (Standard_True);
7fd59977 2591 }
c357e426 2592 }
2593 else
197ac94e 2594 {
c357e426 2595 myView->SetComputedMode (Standard_False);
7fd59977 2596 }
b8ddfc2f 2597}
7fd59977 2598
197ac94e 2599//=============================================================================
2600//function : ComputedMode
2601//purpose :
2602//=============================================================================
2603Standard_Boolean V3d_View::ComputedMode() const
7fd59977 2604{
c357e426 2605 return myView->ComputedMode();
b8ddfc2f 2606}
7fd59977 2607
197ac94e 2608//=============================================================================
2609//function : SetBackFacingModel
2610//purpose :
2611//=============================================================================
c357e426 2612void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
7fd59977 2613{
c357e426 2614 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
7fd59977 2615 Redraw();
b8ddfc2f 2616}
7fd59977 2617
197ac94e 2618//=============================================================================
2619//function : BackFacingModel
2620//purpose :
2621//=============================================================================
2622V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
b8ddfc2f 2623{
c357e426 2624 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
b8ddfc2f 2625}
7fd59977 2626
c357e426 2627//=============================================================================
2628//function : Init
2629//purpose :
2630//=============================================================================
b8ddfc2f 2631void V3d_View::Init()
2632{
7fd59977 2633 myComputedMode = MyViewer->ComputedMode();
c357e426 2634 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2635 {
2636 SetComputedMode (Standard_False);
7fd59977 2637 }
7fd59977 2638}
2639
197ac94e 2640//=============================================================================
197ac94e 2641//function : Dump
2642//purpose :
2643//=============================================================================
692613e5 2644Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2645 const Graphic3d_BufferType& theBufferType)
7fd59977 2646{
2647 Standard_Integer aWinWidth, aWinHeight;
2648 MyWindow->Size (aWinWidth, aWinHeight);
692613e5 2649 Image_AlienPixMap anImage;
b5ac8292 2650
692613e5 2651 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
7fd59977 2652}
2653
197ac94e 2654//=============================================================================
2655//function : ToPixMap
2656//purpose :
2657//=============================================================================
692613e5 2658Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
3bffef55 2659 const V3d_ImageDumpOptions& theParams)
7fd59977 2660{
3bffef55 2661 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2662 if (aTargetSize.x() != 0
2663 && aTargetSize.y() != 0)
2664 {
2665 // allocate image buffer for dumping
2666 if (theImage.IsEmpty()
2667 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2668 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2669 {
dc858f4c 2670 Image_Format aFormat = Image_Format_UNKNOWN;
3bffef55 2671 switch (theParams.BufferType)
2672 {
38d90bb3 2673 case Graphic3d_BT_RGB: aFormat = Image_Format_RGB; break;
2674 case Graphic3d_BT_RGBA: aFormat = Image_Format_RGBA; break;
2675 case Graphic3d_BT_Depth: aFormat = Image_Format_GrayF; break;
2676 case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF; break;
3bffef55 2677 }
2678
2679 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2680 {
2681 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2682 + " for view dump", Message_Fail);
2683 return Standard_False;
2684 }
2685 }
2686 }
2687 if (theImage.IsEmpty())
2688 {
2689 Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2690 return Standard_False;
2691 }
2692 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2693 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2694
b128c892 2695 Handle(Standard_Transient) aFBOPtr;
2696 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
3bffef55 2697 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2698
2699 bool isTiling = false;
2700 if (theParams.TileSize > 0)
2701 {
2702 if (aFBOVPSize.x() > theParams.TileSize
2703 || aFBOVPSize.y() > theParams.TileSize)
2704 {
2705 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2706 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2707 isTiling = true;
2708 }
2709 }
2710
2711 Graphic3d_Vec2i aPrevFBOVPSize;
b128c892 2712 if (!aPrevFBOPtr.IsNull())
7fd59977 2713 {
3bffef55 2714 Graphic3d_Vec2i aPrevFBOSizeMax;
c357e426 2715 myView->FBOGetDimensions (aPrevFBOPtr,
3bffef55 2716 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2717 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2718 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2719 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
7fd59977 2720 {
7fd59977 2721 aFBOPtr = aPrevFBOPtr;
2722 }
2723 }
2724
b128c892 2725 if (aFBOPtr.IsNull())
7fd59977 2726 {
6997ff1c 2727 Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX);
2728 Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY);
2729 if (theParams.TileSize > aMaxTexSizeX
2730 || theParams.TileSize > aMaxTexSizeY)
85e096c3 2731 {
3bffef55 2732 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
6997ff1c 2733 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Fail);
3bffef55 2734 return Standard_False;
85e096c3 2735 }
3bffef55 2736
6997ff1c 2737 if (aFBOVPSize.x() > aMaxTexSizeX
2738 || aFBOVPSize.y() > aMaxTexSizeY)
3bffef55 2739 {
6997ff1c 2740 if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO))
2741 {
2742 Message::DefaultMessenger ()->Send (TCollection_AsciiString ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applyed."), Message_Warning);
2743 }
2744 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Info, tiling image dump is used, image size (")
2745 + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Info);
2746 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX);
2747 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY);
3bffef55 2748 isTiling = true;
2749 }
2750
2751 // Try to create hardware accelerated buffer
2752 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
7fd59977 2753 }
c357e426 2754 myView->SetFBO (aFBOPtr);
7fd59977 2755
b128c892 2756 if (aFBOPtr.IsNull())
7fd59977 2757 {
3bffef55 2758 // try to use on-screen buffer
2759 Graphic3d_Vec2i aWinSize;
2760 MyWindow->Size (aWinSize.x(), aWinSize.y());
2761 if (aFBOVPSize.x() != aWinSize.x()
2762 || aFBOVPSize.y() != aWinSize.y())
7fd59977 2763 {
3bffef55 2764 isTiling = true;
7fd59977 2765 }
3bffef55 2766 aFBOVPSize = aWinSize;
2767
2768 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
7fd59977 2769 }
2770
3bffef55 2771 // backup camera parameters
b5ac8292 2772 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
c357e426 2773 Handle(Graphic3d_Camera) aCamera = Camera();
c357e426 2774 aStoreMapping->Copy (aCamera);
c357e426 2775 if (aCamera->IsStereo())
b5ac8292 2776 {
3bffef55 2777 switch (theParams.StereoOptions)
b5ac8292 2778 {
f978241f 2779 case V3d_SDO_MONO:
2780 {
c357e426 2781 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
b5ac8292 2782 break;
f978241f 2783 }
2784 case V3d_SDO_LEFT_EYE:
2785 {
c357e426 2786 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
b5ac8292 2787 break;
f978241f 2788 }
2789 case V3d_SDO_RIGHT_EYE:
2790 {
c357e426 2791 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
b5ac8292 2792 break;
f978241f 2793 }
2794 case V3d_SDO_BLENDED:
2795 {
2796 break; // dump as is
2797 }
b5ac8292 2798 }
2799 }
3bffef55 2800 if (theParams.ToAdjustAspect)
197ac94e 2801 {
3bffef55 2802 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
7fd59977 2803 }
3bffef55 2804 AutoZFit();
7fd59977 2805
3bffef55 2806 // render immediate structures into back buffer rather than front
2807 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
7fd59977 2808
692613e5 2809 Standard_Boolean isSuccess = Standard_True;
3bffef55 2810 if (!isTiling)
7fd59977 2811 {
3bffef55 2812 if (!aFBOPtr.IsNull())
692613e5 2813 {
3bffef55 2814 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
692613e5 2815 }
3bffef55 2816 Redraw();
2817 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2818 }
2819 else
2820 {
2821 Image_PixMap aTilePixMap;
2822 aTilePixMap.SetTopDown (theImage.IsTopDown());
692613e5 2823
3bffef55 2824 Graphic3d_Vec2i anOffset (0, 0);
2825 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2826 {
2827 anOffset.x() = 0;
2828 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2829 {
c8fe0e2d 2830 Graphic3d_CameraTile aTileUncropped;
2831 aTileUncropped.Offset = anOffset;
2832 aTileUncropped.TotalSize = aTargetSize;
2833 aTileUncropped.TileSize = aFBOVPSize;
2834 const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
3bffef55 2835 if (aTile.TileSize.x() < 1
2836 || aTile.TileSize.y() < 1)
2837 {
2838 continue;
2839 }
2840
2841 const Standard_Integer aLeft = aTile.Offset.x();
2842 Standard_Integer aBottom = aTile.Offset.y();
2843 if (theImage.IsTopDown())
2844 {
2845 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2846 aBottom = aTargetSize.y() - aTop;
2847 }
2848 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2849 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2850 aTile.TileSize.x(), aTile.TileSize.y(),
2851 theImage.SizeRowBytes());
2852
3bffef55 2853 if (!aFBOPtr.IsNull())
2854 {
c8fe0e2d 2855 aCamera->SetTile (aTile);
3bffef55 2856 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2857 }
c8fe0e2d 2858 else
2859 {
2860 // no API to resize viewport of on-screen buffer - render uncropped
2861 aCamera->SetTile (aTileUncropped);
2862 }
3bffef55 2863 Redraw();
2864 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2865 if (!isSuccess)
2866 {
2867 break;
2868 }
2869 }
2870 if (!isSuccess)
2871 {
2872 break;
2873 }
2874 }
7fd59977 2875 }
2876
3bffef55 2877 // restore state
2878 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2879 aCamera->Copy (aStoreMapping);
7fd59977 2880 if (aFBOPtr != aPrevFBOPtr)
2881 {
c357e426 2882 myView->FBORelease (aFBOPtr);
7fd59977 2883 }
b128c892 2884 else if (!aPrevFBOPtr.IsNull())
7fd59977 2885 {
3bffef55 2886 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
7fd59977 2887 }
c357e426 2888 myView->SetFBO (aPrevFBOPtr);
692613e5 2889 return isSuccess;
7fd59977 2890}
6942f04a 2891
c357e426 2892//=============================================================================
2893//function : ImmediateUpdate
2894//purpose :
2895//=============================================================================
6942f04a 2896void V3d_View::ImmediateUpdate() const
2897{
c357e426 2898 if (myImmediateUpdate)
2899 {
2900 Update();
2901 }
6942f04a 2902}
2903
c357e426 2904//=============================================================================
2905//function : SetImmediateUpdate
2906//purpose :
2907//=============================================================================
6942f04a 2908Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2909{
2910 Standard_Boolean aPreviousMode = myImmediateUpdate;
2911 myImmediateUpdate = theImmediateUpdate;
2912 return aPreviousMode;
2913}
b5ac8292 2914
2915// =======================================================================
2916// function : SetCamera
2917// purpose :
2918// =======================================================================
2919void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2920{
c357e426 2921 myView->SetCamera (theCamera);
197ac94e 2922
c357e426 2923 ImmediateUpdate();
b5ac8292 2924}
2925
2926// =======================================================================
2927// function : GetCamera
2928// purpose :
2929// =======================================================================
197ac94e 2930const Handle(Graphic3d_Camera)& V3d_View::Camera() const
b5ac8292 2931{
c357e426 2932 return myView->Camera();
b5ac8292 2933}
2934
2935// =======================================================================
197ac94e 2936// function : FitMinMax
2937// purpose : Internal
b5ac8292 2938// =======================================================================
197ac94e 2939Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
ed063270 2940 const Bnd_Box& theBox,
197ac94e 2941 const Standard_Real theMargin,
2942 const Standard_Real theResolution,
2943 const Standard_Boolean theToEnlargeIfLine) const
2944{
2945 // Check bounding box for validness
ed063270 2946 if (theBox.IsVoid())
b5ac8292 2947 {
197ac94e 2948 return Standard_False; // bounding box is out of bounds...
2949 }
2950
2951 // Apply "axial scaling" to the bounding points.
2952 // It is not the best approach to make this scaling as a part of fit all operation,
2953 // but the axial scale is integrated into camera orientation matrix and the other
2954 // option is to perform frustum plane adjustment algorithm in view camera space,
2955 // which will lead to a number of additional world-view space conversions and
2956 // loosing precision as well.
ab1c121b 2957 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
2958 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
2959
2960 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
b5ac8292 2961 {
197ac94e 2962 return Standard_False; // nothing to fit all
2963 }
2964
ab1c121b 2965 // Prepare camera frustum planes.
2966 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
2967 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
2968 aFrustumPlane.ChangeValue (2),
2969 aFrustumPlane.ChangeValue (3),
2970 aFrustumPlane.ChangeValue (4),
2971 aFrustumPlane.ChangeValue (5),
2972 aFrustumPlane.ChangeValue (6));
197ac94e 2973
ab1c121b 2974 // Prepare camera up, side, direction vectors.
197ac94e 2975 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
2976 gp_Dir aCamDir = theCamera->Direction();
2977 gp_Dir aCamSide = aCamDir ^ aCamUp;
2978
ab1c121b 2979 // Prepare scene bounding box parameters.
2980 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
2981
2982 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
2983 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
2984 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
2985 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
2986 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
2987 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
2988 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
2989 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
2990 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
2991
197ac94e 2992 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
2993 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
2994 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
2995 // set up perspective-correct camera projection matching the bounding box.
2996 // These steps support non-asymmetric transformations of view-projection space provided by camera.
2997 // The zooming can be done by calculating view plane size matching the bounding box at center of
2998 // the bounding box. The only limitation here is that the scale of camera should define size of
2999 // its view plane passing through the camera center, and the center of camera should be on the
3000 // same line with the center of bounding box.
3001
3002 // The following method is applied:
3003 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3004 // 2) Determine new location of frustum planes, "matching" the bounding box.
3005 // 3) Determine new camera projection vector using the normalized asymmetry.
3006 // 4) Determine new zooming in view space.
3007
ab1c121b 3008 // 1. Determine normalized projection asymmetry (if any).
bf02aa7d 3009 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
3010 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
3011 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
3012 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
ab1c121b 3013
3014 // 2. Determine how far should be the frustum planes placed from center
3015 // of bounding box, in order to match the bounding box closely.
3016 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3017 aFitDistance.ChangeValue (1) = 0.0;
3018 aFitDistance.ChangeValue (2) = 0.0;
3019 aFitDistance.ChangeValue (3) = 0.0;
3020 aFitDistance.ChangeValue (4) = 0.0;
3021 aFitDistance.ChangeValue (5) = 0.0;
3022 aFitDistance.ChangeValue (6) = 0.0;
3023
3024 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
197ac94e 3025 {
ab1c121b 3026 // Measure distances from center of bounding box to its corners towards the frustum plane.
3027 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
197ac94e 3028
ab1c121b 3029 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
197ac94e 3030
ab1c121b 3031 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3032 {
3033 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3034 }
197ac94e 3035 }
3036 // The center of camera is placed on the same line with center of bounding box.
3037 // The view plane section crosses the bounding box at its center.
3038 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3039 // into view section size between the point and the frustum plane.
3040 // proj
3041 // /|\ right half of frame //
3042 // | //
3043 // point o<-- distance * coeff -->//---- (view plane section)
3044 // \ //
3045 // (distance) //
3046 // ~ //
3047 // (distance) //
3048 // \/\//
3049 // \//
3050 // //
3051 // (frustum plane)
bf02aa7d 3052 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3053 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3054 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3055 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3056 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3057 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
ab1c121b 3058
3059 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3060 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3061 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3062
3063 // 3. Place center of camera on the same line with center of bounding
3064 // box applying corresponding projection asymmetry (if any).
197ac94e 3065 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3066 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
ab1c121b 3067 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3068 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
197ac94e 3069 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3070 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
ab1c121b 3071 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
197ac94e 3072
3073 gp_Trsf aCenterTrsf;
ab1c121b 3074 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
197ac94e 3075 theCamera->Transform (aCenterTrsf);
ab1c121b 3076 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
197ac94e 3077
3078 // Bounding box collapses to a point or thin line going in depth of the screen
3079 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
b5ac8292 3080 {
197ac94e 3081 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3082 {
3083 return Standard_True; // This is just one point or line and zooming has no effect.
3084 }
3085
3086 // Looking along line and "theToEnlargeIfLine" is requested.
3087 // Fit view to see whole scene on rotation.
3088 aViewSizeXv = aViewSizeZv;
3089 aViewSizeYv = aViewSizeZv;
b5ac8292 3090 }
3091
50d06d8f 3092 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3093
3094 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3095
3096 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
b5ac8292 3097
197ac94e 3098 return Standard_True;
b5ac8292 3099}
3100
3101// =======================================================================
197ac94e 3102// function : Scale
3103// purpose : Internal
b5ac8292 3104// =======================================================================
197ac94e 3105void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3106 const Standard_Real theSizeXv,
3107 const Standard_Real theSizeYv) const
b5ac8292 3108{
197ac94e 3109 Standard_Real anAspect = theCamera->Aspect();
ab1c121b 3110 if (anAspect > 1.0)
3111 {
3112 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3113 }
3114 else
3115 {
3116 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3117 }
b5ac8292 3118}
3119
3120// =======================================================================
197ac94e 3121// function : Translate
3122// purpose : Internal
b5ac8292 3123// =======================================================================
197ac94e 3124void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3125 const Standard_Real theDXv,
3126 const Standard_Real theDYv) const
3127{
3128 const gp_Pnt& aCenter = theCamera->Center();
3129 const gp_Dir& aDir = theCamera->Direction();
3130 const gp_Dir& anUp = theCamera->Up();
3131 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3132
3133 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3134 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3135 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3136 gp_Trsf aPanTrsf;
3137 aPanTrsf.SetTranslation (aCameraPan);
3138
3139 theCamera->Transform (aPanTrsf);
b5ac8292 3140}
b7cd4ba7 3141
3142// =======================================================================
26d9c835 3143// function : DiagnosticInformation
3144// purpose :
3145// =======================================================================
3146void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3147 Graphic3d_DiagnosticInfo theFlags) const
3148{
3149 myView->DiagnosticInformation (theDict, theFlags);
3150}
ebc369da 3151
79b544e6 3152//=======================================================================
3153//function : StatisticInformation
3154//purpose :
3155//=======================================================================
3156void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
3157{
3158 myView->StatisticInformation (theDict);
3159}
3160
3161// =======================================================================
3162// function : StatisticInformation
3163// purpose :
3164// =======================================================================
3165TCollection_AsciiString V3d_View::StatisticInformation() const
3166{
3167 return myView->StatisticInformation();
3168}
3169
ebc369da 3170//=============================================================================
3171//function : RenderingParams
3172//purpose :
3173//=============================================================================
3174const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3175{
3176 return myView->RenderingParams();
3177}
3178
3179//=============================================================================
3180//function : ChangeRenderingParams
3181//purpose :
3182//=============================================================================
3183Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3184{
3185 return myView->ChangeRenderingParams();
3186}