Back to index

salome-geom  6.5.0
MeasureGUI_DistanceDlg.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // GEOM GEOMGUI : GUI for Geometry component
00024 // File   : MeasureGUI_DistanceDlg.cxx
00025 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
00026 //
00027 #include "MeasureGUI_DistanceDlg.h"
00028 #include "MeasureGUI_Widgets.h"
00029 
00030 #include <DlgRef.h>
00031 #include <GEOMBase.h>
00032 #include <GeometryGUI.h>
00033 
00034 #include <SUIT_Session.h>
00035 #include <SUIT_Desktop.h>
00036 #include <SUIT_ResourceMgr.h>
00037 #include <SUIT_ViewWindow.h>
00038 #include <SUIT_ViewManager.h>
00039 #include <SOCC_Prs.h>
00040 #include <SOCC_ViewModel.h>
00041 #include <SalomeApp_Tools.h>
00042 #include <SalomeApp_Application.h>
00043 #include <LightApp_SelectionMgr.h>
00044 
00045 // OCCT Includes
00046 #include <Geom_Plane.hxx>
00047 #include <AIS_LengthDimension.hxx>
00048 #include <AIS_Drawer.hxx>
00049 #include <Prs3d_LengthAspect.hxx>
00050 #include <Prs3d_LineAspect.hxx>
00051 #include <BRepBuilderAPI_MakeEdge.hxx>
00052 #include <BRepBuilderAPI_MakeVertex.hxx>
00053 #include <gce_MakePln.hxx>
00054 #include <Precision.hxx>
00055 
00056 //=================================================================================
00057 // class    : MeasureGUI_DistanceDlg()
00058 // purpose  : Constructs a MeasureGUI_DistanceDlg which is a child of 'parent', with the
00059 //            name 'name' and widget flags set to 'f'.
00060 //            The dialog will by default be modeless, unless you set 'modal' to
00061 //            true to construct a modal dialog.
00062 //=================================================================================
00063 MeasureGUI_DistanceDlg::MeasureGUI_DistanceDlg (GeometryGUI* GUI, QWidget* parent)
00064   : MeasureGUI_Skeleton(GUI, parent)
00065 {
00066   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
00067   QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MINDIST")));
00068   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
00069 
00070   setWindowTitle(tr("GEOM_MINDIST_TITLE"));
00071 
00072   /***************************************************************/
00073   mainFrame()->GroupConstructors->setTitle(tr("GEOM_DISTANCE"));
00074   mainFrame()->RadioButton1->setIcon(image0);
00075 
00076   myGrp = new MeasureGUI_2Sel4LineEdit(centralWidget());
00077   myGrp->GroupBox1->setTitle(tr("GEOM_MINDIST_OBJ"));
00078   myGrp->TextLabel1->setText(tr("GEOM_OBJECT_I").arg("1"));
00079   myGrp->TextLabel2->setText(tr("GEOM_OBJECT_I").arg("2"));
00080   myGrp->TextLabel3->setText(tr("GEOM_LENGTH"));
00081   myGrp->TextLabel4->setText(tr("GEOM_DX"));
00082   myGrp->TextLabel5->setText(tr("GEOM_DY"));
00083   myGrp->TextLabel6->setText(tr("GEOM_DZ"));
00084   myGrp->LineEdit3->setReadOnly(true);
00085   myGrp->PushButton1->setIcon(image1);
00086   myGrp->PushButton2->setIcon(image1);
00087   myGrp->LineEdit1->setReadOnly(true);
00088   myGrp->LineEdit2->setReadOnly(true);
00089   myGrp->LineEdit4->setReadOnly(true);
00090   myGrp->LineEdit5->setReadOnly(true);
00091   myGrp->LineEdit6->setReadOnly(true);
00092 
00093   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
00094   layout->setMargin(0); layout->setSpacing(6);
00095   layout->addWidget(myGrp);
00096   /***************************************************************/
00097 
00098   myHelpFileName = "using_measurement_tools_page.html#min_distance_anchor";
00099 
00100   // Initialisation
00101   Init();
00102 }
00103 
00104 //=================================================================================
00105 // function : ~MeasureGUI_DistanceDlg()
00106 // purpose  : Destroys the object and frees any allocated resources
00107 //=================================================================================
00108 MeasureGUI_DistanceDlg::~MeasureGUI_DistanceDlg()
00109 {
00110 }
00111 
00112 //=================================================================================
00113 // function : Init()
00114 // purpose  :
00115 //=================================================================================
00116 void MeasureGUI_DistanceDlg::Init()
00117 {
00118   // init variables
00119   myGrp->LineEdit1->setText("");
00120   myGrp->LineEdit2->setText("");
00121   myObj = myObj2 = GEOM::GEOM_Object::_nil();
00122 
00123   mySelBtn   = myGrp->PushButton1;
00124   mySelEdit  = myGrp->LineEdit1;
00125 
00126   myEditCurrentArgument = myGrp->LineEdit1;
00127 
00128   // signals and slots connections
00129   connect(myGrp->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
00130   connect(myGrp->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
00131 
00132   MeasureGUI_Skeleton::Init();
00133 }
00134 
00135 //=================================================================================
00136 // function : SelectionIntoArgument()
00137 // purpose  : Called when selection has changed
00138 //=================================================================================
00139 void MeasureGUI_DistanceDlg::SelectionIntoArgument()
00140 {
00141   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
00142   SALOME_ListIO aSelList;
00143   aSelMgr->selectedObjects(aSelList);
00144 
00145   GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil();
00146 
00147   if (aSelList.Extent() > 0) {
00148     aSelectedObject = GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
00149   }
00150 
00151   // clear selection
00152   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
00153   myGeomGUI->getApp()->selectionMgr()->clearSelected();
00154   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
00155           this, SLOT(SelectionIntoArgument()));
00156 
00157   if (myEditCurrentArgument == myGrp->LineEdit1) {
00158     myObj = aSelectedObject;
00159     if (!myObj->_is_nil() && myObj2->_is_nil())
00160       myGrp->PushButton2->click();
00161   }
00162   else {
00163     myObj2 = aSelectedObject;
00164     if (!myObj2->_is_nil() && myObj->_is_nil())
00165       myGrp->PushButton1->click();
00166   }
00167 
00168   processObject();
00169 }
00170 
00171 //=================================================================================
00172 // function : processObject()
00173 // purpose  : Fill dialogs fields in accordance with myObj and myObj2
00174 //=================================================================================
00175 void MeasureGUI_DistanceDlg::processObject()
00176 {
00177   myGrp->LineEdit1->setText(!myObj->_is_nil()  ? GEOMBase::GetName(myObj ) : "");
00178   myGrp->LineEdit2->setText(!myObj2->_is_nil() ? GEOMBase::GetName(myObj2) : "");
00179 
00180   gp_Pnt aPnt1, aPnt2;
00181   double aDist = 0.;
00182   if (getParameters(aDist, aPnt1, aPnt2)) {
00183     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
00184     int aPrecision = resMgr->integerValue( "Geometry", "length_precision", 6 );
00185 
00186     myGrp->LineEdit3->setText(DlgRef::PrintDoubleValue(aDist, aPrecision));
00187 
00188     gp_XYZ aVec = aPnt2.XYZ() - aPnt1.XYZ();
00189     myGrp->LineEdit4->setText(DlgRef::PrintDoubleValue(aVec.X(), aPrecision));
00190     myGrp->LineEdit5->setText(DlgRef::PrintDoubleValue(aVec.Y(), aPrecision));
00191     myGrp->LineEdit6->setText(DlgRef::PrintDoubleValue(aVec.Z(), aPrecision));
00192 
00193     redisplayPreview();
00194   }
00195   else {
00196     myGrp->LineEdit3->setText("");
00197     myGrp->LineEdit4->setText("");
00198     myGrp->LineEdit5->setText("");
00199     myGrp->LineEdit6->setText("");
00200     erasePreview();
00201   }
00202 }
00203 
00204 //=================================================================================
00205 // function : getParameters()
00206 // purpose  : Get distance between objects
00207 //=================================================================================
00208 bool MeasureGUI_DistanceDlg::getParameters (double& theDistance,
00209                                             gp_Pnt& thePnt1,
00210                                             gp_Pnt& thePnt2)
00211 {
00212   QString msg;
00213   if (isValid(msg)) {
00214     GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow( getOperation() );
00215 
00216     try {
00217       double x1, y1, z1, x2, y2, z2;
00218       theDistance = anOper->GetMinDistance(myObj, myObj2, x1, y1, z1, x2, y2, z2);
00219 
00220       thePnt1.SetCoord(x1, y1, z1);
00221       thePnt2.SetCoord(x2, y2, z2);
00222     }
00223     catch(const SALOME::SALOME_Exception& e) {
00224       SalomeApp_Tools::QtCatchCorbaException(e);
00225       return false;
00226     }
00227 
00228     return anOper->IsDone();
00229   }
00230 
00231   return false;
00232 }
00233 
00234 //=================================================================================
00235 // function : SetEditCurrentArgument()
00236 // purpose  :
00237 //=================================================================================
00238 void MeasureGUI_DistanceDlg::SetEditCurrentArgument()
00239 {
00240   QPushButton* send = (QPushButton*)sender();
00241 
00242   if (send == myGrp->PushButton1) {
00243     myEditCurrentArgument = myGrp->LineEdit1;
00244 
00245     myGrp->PushButton2->setDown(false);
00246     myGrp->LineEdit2->setEnabled(false);
00247   }
00248   else {
00249     myEditCurrentArgument = myGrp->LineEdit2;
00250 
00251     myGrp->PushButton1->setDown(false);
00252     myGrp->LineEdit1->setEnabled(false);
00253   }
00254 
00255   // enable line edit
00256   myEditCurrentArgument->setEnabled(true);
00257   myEditCurrentArgument->setFocus();
00258   // after setFocus(), because it will be setDown(false) when loses focus
00259   send->setDown(true);
00260 
00261   // seems we need it only to avoid preview disappearing, caused by selection mode change
00262   redisplayPreview();
00263 }
00264 
00265 //=================================================================================
00266 // function : LineEditReturnPressed()
00267 // purpose  :
00268 //=================================================================================
00269 void MeasureGUI_DistanceDlg::LineEditReturnPressed()
00270 {
00271   QLineEdit* send = (QLineEdit*)sender();
00272 
00273   if (send == myGrp->LineEdit1 || send == myGrp->LineEdit2) {
00274     myEditCurrentArgument = send;
00275 
00276     LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
00277     SALOME_ListIO aSelList;
00278     aSelMgr->selectedObjects(aSelList);
00279 
00280     if (GEOMBase::SelectionByNameInDialogs(this, myGrp->LineEdit1->text(), aSelList))
00281       myGrp->LineEdit1->setText(myGrp->LineEdit1->text());
00282   }
00283 }
00284 
00285 //=================================================================================
00286 // function : buildPrs()
00287 // purpose  :
00288 //=================================================================================
00289 SALOME_Prs* MeasureGUI_DistanceDlg::buildPrs()
00290 {
00291   double aDist = 0.;
00292   gp_Pnt aPnt1(0, 0, 0), aPnt2(0, 0, 0);
00293 
00294   SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
00295 
00296   if (myObj->_is_nil() || myObj2->_is_nil() ||
00297        !getParameters(aDist, aPnt1, aPnt2) ||
00298        vw->getViewManager()->getType() != OCCViewer_Viewer::Type())
00299     return 0;
00300 
00301   try
00302   {
00303     if (aDist <= 1.e-9) {
00304       BRepBuilderAPI_MakeVertex aMaker(aPnt1);
00305       return getDisplayer()->BuildPrs(aMaker.Vertex());
00306     }
00307     else {
00308       BRepBuilderAPI_MakeEdge MakeEdge(aPnt1, aPnt2);
00309       TopoDS_Vertex aVert1 = BRepBuilderAPI_MakeVertex(aPnt1);
00310       TopoDS_Vertex aVert2 = BRepBuilderAPI_MakeVertex(aPnt2);
00311 
00312       QString aLabel;
00313       aLabel.sprintf("%.1f", aDist);
00314 
00315       gp_Pnt aPnt3((aPnt1.X() + aPnt2.X()) / 2,
00316                     (aPnt1.Y() + aPnt2.Y()) / 2,
00317                     (aPnt1.Z() + aPnt2.Z()) / 2);
00318 
00319       gp_Vec va(aPnt3, aPnt1);
00320       gp_Vec vb(aPnt3, aPnt2);
00321 
00322       if (va.IsParallel(vb, Precision::Angular())) {
00323         aPnt3.SetY((aPnt1.Y() + aPnt2.Y()) / 2 + 100);
00324         aPnt3.SetZ((aPnt1.Z() + aPnt2.Z()) / 2);
00325       }
00326 
00327       gce_MakePln gce_MP(aPnt1, aPnt2, aPnt3);
00328       Handle(Geom_Plane) P = new Geom_Plane(gce_MP.Value());
00329 
00330       Handle(AIS_LengthDimension) anIO = new AIS_LengthDimension(
00331         aVert1, aVert2, P, aDist, TCollection_ExtendedString((Standard_CString)aLabel.toLatin1().constData()));
00332       anIO->SetArrowSize(aDist/20);
00333       
00334       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
00335       int w = resMgr->integerValue("Geometry", "measures_line_width", 1);
00336       Handle(Prs3d_LengthAspect) asp = new Prs3d_LengthAspect();
00337       asp->LineAspect()->SetWidth(w);
00338       anIO->Attributes()->SetLengthAspect(asp);
00339 
00340       SOCC_Prs* aPrs = dynamic_cast<SOCC_Prs*>(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0));
00341 
00342       if (aPrs)
00343         aPrs->AddObject(anIO);
00344 
00345       return aPrs;
00346     }
00347   }
00348   catch(Standard_Failure) {
00349     return 0;
00350   }
00351 }
00352 
00353 //=================================================================================
00354 // function : isValid()
00355 // purpose  :
00356 //=================================================================================
00357 bool MeasureGUI_DistanceDlg::isValid (QString& msg)
00358 {
00359   return MeasureGUI_Skeleton::isValid(msg) && !myObj2->_is_nil();
00360 }