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