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