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