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