From 0d3ec65acb5d9259746ed3f555be311fc751e138 Mon Sep 17 00:00:00 2001 From: jfa Date: Wed, 5 Oct 2005 11:45:46 +0000 Subject: [PATCH] Provide corresponding projection setting after mesh presentation creation. This functionality presents in V2.2.x --- src/VISUGUI/VisuGUI_Tools.cxx | 86 ++++++++++++++++++++++++++++++++++- src/VISUGUI/VisuGUI_Tools.h | 11 +++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/VISUGUI/VisuGUI_Tools.cxx b/src/VISUGUI/VisuGUI_Tools.cxx index 030fdd06..ca94e272 100644 --- a/src/VISUGUI/VisuGUI_Tools.cxx +++ b/src/VISUGUI/VisuGUI_Tools.cxx @@ -792,6 +792,89 @@ namespace VISU QApplication::restoreOverrideCursor(); } + static bool ComputeVisiblePropBounds(SVTK_ViewWindow* theViewWindow, + float allBounds[6], + const char* theActorClassName = "VISU_Actor") + { + vtkRenderer *aRen = theViewWindow->getRenderer(); + vtkActorCollection *anActColl = aRen->GetActors(); + vtkProp *prop; + float *bounds; + int somethingVisible = false; + + allBounds[0] = allBounds[2] = allBounds[4] = VTK_LARGE_FLOAT; + allBounds[1] = allBounds[3] = allBounds[5] = -VTK_LARGE_FLOAT; + // loop through all props + for (anActColl->InitTraversal(); (prop = anActColl->GetNextProp()); ) { + // if it's invisible, or has no geometry, we can skip the rest + if (prop->GetVisibility() && prop->IsA(theActorClassName)) { + bounds = prop->GetBounds(); + // make sure we haven't got bogus bounds + if (bounds != NULL && + bounds[0] > -VTK_LARGE_FLOAT && bounds[1] < VTK_LARGE_FLOAT && + bounds[2] > -VTK_LARGE_FLOAT && bounds[3] < VTK_LARGE_FLOAT && + bounds[4] > -VTK_LARGE_FLOAT && bounds[5] < VTK_LARGE_FLOAT) + { + somethingVisible = true; + if (bounds[0] < allBounds[0]) allBounds[0] = bounds[0]; + if (bounds[1] > allBounds[1]) allBounds[1] = bounds[1]; + if (bounds[2] < allBounds[2]) allBounds[2] = bounds[2]; + if (bounds[3] > allBounds[3]) allBounds[3] = bounds[3]; + if (bounds[4] < allBounds[4]) allBounds[4] = bounds[4]; + if (bounds[5] > allBounds[5]) allBounds[5] = bounds[5]; + }//not bogus + } + } + return somethingVisible; + } + + void SetFitAll(SVTK_ViewWindow* theViewWindow) + { + static float PRECISION = 0.000001; + static float DEVIATION = 600; + float XYZ_Bnd[6]; + if (!ComputeVisiblePropBounds(theViewWindow, XYZ_Bnd)) return; + + float absX = XYZ_Bnd[1] - XYZ_Bnd[0]; + float absY = XYZ_Bnd[3] - XYZ_Bnd[2]; + float absZ = XYZ_Bnd[5] - XYZ_Bnd[4]; + + enum CameraOrient {e3D, eFront, eLeft, eTop}; + CameraOrient aCameraOrient = e3D; + if (absX <= PRECISION) aCameraOrient = eFront; + else { + if (absY <= PRECISION) aCameraOrient = eLeft; + else { + if (absZ <= PRECISION) aCameraOrient = eTop; + else { + // all the three dimensions exceeds precision + float dev_abs_XY = absX / absY; + float dev_abs_YZ = absY / absZ; + float dev_abs_XZ = absX / absZ; + if (dev_abs_XY >= DEVIATION || 1./dev_abs_YZ >= DEVIATION) + aCameraOrient = eLeft; + else { + if (1./dev_abs_XY >= DEVIATION || 1./dev_abs_XZ >= DEVIATION) + aCameraOrient = eFront; + else { + if (dev_abs_XZ >= DEVIATION || dev_abs_YZ >= DEVIATION) + aCameraOrient = eTop; + } + } + } + } + } + + switch (aCameraOrient) { + case eFront: theViewWindow->onFrontView(); break; + case eLeft: theViewWindow->onLeftView(); break; + case eTop: theViewWindow->onTopView(); break; + case e3D: theViewWindow->onResetView(); break; + } + theViewWindow->getRenderer()->ResetCameraClippingRange(); + theViewWindow->onFitAll(); + } + //************************************************************ // Plot2d View @@ -1070,7 +1153,8 @@ namespace VISU timer.Start(); #endif PublishInView(theModule, pPresent); - aView->onFitAll(); + //aView->onFitAll(); + SetFitAll(aView); #ifdef CHECKTIME timer.Stop(); MESSAGE("VisuGUI::CreateMesh() - DISPLAY MESH"); diff --git a/src/VISUGUI/VisuGUI_Tools.h b/src/VISUGUI/VisuGUI_Tools.h index 63a767f4..3d6fd0e5 100644 --- a/src/VISUGUI/VisuGUI_Tools.h +++ b/src/VISUGUI/VisuGUI_Tools.h @@ -150,6 +150,17 @@ namespace VISU { void RecreateActor(const SalomeApp_Module* theModule, VISU::Prs3d_i* thePrs); + /*! + * \brief Advanced FitAll, sets view projection in accordance with current view contents + * + * If common bounding box of all actors in \a theViewWindow has + * at least one small side, then corresponding projection will be set + * (Top, Left or Front), else 3D projection will be used. + * + * \param theViewWindow - the view to perform FitAll in. + */ + void SetFitAll(SVTK_ViewWindow* theViewWindow); + // Plot2d View SPlot2d_Viewer* GetPlot2dViewer(const SalomeApp_Module* theModule, const bool theCreate = false); -- 2.39.2