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