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