1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0024996: Visualization - newly displayed objects are clipped until first

camera movement

AutoZFit operation now may be applied on Visual3d_View level.
Visual3d_View tracks Graphic3d_Structure updates and call AutoZFit within
Visual3d_View::Redraw if necessary.
In order to get AutoZFit functionality on Visual3d_View level ZfitAll
method moved from V3d_View into Graphic3d_Camera. AutoZFit method and
AutoZFitMode flag now part of Visual3d_View.

Test case for issue CR24996
This commit is contained in:
duv 2014-07-17 13:46:53 +04:00 committed by bugmaster
parent 9dba391d4c
commit 6bc6a6fc07
11 changed files with 480 additions and 339 deletions

View File

@ -966,3 +966,173 @@ void Graphic3d_Camera::LookOrientation (const NCollection_Vec3<Elem_t>& theEye,
theOutMx.Multiply (anAxialScaleMx);
}
//=============================================================================
//function : ZFitAll
//purpose :
//=============================================================================
void Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB)
{
Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
// Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
// by their real boundaries (computed ignoring infinite flag) into the viewing volume.
// In addition to the graphical boundaries, the usual min max used for fitting perspective
// camera. To avoid numeric errors for perspective camera the negative ZNear values are
// fixed using tolerance distance, relative to boundaries size. The tolerance distance
// should be computed using information on boundaries of primary application actors,
// (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
Standard_Real aMinMax[6]; // applicative min max boundaries
theMinMax.Get (aMinMax[0], aMinMax[1], aMinMax[2], aMinMax[3], aMinMax[4], aMinMax[5]);
Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
theGraphicBB.Get (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2], aGraphicBB[3], aGraphicBB[4], aGraphicBB[5]);
// Check if anything can be adjusted
Standard_Real aLim = (ShortRealLast() - 1.0);
if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
{
// ShortReal precision factor used to add meaningful tolerance to
// ZNear, ZFar values in order to avoid equality after type conversion
// to ShortReal matrices type.
const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
Standard_Real aZFar = Distance() * 3.0;
Standard_Real aZNear = 0.0;
if (!IsOrthographic())
{
if (aZFar < aPrecision)
{
// Invalid case when both values are negative
aZNear = aPrecision;
aZFar = aPrecision * 2.0;
}
else if (aZNear < Abs (aZFar) * aPrecision)
{
// Z is less than 0.0, try to fix it using any appropriate z-scale
aZNear = Abs (aZFar) * aPrecision;
}
}
SetZRange (aZNear, aZFar);
return;
}
// Measure depth of boundary points from camera eye
gp_Pnt aPntsToMeasure[16] =
{
gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
};
// Camera eye plane
gp_Dir aCamDir = Direction();
gp_Pnt aCamEye = myEye;
gp_Pln aCamPln (aCamEye, aCamDir);
Standard_Real aModelMinDist = RealLast();
Standard_Real aModelMaxDist = RealFirst();
Standard_Real aGraphicMinDist = RealLast();
Standard_Real aGraphicMaxDist = RealFirst();
const gp_XYZ& anAxialScale = myAxialScale;
// Get minimum and maximum distances to the eye plane
for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
{
gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
{
continue;
}
aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
aMeasurePnt.Y() * anAxialScale.Y(),
aMeasurePnt.Z() * anAxialScale.Z());
Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
// Check if the camera is intruded into the scene
if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
{
aDistance *= -1;
}
Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
aChangeMinDist = Min (aDistance, aChangeMinDist);
aChangeMaxDist = Max (aDistance, aChangeMaxDist);
}
// Compute depth of bounding box center
Standard_Real aMidDepth = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
// ShortReal precision factor used to add meaningful tolerance to
// ZNear, ZFar values in order to avoid equality after type conversion
// to ShortReal matrices type.
const Standard_Real aPrecision = Pow (0.1, ShortRealDigits() - 2);
// Compute enlarged or shrank near and far z ranges
Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
aZNear -= aPrecision * 0.5;
aZFar += aPrecision * 0.5;
if (!IsOrthographic())
{
if (aZFar >= aPrecision)
{
// To avoid numeric errors... (See comments in the beginning of the method).
// Choose between model distance and graphical distance, as the model boundaries
// might be infinite if all structures have infinite flag.
const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
? aGraphicMaxDist - aGraphicMinDist : RealLast();
const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
? aModelMaxDist - aModelMinDist : RealLast();
const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
const Standard_Real aZTolerance =
Max (Abs (aMinDepth) * aPrecision, aPrecision);
if (aZNear < aZTolerance)
{
aZNear = aZTolerance;
}
}
else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
{
aZNear = aPrecision;
aZFar = aPrecision * 2.0;
}
}
// If range is too small
if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
{
aZFar = aZNear + Abs (aZFar) * aPrecision;
}
SetZRange (aZNear, aZFar);
}

View File

@ -28,6 +28,8 @@
#include <Standard_Macro.hxx>
#include <Standard_TypeDef.hxx>
#include <Bnd_Box.hxx>
DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
//! Camera class provides object-oriented approach to setting up projection
@ -268,6 +270,21 @@ public:
return myFOVy;
}
//! Change Z-min and Z-max planes of projection volume to match the
//! displayed objects. The methods ensures that view volume will
//! be close by depth range to the displayed objects. Fitting assumes that
//! for orthogonal projection the view volume contains the displayed objects
//! completely. For zoomed perspective view, the view volume is adjusted such
//! that it contains the objects or their parts, located in front of the camera.
//! @param theScaleFactor [in] the scale factor for Z-range.
//! The range between Z-min, Z-max projection volume planes
//! evaluated by z fitting method will be scaled using this coefficient.
//! Program error exception is thrown if negative or zero value is passed.
//! @param theMinMax [in] applicative min max boundaries.
//! @param theScaleFactor [in] real graphical boundaries (not accounting infinite flag).
void ZFitAll (const Standard_Real theScaleFactor, const Bnd_Box& theMinMax, const Bnd_Box& theGraphicBB);
//! Change the Near and Far Z-clipping plane positions.
//! For orthographic projection, theZNear, theZFar can be negative or positive.
//! For perspective projection, only positive values are allowed.

View File

@ -121,7 +121,7 @@ Standard_Boolean NIS_View::FitAll3d (const Quantity_Coefficient theCoef)
return Standard_False;
}
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();

View File

@ -244,6 +244,16 @@ is
---Level: Public
---Purpose: Updates the lights of the view. The view is redrawn.
AutoZFit (me : mutable);
---Level: Public
---Purpose: If automatic z-range fitting is turned on, adjusts Z-min and Z-max
-- projection volume planes with call to ZFitAll.
ZFitAll (me : mutable; theScaleFactor : Real from Standard = 1.0);
---Level: Public
---Purpose: Change Z-min and Z-max planes of projection volume to match the
-- displayed objects.
--------------------------------------------------------
---Category: Methods to modify the Attributes of the view
--------------------------------------------------------
@ -413,28 +423,6 @@ is
returns Boolean from Standard;
---Purpose: sets the immediate update mode and returns the previous one.
SetAutoZFitMode (me : mutable;
theIsOn : Boolean;
theScaleFactor : Real from Standard = 1.0);
---Level: public
---Purpose: Sets the automatic z-fit mode and its parameters.
-- The auto z-fit has extra parameters which can controlled from application level
-- to ensure that the size of viewing volume will be sufficiently large to cover
-- the depth of unmanaged objects, for example, transformation persistent ones.
-- @param theScaleFactor [in] the scale factor for Z-range.
-- The range between Z-min, Z-max projection volume planes
-- evaluated by z fitting method will be scaled using this coefficient.
-- Program error exception is thrown if negative or zero value
-- is passed.
AutoZFitMode (me) returns Boolean;
---Level: public
---Purpose: returns TRUE if automatic z-fit mode is turned on.
AutoZFitScaleFactor (me) returns Real from Standard;
---Level: public
---Purpose: returns scale factor parameter of automatic z-fit mode.
---------------------------------------------------
-- Triedron methods
---------------------------------------------------
@ -919,24 +907,6 @@ is
-- @param theMargin [in] the margin coefficient for view borders.
-- @param theToUpdate [in] flag to perform view update.
ZFitAll (me : mutable; theScaleFactor : Real from Standard = 1.0);
---Level: Public
---Purpose: Change Z-min and Z-max planes of projection volume to match the
-- displayed objects. The methods ensures that view volume will
-- be close by depth range to the displayed objects. Fitting assumes that
-- for orthogonal projection the view volume contains the displayed objects
-- completely. For zoomed perspective view, the view volume is adjusted such
-- that it contains the objects or their parts, located in front of the camera.
-- @param theScaleFactor [in] the scale factor for Z-range.
-- The range between Z-min, Z-max projection volume planes
-- evaluated by z fitting method will be scaled using this coefficient.
-- Program error exception is thrown if negative or zero value is passed.
AutoZFit (me : mutable);
---Level: Public
---Purpose: If automatic z-range fitting is turned on, adjusts Z-min and Z-max
-- projection volume planes with call to ZFitAll.
DepthFitAll( me : mutable ; Aspect : Coefficient = 0.01;
Margin : Coefficient = 0.01 );
---Level: Public
@ -1693,8 +1663,6 @@ fields
myViewAxis : Vector from Graphic3d;
myGravityReferencePoint : Vertex from Graphic3d;
myCamProjectionShift : Pnt from gp;
myAutoZFitIsOn : Boolean from Standard;
myAutoZFitScaleFactor : Real from Standard;
friends

View File

@ -165,9 +165,7 @@ V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
MyViewContext (),
myActiveLightsIterator(),
SwitchSetFront(Standard_False),
MyTrsf (1, 4, 1, 4),
myAutoZFitIsOn (Standard_True),
myAutoZFitScaleFactor (1.0)
MyTrsf (1, 4, 1, 4)
{
myImmediateUpdate = Standard_False;
MyView = new Visual3d_View(MyViewer->Viewer());
@ -287,8 +285,7 @@ V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theVi
MyViewContext = aFromView->Context() ;
SetCamera (new Graphic3d_Camera (theView->Camera()));
myAutoZFitIsOn = theView->AutoZFitMode();
myAutoZFitScaleFactor = theView->AutoZFitScaleFactor();
View()->SetAutoZFitMode (theView->View()->AutoZFitMode(), theView->View()->AutoZFitScaleFactor());
MyBackground = aFromView->Background() ;
MyGradientBackground = aFromView->GradientBackground();
@ -396,7 +393,7 @@ void V3d_View::Remove() const
//=============================================================================
void V3d_View::Update() const
{
if( MyView->IsDefined() ) MyView->Update() ;
if( MyView->IsDefined() ) MyView->Update (Aspect_TOU_ASAP) ;
}
//=============================================================================
@ -432,6 +429,24 @@ void V3d_View::Invalidate() const
}
}
//=============================================================================
//function : AutoZFit
//purpose :
//=============================================================================
void V3d_View::AutoZFit()
{
View()->AutoZFit();
}
//=============================================================================
//function : ZFitAll
//purpose :
//=============================================================================
void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
{
View()->ZFitAll (theScaleFactor);
}
//=============================================================================
//function : Redraw
//purpose :
@ -676,7 +691,7 @@ void V3d_View::SetFront()
myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
myCamera->SetUp (gp_Dir (xu, yu, zu));
AutoZFit();
View()->AutoZFit();
SwitchSetFront = !SwitchSetFront;
@ -730,7 +745,7 @@ void V3d_View::Rotate (const Standard_Real ax,
myCamera->Transform (aTrsf);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -785,7 +800,7 @@ void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Stan
myCamera->Transform (aTrsf);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -861,7 +876,7 @@ void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
myCamera->Transform (aRotation);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -896,7 +911,7 @@ void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
myCamera->Transform (aRotation);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -944,7 +959,7 @@ void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standa
myCamera->Transform (aTrsf);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -997,7 +1012,7 @@ void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
myCamera->Transform (aRotation);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1046,40 +1061,11 @@ void V3d_View::SetTwist(const Standard_Real angle)
myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
myCamera->Transform (aTrsf);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
//=============================================================================
//function : SetAutoZFitMode
//purpose :
//=============================================================================
void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
{
Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
myAutoZFitScaleFactor = theScaleFactor;
myAutoZFitIsOn = theIsOn;
}
//=============================================================================
//function : AutoZFitMode
//purpose :
//=============================================================================
Standard_Boolean V3d_View::AutoZFitMode() const
{
return myAutoZFitIsOn;
}
//=============================================================================
//function : AutoZFitScaleFactor
//purpose :
//=============================================================================
Standard_Real V3d_View::AutoZFitScaleFactor () const
{
return myAutoZFitScaleFactor;
}
//=============================================================================
//function : SetEye
//purpose :
@ -1093,7 +1079,7 @@ void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard
myCamera->SetEye (gp_Pnt (X, Y, Z));
SetTwist (aTwistBefore);
AutoZFit();
View()->AutoZFit();
SetImmediateUpdate (wasUpdateEnabled);
@ -1123,7 +1109,7 @@ void V3d_View::SetDepth(const Standard_Real Depth)
myCamera->SetCenter (aCameraCenter);
}
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1148,7 +1134,7 @@ void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Sta
SetTwist(aTwistBefore);
}
AutoZFit();
View()->AutoZFit();
SetImmediateUpdate (wasUpdateEnabled);
@ -1190,7 +1176,7 @@ void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
Panning (aPanX, aPanY);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1209,7 +1195,7 @@ void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_
SetTwist (aTwistBefore);
AutoZFit();
View()->AutoZFit();
SetImmediateUpdate (wasUpdateEnabled);
@ -1253,7 +1239,7 @@ void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standar
myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1296,7 +1282,7 @@ void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1336,7 +1322,7 @@ void V3d_View::Reset( const Standard_Boolean update )
myCamera->CopyMappingData (aDefaultCamera);
myCamera->CopyOrientationData (aDefaultCamera);
AutoZFit();
View()->AutoZFit();
}
SwitchSetFront = Standard_False;
@ -1368,7 +1354,7 @@ void V3d_View::SetSize (const Standard_Real theSize)
myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1471,7 +1457,7 @@ void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
myCamera->SetEye (myCamStartOpEye);
myCamera->SetCenter (myCamStartOpCenter);
myCamera->SetScale (myCamera->Scale() / Coef);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1498,7 +1484,7 @@ void V3d_View::SetScale( const Standard_Real Coef )
myCamera->SetScale (myCamera->Scale() / Coef);
}
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -1512,7 +1498,7 @@ void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, co
V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
AutoZFit();
View()->AutoZFit();
}
//=============================================================================
@ -1538,7 +1524,7 @@ void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean the
return;
}
AutoZFit();
View()->AutoZFit();
if (myImmediateUpdate || theToUpdate)
{
@ -1546,173 +1532,6 @@ void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean the
}
}
//=============================================================================
//function : AutoZFit
//purpose :
//=============================================================================
void V3d_View::AutoZFit()
{
if (!AutoZFitMode())
{
return;
}
ZFitAll (myAutoZFitScaleFactor);
}
//=============================================================================
//function : ZFitAll
//purpose :
//=============================================================================
void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
{
Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
// Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
// by their real boundaries (computed ignoring infinite flag) into the viewing volume.
// In addition to the graphical boundaries, the usual min max used for fitting perspective
// camera. To avoid numeric errors for perspective camera the negative ZNear values are
// fixed using tolerance distance, relative to boundaries size. The tolerance distance
// should be computed using information on boundaries of primary application actors,
// (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
Standard_Real aMinMax[6]; // applicative min max boundaries
View()->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
aMinMax[3], aMinMax[4], aMinMax[5],
Standard_False);
Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
View()->MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
Standard_True);
// Check if anything can be adjusted
Standard_Real aLim = (ShortRealLast() - 1.0);
if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
{
SetZSize (0.0);
ImmediateUpdate();
return;
}
// Measure depth of boundary points from camera eye
gp_Pnt aPntsToMeasure[16] =
{
gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
};
// Camera eye plane
gp_Dir aCamDir = myCamera->Direction();
gp_Pnt aCamEye = myCamera->Eye();
gp_Pln aCamPln (aCamEye, aCamDir);
Standard_Real aModelMinDist = RealLast();
Standard_Real aModelMaxDist = RealFirst();
Standard_Real aGraphicMinDist = RealLast();
Standard_Real aGraphicMaxDist = RealFirst();
const gp_XYZ& anAxialScale = myCamera->AxialScale();
// Get minimum and maximum distances to the eye plane
for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
{
gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
{
continue;
}
aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
aMeasurePnt.Y() * anAxialScale.Y(),
aMeasurePnt.Z() * anAxialScale.Z());
Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
// Check if the camera is intruded into the scene
if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
{
aDistance *= -1;
}
Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
aChangeMinDist = Min (aDistance, aChangeMinDist);
aChangeMaxDist = Max (aDistance, aChangeMaxDist);
}
// Compute depth of bounding box center
Standard_Real aMidDepth = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
// ShortReal precision factor used to add meaningful tolerance to
// ZNear, ZFar values in order to avoid equality after type conversion
// to ShortReal matrices type.
const Standard_Real aPrecision = Pow (0.1, ShortRealDigits() - 2);
// Compute enlarged or shrank near and far z ranges
Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
aZNear -= aPrecision * 0.5;
aZFar += aPrecision * 0.5;
if (!myCamera->IsOrthographic())
{
if (aZFar >= aPrecision)
{
// To avoid numeric errors... (See comments in the beginning of the method).
// Choose between model distance and graphical distance, as the model boundaries
// might be infinite if all structures have infinite flag.
const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
? aGraphicMaxDist - aGraphicMinDist : RealLast();
const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
? aModelMaxDist - aModelMinDist : RealLast();
const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
const Standard_Real aZTolerance =
Max (Abs (aMinDepth) * aPrecision, aPrecision);
if (aZNear < aZTolerance)
{
aZNear = aZTolerance;
}
}
else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
{
aZNear = aPrecision;
aZFar = aPrecision * 2.0;
}
}
// If range is too small
if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
{
aZFar = aZNear + Abs (aZFar) * aPrecision;
}
myCamera->SetZRange (aZNear, aZFar);
ImmediateUpdate();
}
//=============================================================================
//function : DepthFitAll
//purpose :
@ -1858,7 +1677,7 @@ void V3d_View::WindowFit (const Standard_Integer theMinXp,
Translate (myCamera, aPanVec.X(), -aPanVec.Y());
Scale (myCamera, aUSize, aVSize);
AutoZFit();
View()->AutoZFit();
}
else
{
@ -2811,7 +2630,7 @@ void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
myCamera->SetScale (myCamera->Scale() / aCoef);
Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
AutoZFit();
View()->AutoZFit();
SetImmediateUpdate (wasUpdateEnabled);
@ -2867,7 +2686,7 @@ void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
myCamera->SetAspect (aWinAspect);
Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
Scale (myCamera, aFitSizeU, aFitSizeV);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -3104,7 +2923,7 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
const Standard_Boolean toAutoUpdate = myImmediateUpdate;
myImmediateUpdate = Standard_False;
AutoZFit();
View()->AutoZFit();
myImmediateUpdate = toAutoUpdate;
if (theToKeepAspect)

View File

@ -68,7 +68,7 @@ void V3d_View::Move(const Standard_Real Dx, const Standard_Real Dy, const Standa
+ Dz * gp_Pnt (ZX, ZY, ZZ).XYZ()
);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -86,7 +86,7 @@ void V3d_View::Move(const Standard_Real Length, const Standard_Boolean Start) {
myCamera->SetEye (myCamera->Eye().XYZ() + Length * gp_Pnt (Vx, Vy, Vz).XYZ());
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -142,7 +142,7 @@ void V3d_View::Translate(const Standard_Real Dx, const Standard_Real Dy, const S
- Dz * gp_Pnt (ZX, ZY, ZZ).XYZ()
);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}
@ -190,7 +190,7 @@ void V3d_View::Translate(const Standard_Real theLength, const Standard_Boolean t
gp_Pnt aNewCenter (myCamStartOpCenter.XYZ() - gp_Pnt (aVx, aVy, aVz).XYZ() * theLength);
myCamera->SetCenter (aNewCenter);
AutoZFit();
View()->AutoZFit();
ImmediateUpdate();
}

View File

@ -2480,7 +2480,7 @@ static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const
if (theArgsNb == 1)
{
aCurrentView->ZFitAll();
aCurrentView->View()->ZFitAll();
aCurrentView->Redraw();
return 0;
}
@ -2492,7 +2492,7 @@ static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const
aScale = Draw::Atoi (theArgVec[1]);
}
aCurrentView->ZFitAll (aScale);
aCurrentView->View()->ZFitAll (aScale);
aCurrentView->Redraw();
return 0;
@ -2851,7 +2851,7 @@ static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, cons
return 1;
}
V3dView->ZFitAll();
V3dView->View()->ZFitAll();
return 0;
}
@ -5671,7 +5671,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
return 1;
}
Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
Standard_Real aScale = aCurrentView->View()->AutoZFitScaleFactor();
if (theArgsNb > 3)
{
@ -5682,7 +5682,7 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
if (theArgsNb < 2)
{
theDi << "Auto z-fit mode: " << "\n"
<< "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
<< "On: " << (aCurrentView->View()->AutoZFitMode() ? "enabled" : "disabled") << "\n"
<< "Scale: " << aScale << "\n";
return 0;
}
@ -5694,8 +5694,8 @@ static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const
aScale = Draw::Atoi (theArgVec[2]);
}
aCurrentView->SetAutoZFitMode (isOn, aScale);
aCurrentView->AutoZFit();
aCurrentView->View()->SetAutoZFitMode (isOn, aScale);
aCurrentView->View()->AutoZFit();
aCurrentView->Redraw();
return 0;
@ -5810,7 +5810,7 @@ static int VChangeCamera (Draw_Interpretor& theDi, Standard_Integer theArgsNb, c
return 1;
}
ViewerTest::CurrentView()->AutoZFit();
ViewerTest::CurrentView()->View()->AutoZFit();
ViewerTest::CurrentView()->Redraw();
return 0;

View File

@ -390,7 +390,8 @@ is
---Purpose:
-- After this call, each view is mapped in an unique window.
Update ( me : mutable )
Update ( me : mutable;
theUpdateMode : TypeOfUpdate from Aspect )
is static;
---Level: Public
---Purpose: Updates screen in function of modifications of
@ -406,6 +407,38 @@ is
-- the structures.
---Category: Methods to modify the class definition
SetAutoZFitMode (me : mutable;
theIsOn : Boolean;
theScaleFactor : Real from Standard = 1.0);
---Level: public
---Purpose: Sets the automatic z-fit mode and its parameters.
-- The auto z-fit has extra parameters which can controlled from application level
-- to ensure that the size of viewing volume will be sufficiently large to cover
-- the depth of unmanaged objects, for example, transformation persistent ones.
-- @param theScaleFactor [in] the scale factor for Z-range.
-- The range between Z-min, Z-max projection volume planes
-- evaluated by z fitting method will be scaled using this coefficient.
-- Program error exception is thrown if negative or zero value
-- is passed.
AutoZFitMode (me) returns Boolean;
---Level: public
---Purpose: returns TRUE if automatic z-fit mode is turned on.
AutoZFitScaleFactor (me) returns Real from Standard;
---Level: public
---Purpose: returns scale factor parameter of automatic z-fit mode.
AutoZFit (me : mutable);
---Level: Public
---Purpose: If automatic z-range fitting is turned on, adjusts Z-min and Z-max
-- projection volume planes with call to ZFitAll.
ZFitAll (me : mutable; theScaleFactor : Real from Standard = 1.0);
---Level: Public
---Purpose: Change Z-min and Z-max planes of projection volume to match the
-- displayed objects.
ViewMappingReset ( me : mutable )
is static;
---Level: Public
@ -1205,6 +1238,11 @@ fields
myDefaultCamera : Camera_Handle from Graphic3d;
myAutoZFitIsOn : Boolean from Standard;
myAutoZFitScaleFactor : Real from Standard;
myStructuresUpdated : Boolean from Standard;
friends
class ViewManager from Visual3d

View File

@ -155,11 +155,14 @@
//-Constructors
Visual3d_View::Visual3d_View (const Handle(Visual3d_ViewManager)& AManager):
MyContext (),
MyTOCOMPUTESequence (),
MyCOMPUTEDSequence (),
MyDisplayedStructure ()
Visual3d_View::Visual3d_View (const Handle(Visual3d_ViewManager)& AManager) :
MyContext (),
MyTOCOMPUTESequence (),
MyCOMPUTEDSequence (),
MyDisplayedStructure (),
myAutoZFitIsOn (Standard_True),
myAutoZFitScaleFactor (1.0),
myStructuresUpdated (Standard_True)
{
MyPtrViewManager = AManager.operator->();
@ -409,8 +412,7 @@ void Visual3d_View::SetRatio()
}
MyViewManager->SetUpdateMode (UpdateMode);
if (UpdateMode == Aspect_TOU_ASAP)
Update();
Update (UpdateMode);
}
void Visual3d_View::UpdateLights()
@ -487,8 +489,8 @@ void Visual3d_View::SetBackground (const Aspect_Background& ABack) {
MyGraphicDriver->Background (MyCView);
if (MyPtrViewManager && MyViewManager->UpdateMode () == Aspect_TOU_ASAP)
Update ();
if (MyPtrViewManager)
Update (MyViewManager->UpdateMode());
}
@ -506,42 +508,61 @@ void Visual3d_View::SetGradientBackground(const Aspect_GradientBackground& ABack
MyGraphicDriver->GradientBackground(MyCView, aCol1, aCol2, MyGradientBackground.BgGradientFillMethod());
if ( update )
Update ();
else if (MyPtrViewManager && MyViewManager->UpdateMode () == Aspect_TOU_ASAP)
Update();
{
Update (Aspect_TOU_ASAP);
}
else if (MyPtrViewManager)
{
Update (MyViewManager->UpdateMode());
}
}
void Visual3d_View::SetBackgroundImage( const Standard_CString FileName,
const Aspect_FillMethod FillStyle,
const Standard_Boolean update )
{
if ( IsDeleted() )
if (IsDeleted())
{
return;
if ( !IsDefined() )
}
if (!IsDefined())
{
Visual3d_ViewDefinitionError::Raise ("Window not defined");
}
MyGraphicDriver->BackgroundImage( FileName, MyCView, FillStyle );
if ( update )
Update();
else if ( MyViewManager->UpdateMode() == Aspect_TOU_ASAP )
Update();
if (update)
{
Update (Aspect_TOU_ASAP);
}
else
{
Update (MyViewManager->UpdateMode());
}
}
void Visual3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
const Standard_Boolean update )
{
if ( IsDeleted() )
if (IsDeleted())
{
return;
if ( !IsDefined() )
}
if (!IsDefined())
{
Visual3d_ViewDefinitionError::Raise ("Window not defined");
}
MyGraphicDriver->SetBgImageStyle( MyCView, FillStyle );
if ( update )
Update();
else if ( MyViewManager->UpdateMode() == Aspect_TOU_ASAP )
Update();
if (update)
{
Update (Aspect_TOU_ASAP);
} else
{
Update (MyViewManager->UpdateMode());
}
}
Aspect_Background Visual3d_View::Background () const {
@ -553,17 +574,26 @@ Aspect_Background Visual3d_View::Background () const {
void Visual3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
const Standard_Boolean update )
{
if ( IsDeleted() )
if (IsDeleted())
{
return;
if ( !IsDefined() )
}
if (!IsDefined())
{
Visual3d_ViewDefinitionError::Raise ("Window not defined");
}
MyGraphicDriver->SetBgGradientStyle( MyCView, FillStyle );
if ( update )
Update();
else if ( MyViewManager->UpdateMode() == Aspect_TOU_ASAP )
Update();
if (update)
{
Update (Aspect_TOU_ASAP);
}
else
{
Update (MyViewManager->UpdateMode());
}
}
@ -598,10 +628,7 @@ void Visual3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
MyGraphicDriver->SetCamera (MyCView);
if (MyViewManager->UpdateMode() == Aspect_TOU_ASAP)
{
Update();
}
Update (MyViewManager->UpdateMode());
}
// =======================================================================
@ -634,10 +661,7 @@ void Visual3d_View::ViewOrientationReset ()
MyCView.Context.Camera->CopyOrientationData (myDefaultCamera);
}
if (MyViewManager->UpdateMode() == Aspect_TOU_ASAP)
{
Update();
}
Update (MyViewManager->UpdateMode());
}
// =======================================================================
@ -669,10 +693,7 @@ void Visual3d_View::ViewMappingReset ()
MyCView.Context.Camera->CopyMappingData (myDefaultCamera);
}
if (MyViewManager->UpdateMode() == Aspect_TOU_ASAP)
{
Update();
}
Update (MyViewManager->UpdateMode());
}
void Visual3d_View::SetContext (const Visual3d_ContextView& CTX) {
@ -872,7 +893,7 @@ Standard_Integer Length = FooSequence.Length ();
if (Length != 0) FooSequence.Clear ();
}
if (MyViewManager->UpdateMode () == Aspect_TOU_ASAP) Update ();
Update (MyViewManager->UpdateMode());
}
@ -957,7 +978,7 @@ Standard_Boolean BZBuffer = ZBufferIsActivated ();
SetZBufferActivity (0);
}
if (MyViewManager->UpdateMode () == Aspect_TOU_ASAP) Update ();
Update (MyViewManager->UpdateMode());
}
@ -1008,7 +1029,7 @@ void Visual3d_View::Deactivate () {
}
}
if (MyViewManager->UpdateMode () == Aspect_TOU_ASAP) Update ();
Update (MyViewManager->UpdateMode());
// No action currently possible in the view
MyCView.Active = 0;
@ -1082,6 +1103,12 @@ void Visual3d_View::Redraw (const Handle(Visual3d_Layer)& theUnderLayer,
}
}
if (myStructuresUpdated)
{
AutoZFit();
myStructuresUpdated = Standard_False;
}
MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
if (!MyGraphicDriver->IsDeviceLost())
{
@ -1118,12 +1145,17 @@ void Visual3d_View::Invalidate()
MyGraphicDriver->Invalidate (MyCView);
}
void Visual3d_View::Update()
void Visual3d_View::Update (Aspect_TypeOfUpdate theUpdateMode)
{
IsInitialized = Standard_True;
Compute ();
myStructuresUpdated = Standard_True;
Redraw (MyViewManager->UnderLayer(), MyViewManager->OverLayer(), 0, 0, 0, 0);
if (theUpdateMode == Aspect_TOU_ASAP)
{
IsInitialized = Standard_True;
Compute ();
Redraw (MyViewManager->UnderLayer(), MyViewManager->OverLayer(), 0, 0, 0, 0);
}
}
void Visual3d_View::Update (const Handle(Visual3d_Layer)& theUnderLayer,
@ -1132,9 +1164,83 @@ void Visual3d_View::Update (const Handle(Visual3d_Layer)& theUnderLayer,
IsInitialized = Standard_True;
Compute ();
myStructuresUpdated = Standard_True;
Redraw (theUnderLayer, theOverLayer, 0, 0, 0, 0);
}
//=============================================================================
//function : SetAutoZFitMode
//purpose :
//=============================================================================
void Visual3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
{
Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
myAutoZFitScaleFactor = theScaleFactor;
myAutoZFitIsOn = theIsOn;
}
//=============================================================================
//function : AutoZFitMode
//purpose :
//=============================================================================
Standard_Boolean Visual3d_View::AutoZFitMode() const
{
return myAutoZFitIsOn;
}
//=============================================================================
//function : AutoZFitScaleFactor
//purpose :
//=============================================================================
Standard_Real Visual3d_View::AutoZFitScaleFactor () const
{
return myAutoZFitScaleFactor;
}
//=============================================================================
//function : AutoZFit
//purpose :
//=============================================================================
void Visual3d_View::AutoZFit()
{
if (!AutoZFitMode())
{
return;
}
ZFitAll (myAutoZFitScaleFactor);
}
//=============================================================================
//function : ZFitAll
//purpose :
//=============================================================================
void Visual3d_View::ZFitAll (const Standard_Real theScaleFactor)
{
Standard_Real aMinMax[6]; // applicative min max boundaries
MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
aMinMax[3], aMinMax[4], aMinMax[5],
Standard_False);
Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
Standard_True);
Bnd_Box aMinMaxBox;
Bnd_Box aGraphicBox;
aMinMaxBox.Update (aMinMax[0], aMinMax[1], aMinMax[2],
aMinMax[3], aMinMax[4], aMinMax[5]);
aGraphicBox.Update (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
aGraphicBB[3], aGraphicBB[4], aGraphicBB[5]);
const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera;
aCamera->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
}
Visual3d_TypeOfAnswer Visual3d_View::AcceptDisplay (const Handle(Graphic3d_Structure)& AStructure) const {
// Return type of visualization of the view
@ -1390,7 +1496,7 @@ Standard_Integer Index = IsComputed (AStructure);
AStructure->CalculateBoundBox();
MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), AStructure->DisplayPriority());
MyDisplayedStructure.Add (AStructure);
if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
Update (AnUpdateMode);
}
if (Answer == Visual3d_TOA_COMPUTE) {
@ -1405,7 +1511,7 @@ Standard_Integer OldStructId =
if (! IsDisplayed (AStructure)) {
MyDisplayedStructure.Add (AStructure);
MyGraphicDriver->DisplayStructure (MyCView, *(MyCOMPUTEDSequence.Value (Index)->CStructure()), AStructure->DisplayPriority ());
if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
Update (AnUpdateMode);
}
return;
}
@ -1429,7 +1535,7 @@ Standard_Integer OldStructId =
Identification ();
MyDisplayedStructure.Add (AStructure);
MyGraphicDriver->DisplayStructure (MyCView, *(MyCOMPUTEDSequence.Value (NewIndex)->CStructure()), AStructure->DisplayPriority ());
if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
Update (AnUpdateMode);
}
return;
}
@ -1517,7 +1623,7 @@ Standard_Boolean ComputeShading = ((ViewType == Visual3d_TOV_SHADING) &&
if (! IsDisplayed (AStructure))
MyDisplayedStructure.Add (AStructure);
MyGraphicDriver->DisplayStructure (MyCView, *(TheStructure->CStructure()), AStructure->DisplayPriority ());
if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
Update (AnUpdateMode);
}
} // Visual3d_TOA_COMPUTE
}
@ -1575,7 +1681,7 @@ Standard_Integer Index = IsComputed (AStructure);
// else is impossible
}
MyDisplayedStructure.Remove (AStructure);
if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
Update (AnUpdateMode);
}
}
@ -2794,7 +2900,7 @@ void Visual3d_View :: SetComputedMode ( const Standard_Boolean aMode )
} // end while
if ( MyViewManager -> UpdateMode () == Aspect_TOU_ASAP ) Update ();
Update (MyViewManager->UpdateMode());
} // end else

23
tests/bugs/vis/bug24996 Normal file
View File

@ -0,0 +1,23 @@
puts "============"
puts "CR24996"
puts "============"
puts ""
#######################################################################
# Visualization - newly displayed objects are clipped until first camera movement
#######################################################################
box b1 0 0 0 1 2 3
box b2 3 2 1 1 2 3
box b3 5 -4 0 1 2 3
vinit
vclear
vaxo
vsetdispmode 0
vdisplay b1
vfit
vzoom 0.25
vdisplay b2 b3
set anImage ${imagedir}/${casename}.png
vdump ${anImage}

View File

@ -17,4 +17,4 @@ if { [catch { featperform prism result face face } ] != 0 } {
puts "Error in featperform"
}
set square 82351.1
set square 103218