Salome HOME
In ModifiedMesh(), set icons corresponding to group/submesh emptiness
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Utils.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_Utils.cxx
25 // Author : Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_Utils.h"
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Selection.h"
31 #include "SMESH_Type.h"
32
33 #include <SMDS_MeshNode.hxx>
34 #include <SMDS_MeshFace.hxx>
35
36 // SALOME GUI includes
37 #include <SUIT_Desktop.h>
38 #include <SUIT_Session.h>
39 #include <SUIT_MessageBox.h>
40 #include <SUIT_ResourceMgr.h>
41
42 #include <LightApp_SelectionMgr.h>
43 #include <SalomeApp_Application.h>
44 #include <SalomeApp_Module.h>
45 #include <SalomeApp_Study.h>
46
47 #include <SALOME_ListIO.hxx>
48
49 // OCC includes
50 #include <gp_XYZ.hxx>
51 #include <TColgp_Array1OfXYZ.hxx>
52
53 namespace SMESH
54 {
55   SUIT_Desktop*
56   GetDesktop(const CAM_Module* theModule)
57   {
58     return theModule->application()->desktop();
59   }
60
61   LightApp_SelectionMgr*
62   GetSelectionMgr(const SalomeApp_Module* theModule)
63   {
64     return theModule->getApp()->selectionMgr();
65   }
66
67   SUIT_ResourceMgr*
68   GetResourceMgr( const SalomeApp_Module* )
69   {
70     return SUIT_Session::session()->resourceMgr();
71   }
72
73   _PTR(Study)
74   GetCStudy(const SalomeApp_Study* theStudy)
75   {
76     return theStudy->studyDS();
77   }
78
79   CORBA::Object_var 
80   DataOwnerToObject(const LightApp_DataOwnerPtr& theOwner)
81   {
82     CORBA::Object_var anObj;
83     if(theOwner){
84       const Handle(SALOME_InteractiveObject)& anIO = theOwner->IO();
85       if(!anIO.IsNull()){
86         if(anIO->hasEntry()){
87           _PTR(Study) aStudy = GetActiveStudyDocument();
88           _PTR(SObject) aSObj = aStudy->FindObjectID(anIO->getEntry());
89           anObj = SObjectToObject(aSObj,aStudy);
90         }
91       }
92     }
93     return anObj;
94   }
95
96   SUIT_Study* GetActiveStudy()
97   {
98     SUIT_Application* app = SUIT_Session::session()->activeApplication();
99     if (app)
100       return app->activeStudy();
101     else
102       return NULL;
103   }
104
105   SUIT_ViewWindow* GetActiveWindow()
106   {
107     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
108       (SUIT_Session::session()->activeApplication());
109     if (app && app->desktop() )
110       return app->desktop()->activeWindow();
111     else
112       return NULL;
113   }
114
115   _PTR(Study) GetActiveStudyDocument()
116   {
117     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(GetActiveStudy());
118     if (aStudy)
119       return aStudy->studyDS();
120     else
121       return _PTR(Study)();
122   }
123
124   _PTR(SObject) FindSObject (CORBA::Object_ptr theObject)
125   {
126     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
127       (SUIT_Session::session()->activeApplication());
128     if (app && !CORBA::is_nil(theObject)) {
129       if(_PTR(Study) aStudy = GetActiveStudyDocument()){
130         CORBA::String_var anIOR = app->orb()->object_to_string(theObject);
131         if (strcmp(anIOR.in(), "") != 0)
132           return aStudy->FindObjectIOR(anIOR.in());
133       }
134     }
135     return _PTR(SObject)();
136   }
137
138   void SetName (_PTR(SObject) theSObject, const QString& theName)
139   {
140     _PTR(Study) aStudy = GetActiveStudyDocument();
141     if (aStudy->GetProperties()->IsLocked())
142       return;
143     SMESHGUI::GetSMESHGen()->SetName(theSObject->GetIOR().c_str(), theName.toLatin1().data());
144   }
145
146   void SetValue (_PTR(SObject) theSObject, const QString& theValue)
147   {
148     _PTR(Study) aStudy = GetActiveStudyDocument();
149     if (aStudy->GetProperties()->IsLocked())
150       return;
151     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
152     _PTR(GenericAttribute) anAttr =
153       aBuilder->FindOrCreateAttribute(theSObject, "AttributeComment");
154     _PTR(AttributeComment) aComment = anAttr;
155     if (aComment)
156       aComment->SetValue(theValue.toLatin1().data());
157   }
158   
159   void setFileName (_PTR(SObject) theSObject, const QString& theValue)
160   {
161     _PTR(Study) aStudy = GetActiveStudyDocument();
162     if (aStudy->GetProperties()->IsLocked())
163       return;
164     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
165     _PTR(GenericAttribute) anAttr =
166       aBuilder->FindOrCreateAttribute(theSObject, "AttributeExternalFileDef");
167     _PTR(AttributeExternalFileDef) aFileName = anAttr;
168     if (aFileName)
169       aFileName->SetValue(theValue.toLatin1().data());
170   }
171   
172   void setFileType (_PTR(SObject) theSObject, const QString& theValue)
173   {
174     _PTR(Study) aStudy = GetActiveStudyDocument();
175     if (aStudy->GetProperties()->IsLocked())
176       return;
177     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
178     _PTR(GenericAttribute) anAttr =
179       aBuilder->FindOrCreateAttribute(theSObject, "AttributeFileType");
180     _PTR(AttributeFileType) aFileType = anAttr;
181     if (aFileType)
182       aFileType->SetValue(theValue.toLatin1().data());
183   }
184
185   CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject,
186                                      _PTR(Study)   theStudy)
187   {
188     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
189       (SUIT_Session::session()->activeApplication());
190     if (theSObject) {
191       _PTR(GenericAttribute) anAttr;
192       if (theSObject->FindAttribute(anAttr, "AttributeIOR")) {
193         _PTR(AttributeIOR) anIOR = anAttr;
194         CORBA::String_var aVal = anIOR->Value().c_str();
195         // string_to_object() DOC: If the input string is not valid ...
196         // a CORBA::SystemException is thrown.
197         if ( aVal && strlen( aVal ) > 0 )
198           return app->orb()->string_to_object(aVal);
199       }
200     }
201     return CORBA::Object::_nil();
202   }
203
204   CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject)
205   {
206     _PTR(Study) aStudy = GetActiveStudyDocument();
207     return SObjectToObject(theSObject,aStudy);
208   }
209
210   _PTR(SObject) ObjectToSObject( CORBA::Object_ptr theObject )
211   {
212     _PTR(SObject) res;
213     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
214       (SUIT_Session::session()->activeApplication());
215     if ( app ) {
216       QString IOR = app->orb()->object_to_string( theObject );
217       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
218       if ( study && !IOR.isEmpty() )
219         res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
220     }
221     return res;
222   }
223
224   CORBA::Object_var IObjectToObject (const Handle(SALOME_InteractiveObject)& theIO)
225   {
226     if (!theIO.IsNull()) {
227       if (theIO->hasEntry()) {
228         _PTR(Study) aStudy = GetActiveStudyDocument();
229         _PTR(SObject) anObj = aStudy->FindObjectID(theIO->getEntry());
230         return SObjectToObject(anObj,aStudy);
231       }
232     }
233     return CORBA::Object::_nil();
234   }
235
236   CORBA::Object_var IORToObject (const QString& theIOR)
237   {
238     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
239       (SUIT_Session::session()->activeApplication());
240     return app->orb()->string_to_object(theIOR.toLatin1().data());
241   }
242
243   int GetNameOfSelectedIObjects(LightApp_SelectionMgr* theMgr, QString& theName)
244   {
245     if (!theMgr)
246       return 0;
247
248     SALOME_ListIO selected;
249     theMgr->selectedObjects(selected);
250     int aNbSel = selected.Extent();
251     if (aNbSel == 1) {
252       Handle(SALOME_InteractiveObject) anIObject = selected.First();
253       theName = anIObject->getName();
254     } else {
255       theName = QObject::tr("SMESH_OBJECTS_SELECTED").arg(aNbSel);
256     }
257     return aNbSel;
258   }
259
260   _PTR(SObject) GetMeshOrSubmesh (_PTR(SObject) theSObject)
261   {
262     GEOM::GEOM_Object_var aShape = SObjectToInterface<GEOM::GEOM_Object>(theSObject);
263     if (!aShape->_is_nil()){ //It s a shape
264       return theSObject->GetFather();
265     }
266     _PTR(SObject) aSObject;
267     if (theSObject->ReferencedObject(aSObject)) {
268       aSObject = theSObject->GetFather();
269       return aSObject->GetFather();
270     }
271     return theSObject->GetFather();
272   }
273
274   void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNotModif, bool isEmptyMesh)
275   {
276     _PTR(Study) aStudy = GetActiveStudyDocument();
277     if (aStudy->GetProperties()->IsLocked())
278       return;
279
280     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
281     _PTR(GenericAttribute) anAttr =
282       aBuilder->FindOrCreateAttribute(theSObject,"AttributePixMap");
283     _PTR(AttributePixMap) aPixmap = anAttr;
284
285     std::string pmName;
286     if (theIsNotModif)
287       pmName = "ICON_SMESH_TREE_MESH";
288     else if ( isEmptyMesh )
289       pmName = "ICON_SMESH_TREE_MESH_WARN";
290     else
291       pmName = "ICON_SMESH_TREE_MESH_PARTIAL";
292     aPixmap->SetPixMap( pmName );
293
294     _PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject);
295     for (int i = 1; anIter->More(); anIter->Next(), i++) {
296       _PTR(SObject) aSObj = anIter->Value();
297       if (i >= 4) {
298         _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj);
299         for ( ; anIter1->More(); anIter1->Next())
300         {
301           _PTR(SObject) aSObj1 = anIter1->Value();
302
303           anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
304           aPixmap = anAttr;
305
306           std::string entry = aSObj1->GetID();
307           int objType = SMESHGUI_Selection::type( entry.c_str(), aStudy );
308
309           SMESH::SMESH_IDSource_var idSrc = SObjectToInterface<SMESH::SMESH_IDSource>( aSObj1 );
310           if ( !idSrc->_is_nil() )
311           {
312             SMESH::array_of_ElementType_var elemTypes = idSrc->GetTypes();
313             const bool isEmpty = ( elemTypes->length() == 0 );
314             if ( isEmpty )
315               aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
316             else if ( objType == GROUP )
317               aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
318             else
319               aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
320           }
321           else
322           {
323             if ( !theIsNotModif )
324               aPixmap->SetPixMap( pmName );
325             else if ( objType == GROUP )
326               aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
327             else
328               aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
329           }
330         }
331       }
332     }
333   }
334
335   void ShowHelpFile (const QString& theHelpFileName)
336   {
337     LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
338     if (app) {
339       SMESHGUI* gui = SMESHGUI::GetSMESHGUI();
340       app->onHelpContextModule(gui ? app->moduleName(gui->moduleName()) : QString(""),
341                                theHelpFileName);
342     }
343     else {
344       SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
345                                QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
346                                arg(app->resourceMgr()->stringValue("ExternalBrowser", 
347                                                                    "application")).
348                                arg(theHelpFileName));
349     }
350   }
351
352   //=======================================================================
353   /**
354      Return normale to a given face
355   */
356   //=======================================================================
357   gp_XYZ getNormale( const SMDS_MeshFace* theFace )
358   {
359     gp_XYZ n;
360     int aNbNode = theFace->NbNodes();
361     TColgp_Array1OfXYZ anArrOfXYZ(1,4);
362     SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
363     int i = 1;
364     for ( ; aNodeItr->more() && i <= 4; i++ ) {
365       SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
366       anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
367     }
368     
369     gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
370     gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
371     n  = q1 ^ q2;
372     if ( aNbNode > 3 ) {
373       gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
374       n += q2 ^ q3;
375     }
376     double len = n.Modulus();
377     if ( len > 0 )
378       n /= len;
379     return n;
380   }
381   
382 } // end of namespace SMESH