X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_ComputeDlg.cxx;fp=src%2FSMESHGUI%2FSMESHGUI_ComputeDlg.cxx;h=51d62037b2b8d48617ca9718e9b1787ce568c906;hb=79b1ac2b6df9117f16f11d444b1f165d477a1813;hp=0000000000000000000000000000000000000000;hpb=984c4ffdd7df62aeaedc544cd0b8e64ff8f53f1a;p=modules%2Fsmesh.git diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx new file mode 100644 index 000000000..51d62037b --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -0,0 +1,1146 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// +// +// File : SMESHGUI_ComputeDlg.cxx +// Author : Edward AGAPOV +// Module : SMESH + +#include "SMESHGUI_ComputeDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_GEOMGenUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_HypothesesUtils.h" + +#include "SMDS_SetIterator.hxx" +#include + +#include "GEOMBase.h" +#include "GEOM_Actor.h" + +#include "LightApp_SelectionMgr.h" +#include "LightApp_UpdateFlags.h" +#include "SALOMEDSClient_SObject.hxx" +#include "SALOME_ListIO.hxx" +#include "SVTK_ViewWindow.h" +#include "SVTK_ViewModel.h" +#include "SalomeApp_Tools.h" +#include "SalomeApp_Application.h" +#include "SUIT_ResourceMgr.h" +#include "SUIT_OverrideCursor.h" +#include "SUIT_MessageBox.h" +#include "SUIT_Desktop.h" +#include "SUIT_Study.h" +#include "OB_Browser.h" + +// OCCT Includes +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// IDL Headers +#include +#include CORBA_SERVER_HEADER(SMESH_Gen) +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +#include +#include + + +#define SPACING 5 +#define MARGIN 10 + +#define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" ) + +#define _SEPARATOR(father) \ +{\ + /*new QLabel(father); new QLabel(father); new QLabel(father)*/;\ + (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\ + (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\ + (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\ + (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\ +} + +enum TCol { COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, NB_COLUMNS }; + +using namespace SMESH; + +namespace SMESH { + + //============================================================================= + /*! + * \brief Allocate some memory at construction and release it at destruction. + * Is used to be able to continue working after mesh generation or visualization + * break due to lack of memory + */ + //============================================================================= + + struct MemoryReserve + { + char* myBuf; + MemoryReserve(): myBuf( new char[1024*1024*1] ){} // 1M + ~MemoryReserve() { delete [] myBuf; } + }; + + // ========================================================================================= + /*! + * \brief Class showing shapes without publishing + */ + // ========================================================================================= + + class TShapeDisplayer + { + public: + // ----------------------------------------------------------------------- + TShapeDisplayer(): myViewWindow(0) + { + myProperty = vtkProperty::New(); + myProperty->SetRepresentationToWireframe(); + myProperty->SetColor( 250, 0, 250 ); + myProperty->SetAmbientColor( 250, 0, 250 ); + myProperty->SetDiffuseColor( 250, 0, 250 ); + //myProperty->SetSpecularColor( 250, 0, 250 ); + myProperty->SetLineWidth( 5 ); + } + // ----------------------------------------------------------------------- + ~TShapeDisplayer() + { + DeleteActors(); + myProperty->Delete(); + } + // ----------------------------------------------------------------------- + void DeleteActors() + { + if ( hasViewWindow() ) { + TActorIterator actorIt = actorIterator(); + while ( actorIt.more() ) + if (VTKViewer_Actor* anActor = actorIt.next()) { + myViewWindow->RemoveActor( anActor ); + //anActor->Delete(); + } + } + myIndexToShape.Clear(); + myActors.clear(); + myShownActors.clear(); + myBuiltSubs.clear(); + } + // ----------------------------------------------------------------------- + void SetVisibility (bool theVisibility) + { + TActorIterator actorIt = shownIterator(); + while ( actorIt.more() ) + if (VTKViewer_Actor* anActor = actorIt.next()) + anActor->SetVisibility(theVisibility); + SMESH::RepaintCurrentView(); + } + // ----------------------------------------------------------------------- + bool HasReadyActorsFor (int subShapeID, GEOM::GEOM_Object_var aMainShape ) + { + string mainEntry; + if ( !aMainShape->_is_nil() ) + mainEntry = aMainShape->GetStudyEntry(); + return ( myMainEntry == mainEntry && + myBuiltSubs.find( subShapeID ) != myBuiltSubs.end() ); + } + // ----------------------------------------------------------------------- + void Show( int subShapeID, GEOM::GEOM_Object_var aMainShape, bool only = false) + { + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ); + string mainEntry; + if ( !aMainShape->_is_nil() ) + mainEntry = aMainShape->GetStudyEntry(); + if ( myMainEntry != mainEntry || aViewWindow != myViewWindow ) { // remove actors + DeleteActors(); + TopoDS_Shape aShape; + if ( !aMainShape->_is_nil() && GEOMBase::GetShape(aMainShape, aShape)) { + checkTriangulation( aShape ); + TopExp::MapShapes(aShape, myIndexToShape); + myActors.resize( myIndexToShape.Extent(), 0 ); + myShownActors.reserve( myIndexToShape.Extent() ); + } + myMainEntry = mainEntry; + myViewWindow = aViewWindow; + } + if ( only ) { // hide shown actors + TActorIterator actorIt = shownIterator(); + while ( actorIt.more() ) + if (VTKViewer_Actor* anActor = actorIt.next()) + anActor->SetVisibility(false); + myShownActors.clear(); + } + // find actors to show + TopoDS_Shape aShape = myIndexToShape( subShapeID ); + if ( !aShape.IsNull() ) { + TopAbs_ShapeEnum type( aShape.ShapeType() >= TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE ); + for ( TopExp_Explorer exp( aShape, type ); exp.More(); exp.Next() ) { + //checkTriangulation( exp.Current() ); + if ( GEOM_Actor* anActor = getActor( exp.Current() )) + myShownActors.push_back( anActor ); + } + if ( type == TopAbs_FACE ) { + for ( TopExp_Explorer exp( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) { + const TopoDS_Edge & edge = TopoDS::Edge( exp.Current() ); + if ( !BRep_Tool::Degenerated( edge )) + if ( GEOM_Actor* anActor = getActor( exp.Current() )) + myShownActors.push_back( anActor ); + } + } + } + myBuiltSubs.insert( subShapeID ); + SetVisibility(true); + } + // ----------------------------------------------------------------------- + + private: + + typedef std::vector TActorVec; + TActorVec myActors; + TActorVec myShownActors; + TopTools_IndexedMapOfShape myIndexToShape; + string myMainEntry; + SVTK_ViewWindow* myViewWindow; + vtkProperty* myProperty; + std::set myBuiltSubs; + + // ----------------------------------------------------------------------- + typedef SMDS_SetIterator< GEOM_Actor*, TActorVec::const_iterator> TActorIterator; + TActorIterator actorIterator() { + return TActorIterator( myActors.begin(), myActors.end() ); + } + TActorIterator shownIterator() { + return TActorIterator( myShownActors.begin(), myShownActors.end() ); + } + // ----------------------------------------------------------------------- + GEOM_Actor* getActor(const TopoDS_Shape& shape) + { + int index = myIndexToShape.FindIndex( shape ) - 1; + if ( index < 0 || index >= myActors.size() ) + return 0; + GEOM_Actor* & actor = myActors[ index ]; + if ( !actor ) { + actor = GEOM_Actor::New(); + if ( actor ) { + actor->setInputShape(shape,0,0); + //actor->SetProperty(myProperty); + actor->SetShadingProperty(myProperty); + actor->SetWireframeProperty(myProperty); + actor->SetPreviewProperty(myProperty); + actor->PickableOff(); + // if ( shape.ShapeType() == TopAbs_EDGE ) + // actor->SubShapeOn(); + myViewWindow->AddActor( actor ); + } + } + return actor; + } + // ----------------------------------------------------------------------- + void checkTriangulation(const TopoDS_Shape& shape) + { + TopLoc_Location aLoc; + Standard_Boolean alreadymesh = Standard_True; + TopExp_Explorer ex(shape, TopAbs_FACE); + if ( ex.More() ) + for (; ex.More(); ex.Next()) { + const TopoDS_Face& aFace = TopoDS::Face(ex.Current()); + Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); + if(aPoly.IsNull()) { alreadymesh = Standard_False; break; } + } + else + for (ex.Init(shape, TopAbs_EDGE); ex.More(); ex.Next()) { + const TopoDS_Edge& edge = TopoDS::Edge(ex.Current()); + Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(edge, aLoc); + if(aPoly.IsNull()) { alreadymesh = Standard_False; break; } + } + if (alreadymesh) return; + // Compute default deflection + Bnd_Box B; + BRepBndLib::Add(shape, B); + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + double deflection = Max( aXmax-aXmin , Max ( aYmax-aYmin , aZmax-aZmin)) * 0.01 *4; + BRepMesh_IncrementalMesh MESH(shape,deflection); + } + // ----------------------------------------------------------------------- + bool hasViewWindow() const + { + if ( !myViewWindow ) return false; + + if ( SalomeApp_Application* anApp = SMESHGUI::GetSMESHGUI()->getApp() ) + return FindVtkViewWindow( anApp->getViewManager(SVTK_Viewer::Type(), false ), + myViewWindow ); + return false; + } + }; + + // ========================================================================================= + /*! + * \brief Return text describing an error + */ +#define CASE2TEXT(enum) case SMESH::enum: text = QObject::tr( #enum ); break; + QString errorText(int errCode, const char* comment) + { + QString text; + switch ( errCode ) { + CASE2TEXT( COMPERR_OK ); + CASE2TEXT( COMPERR_BAD_INPUT_MESH); + CASE2TEXT( COMPERR_STD_EXCEPTION ); + CASE2TEXT( COMPERR_OCC_EXCEPTION ); + case SMESH::COMPERR_SLM_EXCEPTION: break; // avoid double "Salome exception" + CASE2TEXT( COMPERR_EXCEPTION ); + CASE2TEXT( COMPERR_MEMORY_PB ); + CASE2TEXT( COMPERR_BAD_SHAPE ); + case SMESH::COMPERR_ALGO_FAILED: + if ( strlen(comment) == 0 ) + text = QObject::tr("COMPERR_ALGO_FAILED"); + break; + default: + text = QString("#%1").arg( -errCode ); + } + if ( text.length() > 0 ) text += ". "; + return text + comment; + } + // ----------------------------------------------------------------------- + /*! + * \brief Return SO of a subshape + */ + _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape) + { + _PTR(SObject) so = SMESH::FindSObject(aMainShape); + if ( subShapeID == 1 || !so ) + return so; + _PTR(ChildIterator) it; + if (_PTR(Study) study = SMESH::GetActiveStudyDocument()) + it = study->NewChildIterator(so); + _PTR(SObject) subSO; + if ( it ) { + for ( it->InitEx(true); !subSO && it->More(); it->Next() ) { + GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface( it->Value() ); + if ( !geom->_is_nil() ) { + GEOM::ListOfLong_var list = geom->GetSubShapeIndices(); + if ( list->length() == 1 && list[0] == subShapeID ) + subSO = it->Value(); + } + } + } + return subSO; + } + // ----------------------------------------------------------------------- + /*! + * \brief Return subshape by ID + */ + GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape) + { + GEOM::GEOM_Object_var aSubShape; + if ( subShapeID == 1 ) + aSubShape = aMainShape; + else if ( _PTR(SObject) so = getSubShapeSO( subShapeID, aMainShape )) + aSubShape = SMESH::SObjectToInterface( so ); + else + aSubShape = SMESH::GetSubShape( aMainShape, subShapeID ); + return aSubShape._retn(); + } + // ----------------------------------------------------------------------- + /*! + * \brief Return shape type name + */ +#define CASE2NAME(enum) case GEOM::enum: name = QObject::tr( "GEOM_" #enum ); break; + QString shapeTypeName(GEOM::GEOM_Object_var aShape, const char* dflt = "" ) + { + QString name = dflt; + if ( !aShape->_is_nil() ) { + switch ( aShape->GetShapeType() ) { + CASE2NAME( VERTEX ); + CASE2NAME( EDGE ); + CASE2NAME( WIRE ); + CASE2NAME( FACE ); + CASE2NAME( SHELL ); + CASE2NAME( SOLID ); + CASE2NAME( COMPSOLID ); + CASE2NAME( COMPOUND ); + default:; + } + } + return name; + } + // ----------------------------------------------------------------------- + /*! + * \brief Return text describing a subshape + */ + QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape ) + { + QString text; + if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape )) + text = aSO->GetName(); + else { + text = QString("#%1").arg( subShapeID ); + QString typeName = shapeTypeName( getSubShape( subShapeID, aMainShape )); + if ( typeName.length() ) + text += QString(" (%1)").arg(typeName); + } + return text; + } + // ----------------------------------------------------------------------- + /*! + * \brief Return a list of selected rows + */ + bool getSelectedRows(QTable* table, list< int > & rows) + { + rows.clear(); + int nbSel = table->numSelections(); + for ( int i = 0; i < nbSel; ++i ) + { + QTableSelection selected = table->selection(i); + if ( !selected.isActive() ) continue; + for ( int row = selected.topRow(); row <= selected.bottomRow(); ++row ) + rows.push_back( row ); + } + if (rows.empty() && table->currentRow() > -1 ) + rows.push_back( table->currentRow() ); + + return !rows.empty(); + } + +} // namespace SMESH + + +// ========================================================================================= +/*! + * \brief Box showing mesh info + */ +// ========================================================================================= + +SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent) + :QGroupBox( 4, Qt::Horizontal, tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full ) +{ + // title + QLabel* lab1 = new QLabel(this); + QLabel* lab2 = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this ); + QLabel* lab3 = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this ); + QLabel* lab4 = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this ); + + QFont italic = lab1->font(); italic.setItalic(true); + QFont bold = lab1->font(); bold.setBold(true); + + lab1->setMinimumWidth(100); lab1->setFont( italic ); + lab2->setMinimumWidth(100); lab2->setFont( italic ); + lab3->setMinimumWidth(100); lab3->setFont( italic ); + lab4->setMinimumWidth(100); lab4->setFont( italic ); + + if ( myFull ) + { + // nodes + (new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ))->setFont( bold ); + myNbNode = new QLabel( this ); + new QLabel(this); + new QLabel(this); + + _SEPARATOR(this); + + // edges + (new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ))->setFont( bold ); + myNbEdge = new QLabel( this ); + myNbLinEdge = new QLabel( this ); + myNbQuadEdge = new QLabel( this ); + + _SEPARATOR(this); + + // faces + (new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this))->setFont( bold ); + myNbFace = new QLabel( this ); + myNbLinFace = new QLabel( this ); + myNbQuadFace = new QLabel( this ); + // triangles + new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this ); + myNbTrai = new QLabel( this ); + myNbLinTrai = new QLabel( this ); + myNbQuadTrai = new QLabel( this ); + // quadrangles + new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this ); + myNbQuad = new QLabel( this ); + myNbLinQuad = new QLabel( this ); + myNbQuadQuad = new QLabel( this ); + // poligones + new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this ); + myNbPolyg = new QLabel( this ); + new QLabel("",this ); + new QLabel("", this ); + + _SEPARATOR(this); + + // volumes + (new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this))->setFont( bold ); + myNbVolum = new QLabel( this ); + myNbLinVolum = new QLabel( this ); + myNbQuadVolum = new QLabel( this ); + // tetras + new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this ); + myNbTetra = new QLabel( this ); + myNbLinTetra = new QLabel( this ); + myNbQuadTetra = new QLabel( this ); + // hexas + new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this ); + myNbHexa = new QLabel( this ); + myNbLinHexa = new QLabel( this ); + myNbQuadHexa = new QLabel( this ); + // pyras + new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this ); + myNbPyra = new QLabel( this ); + myNbLinPyra = new QLabel( this ); + myNbQuadPyra = new QLabel( this ); + // prisms + new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this ); + myNbPrism = new QLabel( this ); + myNbLinPrism = new QLabel( this ); + myNbQuadPrism = new QLabel( this ); + // polyedres + new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this ); + myNbPolyh = new QLabel( this ); + new QLabel("", this ); + new QLabel("", this ); + } + else + { + // nodes + new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ); + myNbNode = new QLabel( this ); + new QLabel(this); + new QLabel(this); + + // edges + new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ); + myNbEdge = new QLabel( this ); + myNbLinEdge = new QLabel( this ); + myNbQuadEdge = new QLabel( this ); + + // faces + new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this); + myNbFace = new QLabel( this ); + myNbLinFace = new QLabel( this ); + myNbQuadFace = new QLabel( this ); + + // volumes + new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this); + myNbVolum = new QLabel( this ); + myNbLinVolum = new QLabel( this ); + myNbQuadVolum = new QLabel( this ); + } +} + +// ========================================================================================= +/*! + * \brief Set mesh info + */ +// ========================================================================================= + +void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh) +{ + const SMESH::ElementOrder lin = SMESH::ORDER_LINEAR; + int nbTot, nbLin; + + // nodes + myNbNode ->setText( QString("%1").arg( mesh->NbNodes() )); + + // edges + nbTot = mesh->NbEdges(), nbLin = mesh->NbEdgesOfOrder(lin); + myNbEdge ->setText( QString("%1").arg( nbTot )); + myNbLinEdge ->setText( QString("%1").arg( nbLin )); + myNbQuadEdge ->setText( QString("%1").arg( nbTot - nbLin )); + + // faces + nbTot = mesh->NbFaces(), nbLin = mesh->NbFacesOfOrder(lin); + myNbFace ->setText( QString("%1").arg( nbTot )); + myNbLinFace ->setText( QString("%1").arg( nbLin )); + myNbQuadFace ->setText( QString("%1").arg( nbTot - nbLin )); + + // volumes + nbTot = mesh->NbVolumes(), nbLin = mesh->NbVolumesOfOrder(lin); + myNbVolum ->setText( QString("%1").arg( nbTot )); + myNbLinVolum ->setText( QString("%1").arg( nbLin )); + myNbQuadVolum->setText( QString("%1").arg( nbTot - nbLin )); + + if ( myFull ) + { + // triangles + nbTot = mesh->NbTriangles(), nbLin = mesh->NbTrianglesOfOrder(lin); + myNbTrai ->setText( QString("%1").arg( nbTot )); + myNbLinTrai ->setText( QString("%1").arg( nbLin )); + myNbQuadTrai ->setText( QString("%1").arg( nbTot - nbLin )); + // quadrangles + nbTot = mesh->NbQuadrangles(), nbLin = mesh->NbQuadranglesOfOrder(lin); + myNbQuad ->setText( QString("%1").arg( nbTot )); + myNbLinQuad ->setText( QString("%1").arg( nbLin )); + myNbQuadQuad ->setText( QString("%1").arg( nbTot - nbLin )); + // poligones + myNbPolyg ->setText( QString("%1").arg( mesh->NbPolygons() )); + + // tetras + nbTot = mesh->NbTetras(), nbLin = mesh->NbTetrasOfOrder(lin); + myNbTetra ->setText( QString("%1").arg( nbTot )); + myNbLinTetra ->setText( QString("%1").arg( nbLin )); + myNbQuadTetra->setText( QString("%1").arg( nbTot - nbLin )); + // hexas + nbTot = mesh->NbHexas(), nbLin = mesh->NbHexasOfOrder(lin); + myNbHexa ->setText( QString("%1").arg( nbTot )); + myNbLinHexa ->setText( QString("%1").arg( nbLin )); + myNbQuadHexa ->setText( QString("%1").arg( nbTot - nbLin )); + // pyras + nbTot = mesh->NbPyramids(), nbLin = mesh->NbPyramidsOfOrder(lin); + myNbPyra ->setText( QString("%1").arg( nbTot )); + myNbLinPyra ->setText( QString("%1").arg( nbLin )); + myNbQuadPyra ->setText( QString("%1").arg( nbTot - nbLin )); + // prisms + nbTot = mesh->NbPrisms(), nbLin = mesh->NbPrismsOfOrder(lin); + myNbPrism ->setText( QString("%1").arg( nbTot )); + myNbLinPrism ->setText( QString("%1").arg( nbLin )); + myNbQuadPrism->setText( QString("%1").arg( nbTot - nbLin )); + // polyedres + myNbPolyh ->setText( QString("%1").arg( mesh->NbPolyhedrons() )); + } +} + +// ========================================================================================= +/*! + * \brief Dialog to compute a mesh and show computation errors + */ +//======================================================================= + +SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, OK/* | Help*/ ) +{ + QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame(), 0, SPACING); + + QFrame* aMainFrame = createMainFrame (mainFrame()); + + aDlgLay->addWidget(aMainFrame); + + aDlgLay->setStretchFactor(aMainFrame, 1); +} + +//======================================================================= +// function : createMainFrame() +// purpose : Create frame containing dialog's fields +//======================================================================= + +#define CASE2HEADER(enum) case enum: header = QObject::tr( #enum "_HEADER" ); break; + +QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent) +{ + QFrame* aFrame = new QFrame(theParent); + + SUIT_ResourceMgr* rm = resourceMgr(); + QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_COMPUTE"))); + + // constructor + + QButtonGroup* aPixGrp = new QButtonGroup(1, Qt::Vertical, tr("CONSTRUCTOR"), aFrame); + aPixGrp->setExclusive(TRUE); + QRadioButton* aRBut = new QRadioButton(aPixGrp); + aRBut->setPixmap(iconCompute); + aRBut->setChecked(TRUE); + + // Mesh name + + QHGroupBox* nameBox = new QHGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame ); + myMeshName = new QLabel(nameBox); + + // Mesh Info + + myBriefInfo = new SMESHGUI_MeshInfosBox(false, aFrame); + myFullInfo = new SMESHGUI_MeshInfosBox(true, aFrame); + + // Computation errors + + myCompErrorGroup = new QGroupBox(tr("ERRORS"), aFrame, "myCompErrorGroup"); + myTable = new QTable( 1, NB_COLUMNS, myCompErrorGroup, "myTable"); + myShowBtn = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup, "myShowBtn"); + myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup, "myPublishBtn"); + + myTable->setReadOnly( TRUE ); + myTable->hideColumn( COL_PUBLISHED ); + myTable->hideColumn( COL_SHAPEID ); + myTable->setColumnStretchable( COL_ERROR, 1 ); + for ( int col = 0; col < NB_COLUMNS; ++col ) { + QString header; + switch ( col ) { + CASE2HEADER( COL_ALGO ); + CASE2HEADER( COL_SHAPE ); + CASE2HEADER( COL_ERROR ); + CASE2HEADER( COL_SHAPEID ); + CASE2HEADER( COL_PUBLISHED); + } + myTable->horizontalHeader()->setLabel( col, header ); + } + // layouting + myCompErrorGroup->setColumnLayout(0, Qt::Vertical); + myCompErrorGroup->layout()->setSpacing(0); + myCompErrorGroup->layout()->setMargin(0); + QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup->layout()); + grpLayout->setAlignment(Qt::AlignTop); + grpLayout->setSpacing(SPACING); + grpLayout->setMargin(MARGIN); + grpLayout->addMultiCellWidget( myTable, 0, 2, 0, 0 ); + grpLayout->addWidget ( myShowBtn, 0, 1 ); + grpLayout->addWidget ( myPublishBtn, 1, 1 ); + grpLayout->setRowStretch( 2, 1 ); + + // Hypothesis definition errors + + myHypErrorGroup = new QGroupBox(1,Qt::Vertical, tr("SMESH_WRN_MISSING_PARAMETERS"),aFrame); + myHypErrorLabel = new QLabel(myHypErrorGroup); + + // Memory Lack Label + + myMemoryLackGroup = new QVGroupBox(tr("ERRORS"), aFrame, "memlackGrBox"); + QLabel* memLackLabel = new QLabel(tr("MEMORY_LACK"), myMemoryLackGroup); + QFont bold = memLackLabel->font(); bold.setBold(true); + memLackLabel->setFont( bold ); + memLackLabel->setMinimumWidth(300); + + // add all widgets to aFrame + QVBoxLayout* aLay = new QVBoxLayout(aFrame); + aLay->addWidget( aPixGrp ); + aLay->addWidget( nameBox ); + aLay->addWidget( myBriefInfo ); + aLay->addWidget( myFullInfo ); + aLay->addWidget( myHypErrorGroup ); + aLay->addWidget( myCompErrorGroup ); + aLay->addWidget( myMemoryLackGroup ); + aLay->setStretchFactor( myCompErrorGroup, 1 ); + + ((QPushButton*) button( OK ))->setDefault( true ); + + return aFrame; +} + +//================================================================================ +/*! + * \brief Constructor +*/ +//================================================================================ + +SMESHGUI_ComputeOp::SMESHGUI_ComputeOp() +{ + myDlg = new SMESHGUI_ComputeDlg; + myTShapeDisplayer = new TShapeDisplayer(); + //myHelpFileName = "/files/about_meshes.htm"; // V3 + myHelpFileName = "about_meshes_page.html"; // V4 + + // connect signals and slots + connect(myDlg->myShowBtn, SIGNAL (clicked()), SLOT(onPreviewShape())); + connect(myDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape())); + connect(table(),SIGNAL(selectionChanged()), SLOT(currentCellChanged())); + connect(table(),SIGNAL(currentChanged(int,int)), SLOT(currentCellChanged())); +} + +//======================================================================= +// function : startOperation() +// purpose : Init dialog fields, connect signals and slots, show dialog +//======================================================================= + +void SMESHGUI_ComputeOp::startOperation() +{ + SMESHGUI_Operation::startOperation(); + + // check selection + + SMESH::SMESH_Mesh_var aMesh; + myMainShape = GEOM::GEOM_Object::_nil(); + + LightApp_SelectionMgr *Sel = selectionMgr(); + SALOME_ListIO selected; Sel->selectedObjects( selected ); + + int nbSel = selected.Extent(); + if (nbSel != 1) { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NO_AVAILABLE_DATA"), + tr("SMESH_BUT_OK")); + onCancel(); + return; + } + + Handle(SALOME_InteractiveObject) IObject = selected.First(); + aMesh = SMESH::GetMeshByIO(IObject); + if (aMesh->_is_nil()) { + SUIT_MessageBox::warn1(desktop(), + tr("SMESH_WRN_WARNING"), + tr("SMESH_WRN_NO_AVAILABLE_DATA"), + tr("SMESH_BUT_OK")); + onCancel(); + return; + } + + // COMPUTE MESH + + MemoryReserve aMemoryReserve; + + SMESH::compute_error_array_var aCompErrors; + QString aHypErrors; + + bool computeFailed = true, memoryLack = false; + + _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh); + myMainShape = aMesh->GetShapeToMesh(); + bool hasShape = aMesh->HasShapeToMesh(); + bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape; + if ( shapeOK && aMeshSObj ) + { + myDlg->myMeshName->setText( aMeshSObj->GetName() ); + SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen(); + SMESH::algo_error_array_var errors = gen->GetAlgoState(aMesh,myMainShape); + if ( errors->length() > 0 ) { + aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() ); + } + SUIT_OverrideCursor aWaitCursor; + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + if (gen->Compute(aMesh, myMainShape)) + computeFailed = false; + } + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + } + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + aCompErrors = gen->GetComputeErrors( aMesh, myMainShape ); + // check if there are memory problems + for ( int i = 0; (i < aCompErrors->length()) && !memoryLack; ++i ) + memoryLack = ( aCompErrors[ i ].code == SMESH::COMPERR_MEMORY_PB ); + } + catch(const SALOME::SALOME_Exception & S_ex){ + memoryLack = true; + } + + // NPAL16631: if ( !memoryLack ) + { + SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0); + update( UF_ObjBrowser | UF_Model ); + + // SHOW MESH + // NPAL16631: if ( getSMESHGUI()->automaticUpdate() ) + if ( !memoryLack && getSMESHGUI()->automaticUpdate() ) + { + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + SMESH::Update(IObject, true); + } + catch (...) { +#ifdef _DEBUG_ + cout << "Exception thrown during mesh visualization" << endl; +#endif + if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? + SMESH::OnVisuException(); + } + else { + memoryLack = true; + } + } + } + Sel->setSelectedObjects( selected ); + } + } + myDlg->setCaption(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED")); + myDlg->myMemoryLackGroup->hide(); + + // SHOW ERRORS + + bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 ); + bool noHypoError = ( aHypErrors.isEmpty() ); + + if ( memoryLack ) + { + myDlg->myMemoryLackGroup->show(); + myDlg->myFullInfo->hide(); + myDlg->myBriefInfo->hide(); + myDlg->myHypErrorGroup->hide(); + myDlg->myCompErrorGroup->hide(); + } + else if ( noCompError && noHypoError ) + { + myDlg->myFullInfo->SetInfoByMesh( aMesh ); + myDlg->myFullInfo->show(); + myDlg->myBriefInfo->hide(); + myDlg->myHypErrorGroup->hide(); + myDlg->myCompErrorGroup->hide(); + } + else + { + QTable* tbl = myDlg->myTable; + myDlg->myBriefInfo->SetInfoByMesh( aMesh ); + myDlg->myBriefInfo->show(); + myDlg->myFullInfo->hide(); + + if ( noHypoError ) { + myDlg->myHypErrorGroup->hide(); + } + else { + myDlg->myHypErrorGroup->show(); + myDlg->myHypErrorLabel->setText( aHypErrors ); + } + + if ( noCompError ) { + myDlg->myCompErrorGroup->hide(); + } + else { + myDlg->myCompErrorGroup->show(); + + if ( !hasShape ) { + myDlg->myPublishBtn->hide(); + myDlg->myShowBtn->hide(); + } + else { + myDlg->myPublishBtn->show(); + myDlg->myShowBtn->show(); + } + + // fill table of errors + tbl->setNumRows( aCompErrors->length() ); + if ( !hasShape ) tbl->hideColumn( COL_SHAPE ); + else tbl->showColumn( COL_SHAPE ); + tbl->setColumnWidth( COL_ERROR, 200 ); + + for ( int row = 0; row < aCompErrors->length(); ++row ) + { + SMESH::ComputeError & err = aCompErrors[ row ]; + tbl->setText( row, COL_ALGO, err.algoName.in() ); + tbl->setText( row, COL_ERROR, errorText( err.code, err.comment.in() )); + tbl->setText( row, COL_SHAPEID, QString("%1").arg( err.subShapeID )); + + QString text = hasShape ? shapeText( err.subShapeID, myMainShape ) : QString(""); + tbl->setText( row, COL_SHAPE, text ); + + text = ( !hasShape || getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : ""; + tbl->setText( row, COL_PUBLISHED, text ); // if text=="", "PUBLISH" button enabled + + tbl->item( row, COL_ERROR )->setWordWrap( TRUE ); + tbl->adjustRow( row ); + } + tbl->adjustColumn( COL_ALGO ); + tbl->adjustColumn( COL_SHAPE ); + + tbl->setCurrentCell(0,0); + currentCellChanged(); // to update buttons + } + } + myDlg->show(); +} + +//================================================================================ +/*! + * \brief Stops operation + */ +//================================================================================ + +void SMESHGUI_ComputeOp::stopOperation() +{ + SMESHGUI_Operation::stopOperation(); + myTShapeDisplayer->SetVisibility( false ); +} + +//================================================================================ +/*! + * \brief publish selected subshape + */ +//================================================================================ + +void SMESHGUI_ComputeOp::onPublishShape() +{ + GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen(); + SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy(); + + list< int > rows; + list< int >::iterator row; + getSelectedRows( table(), rows ); + for ( row = rows.begin(); row != rows.end(); ++row ) + { + int curSub = table()->text(*row, COL_SHAPEID).toInt(); + GEOM::GEOM_Object_var shape = getSubShape( curSub, myMainShape ); + if ( !shape->_is_nil() && ! getSubShapeSO( curSub, myMainShape )) + { + if ( !getSubShapeSO( 1, myMainShape )) // the main shape not published + { + QString name = GEOMBase::GetDefaultName( shapeTypeName( myMainShape, "MAIN_SHAPE" )); + SALOMEDS::SObject_var so = + geomGen->AddInStudy( study, myMainShape, name, GEOM::GEOM_Object::_nil()); + // look for myMainShape in the table + for ( int r = 0, nr = table()->numRows(); r < nr; ++r ) { + if ( table()->text(r, COL_SHAPEID) == "1" ) { + if ( so->_is_nil() ) { + table()->setText( r, COL_SHAPE, so->GetName() ); + table()->setText( r, COL_PUBLISHED, so->GetID() ); + } + break; + } + } + if ( curSub == 1 ) continue; + } + QString name = GEOMBase::GetDefaultName( shapeTypeName( shape, "ERROR_SHAPE" )); + SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name, myMainShape); + if ( !so->_is_nil() ) { + table()->setText( *row, COL_SHAPE, so->GetName() ); + table()->setText( *row, COL_PUBLISHED, so->GetID() ); + } + } + } + getSMESHGUI()->getApp()->updateObjectBrowser(); + currentCellChanged(); // to update buttons +} + +//================================================================================ +/*! + * \brief SLOT called when a selected cell in table() changed + */ +//================================================================================ + +void SMESHGUI_ComputeOp::currentCellChanged() +{ + myTShapeDisplayer->SetVisibility( false ); + + bool publishEnable = 0, showEnable = 0, showOnly = 1; + list< int > rows; + list< int >::iterator row; + getSelectedRows( table(), rows ); + for ( row = rows.begin(); row != rows.end(); ++row ) + { + bool hasData = ( !table()->text(*row, COL_SHAPE).isEmpty() ); + bool isPublished = ( !table()->text(*row, COL_PUBLISHED).isEmpty() ); + if ( hasData && !isPublished ) + publishEnable = true; + + int curSub = table()->text(*row, COL_SHAPEID).toInt(); + bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape ); + if ( prsReady ) { + myTShapeDisplayer->Show( curSub, myMainShape, showOnly ); + showOnly = false; + } + else { + showEnable = true; + } + } + myDlg->myPublishBtn->setEnabled( publishEnable ); + myDlg->myShowBtn->setEnabled( showEnable ); +} + +//================================================================================ +/*! + * \brief update preview + */ +//================================================================================ + +void SMESHGUI_ComputeOp::onPreviewShape() +{ + if ( myTShapeDisplayer ) + { + SUIT_OverrideCursor aWaitCursor; + list< int > rows; + list< int >::iterator row; + getSelectedRows( table(), rows ); + + bool showOnly = true; + for ( row = rows.begin(); row != rows.end(); ++row ) + { + int curSub = table()->text(*row, COL_SHAPEID).toInt(); + if ( curSub > 0 ) { + myTShapeDisplayer->Show( curSub, myMainShape, showOnly ); + showOnly = false; + } + } + currentCellChanged(); // to update buttons + } +} + +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp() +{ + if ( myTShapeDisplayer ) delete myTShapeDisplayer; +} + +//================================================================================ +/*! + * \brief Gets dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ +//================================================================================ + +LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const +{ + return myDlg; +} + +//================================================================================ +/*! + * \brief perform it's intention action: compute mesh + */ +//================================================================================ + +bool SMESHGUI_ComputeOp::onApply() +{ + return true; +} + +//================================================================================ +/*! + * \brief Return a table + */ +//================================================================================ + +QTable* SMESHGUI_ComputeOp::table() +{ + return myDlg->myTable; +}