1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

OCC22529 FitALL works incorrectly for small flat shapes

This commit is contained in:
KGV 2011-05-25 08:36:49 +00:00 committed by bugmaster
parent 1f33f955ce
commit 3561782339

View File

@ -1748,118 +1748,178 @@ void V3d_View::FitAll(const Standard_Real Coef, const Standard_Boolean FitZ,
{ {
Standard_Real Umin, Umax, Vmin, Vmax, Xrp, Yrp, Zrp, U, V, W, U1, V1, W1; Standard_Real Umin, Umax, Vmin, Vmax, Xrp, Yrp, Zrp, U, V, W, U1, V1, W1;
Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
Standard_Real DxvOld,DyvOld,DxvNew,DyvNew,RapOld,RapNew ; Standard_Real DxvOld, DyvOld, DxvNew, DyvNew;
Standard_Integer Xpixel,Ypixel;
// CAL 6/11/98
Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures(); Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures();
Standard_Integer nbPasse = 2;
if( (Nstruct <= 0) || (Coef < 0.) || (Coef > 1.) ) { if ((Nstruct <= 0) || (Coef < 0.0) || (Coef > 1.0))
{
#ifndef IMP020300 #ifndef IMP020300
ImmediateUpdate(); ImmediateUpdate();
#endif #endif
return; return;
} }
MyProjReferencePoint = MyViewMapping.ProjectionReferencePoint(); MyProjReferencePoint = MyViewMapping.ProjectionReferencePoint();
MyProjReferencePoint.Coord (Xrp, Yrp, Zrp); MyProjReferencePoint.Coord (Xrp, Yrp, Zrp);
if( MyView->IsDefined() ) { if (MyView->IsDefined())
{
Standard_Integer Xpixel, Ypixel;
MyWindow->Size (Xpixel, Ypixel); MyWindow->Size (Xpixel, Ypixel);
DxvOld = Xpixel; DyvOld = Ypixel; DxvOld = Xpixel;
} else { DyvOld = Ypixel;
}
else
{
MyViewMapping.WindowLimit (Umin, Vmin, Umax, Vmax); MyViewMapping.WindowLimit (Umin, Vmin, Umax, Vmax);
DxvOld = Abs(Umax - Umin) ; DyvOld = Abs(Vmax - Vmin) ; DxvOld = Abs (Umax - Umin);
DyvOld = Abs (Vmax - Vmin);
} }
if( (DxvOld == 0.) || (DyvOld == 0.) ) return ; if ((DxvOld == 0.0) || (DyvOld == 0.0))
RapOld = DxvOld/DyvOld ; {
return;
MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
//Object with null bounding box for anyone axis has been
//obtained unit bounding interval
if( Xmin == Xmax ) {
Xmin--; Xmax++;
}
if( Ymin == Ymax ) {
Ymin--; Ymax++;
}
if( Zmin == Zmax ) {
Zmin--; Zmax++;
} }
Standard_Real LIM = ShortRealLast() -1.; Standard_Real aWinRatio = DxvOld / DyvOld;
// retrieve min / max values for current displayed objects
MyView->MinMaxValues (Xmin, Ymin, Zmin,
Xmax, Ymax, Zmax);
Standard_Real LIM = ShortRealLast() - 1.0;
if (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM if (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
|| Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM ) { || Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM)
{
#ifndef IMP020300 #ifndef IMP020300
ImmediateUpdate(); ImmediateUpdate();
#endif #endif
return; return;
} }
while (nbPasse != 0) // eliminate fluctuations between sequential FitAll() calls
MyViewMapping.SetWindowLimit (-1.0 * aWinRatio, -1.0, 1.0 * aWinRatio, 1.0);
if (MyType != V3d_PERSPECTIVE)
{
MyProjReferencePoint.SetCoord (0.0, 0.0, Zrp);
MyViewMapping.SetProjectionReferencePoint (MyProjReferencePoint);
}
MyView->SetViewMapping (MyViewMapping);
// iterate 2 times to find optimal view plane size
// (use view plane values computed on previous iteration)
for (Standard_Integer aIteration = 2; aIteration > 0; --aIteration)
{ {
MyView->Projects (Xmin, Ymin, Zmin, U, V, W); MyView->Projects (Xmin, Ymin, Zmin, U, V, W);
MyView->Projects (Xmax, Ymax, Zmax, U1, V1, W1); MyView->Projects (Xmax, Ymax, Zmax, U1, V1, W1);
Umin = Min (U, U1); Umax = Max (U, U1); Umin = Min (U, U1); Umax = Max (U, U1);
Vmin = Min (V, V1); Vmax = Max (V, V1); Vmin = Min (V, V1); Vmax = Max (V, V1);
MyView->Projects (Xmin, Ymin, Zmax, U, V, W); MyView->Projects (Xmin, Ymin, Zmax, U, V, W);
Umin = Min (U, Umin); Umax = Max (U, Umax); Umin = Min (U, Umin); Umax = Max (U, Umax);
Vmin = Min (V, Vmin); Vmax = Max (V, Vmax); Vmin = Min (V, Vmin); Vmax = Max (V, Vmax);
MyView->Projects (Xmax, Ymin, Zmax, U, V, W); MyView->Projects (Xmax, Ymin, Zmax, U, V, W);
Umin = Min (U, Umin); Umax = Max (U, Umax); Umin = Min (U, Umin); Umax = Max (U, Umax);
Vmin = Min (V, Vmin); Vmax = Max (V, Vmax); Vmin = Min (V, Vmin); Vmax = Max (V, Vmax);
MyView->Projects (Xmax, Ymin, Zmin, U, V, W); MyView->Projects (Xmax, Ymin, Zmin, U, V, W);
Umin = Min (U, Umin); Umax = Max (U, Umax); Umin = Min (U, Umin); Umax = Max (U, Umax);
Vmin = Min (V, Vmin); Vmax = Max (V, Vmax); Vmin = Min (V, Vmin); Vmax = Max (V, Vmax);
MyView->Projects (Xmax, Ymax, Zmin, U, V, W); MyView->Projects (Xmax, Ymax, Zmin, U, V, W);
Umin = Min (U, Umin); Umax = Max (U, Umax); Umin = Min (U, Umin); Umax = Max (U, Umax);
Vmin = Min (V, Vmin); Vmax = Max (V, Vmax); Vmin = Min (V, Vmin); Vmax = Max (V, Vmax);
MyView->Projects (Xmin, Ymax, Zmax, U, V, W); MyView->Projects (Xmin, Ymax, Zmax, U, V, W);
Umin = Min (U, Umin); Umax = Max (U, Umax); Umin = Min (U, Umin); Umax = Max (U, Umax);
Vmin = Min (V, Vmin); Vmax = Max (V, Vmax); Vmin = Min (V, Vmin); Vmax = Max (V, Vmax);
MyView->Projects (Xmin, Ymax, Zmin, U, V, W); MyView->Projects (Xmin, Ymax, Zmin, U, V, W);
Umin = Min (U, Umin); Umax = Max (U, Umax); Umin = Min (U, Umin); Umax = Max (U, Umax);
Vmin = Min (V, Vmin); Vmax = Max (V, Vmax); Vmin = Min (V, Vmin); Vmax = Max (V, Vmax);
if( (Umax > Umin) && (Vmax > Vmin) ) {
DxvNew = Abs(Umax - Umin) ; DyvNew = Abs(Vmax - Vmin) ;
RapNew = DxvNew/DyvNew ; DxvNew = Abs (Umax - Umin);
if( RapNew >= RapOld ) { DyvNew = Abs (Vmax - Vmin);
if (DyvNew < 10.0 * Precision::Confusion())
{
if (DxvNew < 10.0 * Precision::Confusion())
{
// whole scene projected to point
DxvNew = Max (Abs (Zmax - Zmin), (Max (Abs (Xmax - Xmin), Abs (Ymax - Ymin))));
if (DxvNew < 10.0 * Precision::Confusion())
{
// this is really just one (!) point and zooming has no any effect
// just center the view
DyvNew = DyvOld;
DxvNew = DxvOld;
}
else
{
// we look along some line
// fit view like that to see whole scene on rotation
DxvNew += Coef * DxvNew; DxvNew += Coef * DxvNew;
DyvNew = DxvNew/RapOld ; DyvNew = DxvNew / aWinRatio;
} else { }
}
else
{
// whole scene projected to horizontal line
DxvNew += Coef * DxvNew;
DyvNew = DxvNew / aWinRatio;
}
}
else
{
// general case (or DxvNew == 0.0 - vertical line)
// safe original ratio
Standard_Real aFitRatio = DxvNew / DyvNew;
if (aFitRatio >= aWinRatio)
{
DxvNew += Coef * DxvNew;
DyvNew = DxvNew / aWinRatio;
}
else
{
DyvNew += Coef * DyvNew; DyvNew += Coef * DyvNew;
DxvNew = DyvNew*RapOld ; DxvNew = DyvNew * aWinRatio;
}
} }
Xrp = (Umin + Umax)/2. ; Yrp = (Vmin + Vmax)/2. ; // new scene center
Umin = Xrp - DxvNew/2. ; Umax = Xrp + DxvNew/2. ; Xrp = 0.5 * (Umin + Umax);
Vmin = Yrp - DyvNew/2. ; Vmax = Yrp + DyvNew/2. ; Yrp = 0.5 * (Vmin + Vmax);
// new window limits
Umin = Xrp - 0.5 * DxvNew;
Umax = Xrp + 0.5 * DxvNew;
Vmin = Yrp - 0.5 * DyvNew;
Vmax = Yrp + 0.5 * DyvNew;
MyViewMapping.SetWindowLimit (Umin, Vmin, Umax, Vmax); MyViewMapping.SetWindowLimit (Umin, Vmin, Umax, Vmax);
#ifdef OCC280 if (MyType != V3d_PERSPECTIVE)
if( MyType != V3d_PERSPECTIVE ) { {
// center the view
MyProjReferencePoint.SetCoord (Xrp, Yrp, Zrp); MyProjReferencePoint.SetCoord (Xrp, Yrp, Zrp);
MyViewMapping.SetProjectionReferencePoint (MyProjReferencePoint); MyViewMapping.SetProjectionReferencePoint (MyProjReferencePoint);
} }
#else
MyProjReferencePoint.SetCoord(Xrp,Yrp,Zrp) ;
MyViewMapping.SetProjectionReferencePoint(MyProjReferencePoint);
#endif
MyView->SetViewMapping (MyViewMapping); MyView->SetViewMapping (MyViewMapping);
} }
nbPasse--; if (FitZ)
} // while {
if(FitZ) {
ZFitAll (Zmargin); ZFitAll (Zmargin);
#ifdef IMP020300 #ifdef IMP020300
} else { }
else
{
ImmediateUpdate(); ImmediateUpdate();
#endif #endif
} }
#ifdef IMP020300 #ifdef IMP020300
if( !myImmediateUpdate && update ) Update(); if (!myImmediateUpdate && update)
{
Update();
}
#endif #endif
} }
@ -1889,18 +1949,6 @@ void V3d_View::ZFitAll(const Standard_Real Coef) {
return ; return ;
} }
//Object with null bounding box for anyone axis has been
//obtained unit bounding interval
if( Xmin == Xmax ) {
Xmin--; Xmax++;
}
if( Ymin == Ymax ) {
Ymin--; Ymax++;
}
if( Zmin == Zmax ) {
Zmin--; Zmax++;
}
// CAL 6/11/98 // CAL 6/11/98
// Case when view contains only a point // Case when view contains only a point
if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) { if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
@ -1954,18 +2002,6 @@ void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
return ; return ;
} }
//Object with null bounding box for anyone axis has been
//obtained unit bounding interval
if( Xmin == Xmax ) {
Xmin--; Xmax++;
}
if( Ymin == Ymax ) {
Ymin--; Ymax++;
}
if( Zmin == Zmax ) {
Zmin--; Zmax++;
}
if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) { if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
ImmediateUpdate(); ImmediateUpdate();
return ; return ;