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