Salome HOME
22261: EDF 2698 SMESH: Memory leak when displaying 2D quadratic elements as arcs
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Utils.cxx
1 // Copyright (C) 2007-2013  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 #include CORBA_SERVER_HEADER(SMESH_Group)
54
55 namespace SMESH
56 {
57   SUIT_Desktop*
58   GetDesktop(const CAM_Module* theModule)
59   {
60     return theModule->application()->desktop();
61   }
62
63   LightApp_SelectionMgr*
64   GetSelectionMgr(const SalomeApp_Module* theModule)
65   {
66     return theModule->getApp()->selectionMgr();
67   }
68
69   SUIT_ResourceMgr*
70   GetResourceMgr( const SalomeApp_Module* )
71   {
72     return SUIT_Session::session()->resourceMgr();
73   }
74
75   _PTR(Study)
76   GetCStudy(const SalomeApp_Study* theStudy)
77   {
78     return theStudy->studyDS();
79   }
80
81   CORBA::Object_var 
82   DataOwnerToObject(const LightApp_DataOwnerPtr& theOwner)
83   {
84     CORBA::Object_var anObj;
85     if(theOwner){
86       const Handle(SALOME_InteractiveObject)& anIO = theOwner->IO();
87       if(!anIO.IsNull()){
88         if(anIO->hasEntry()){
89           _PTR(Study) aStudy = GetActiveStudyDocument();
90           _PTR(SObject) aSObj = aStudy->FindObjectID(anIO->getEntry());
91           anObj = SObjectToObject(aSObj,aStudy);
92         }
93       }
94     }
95     return anObj;
96   }
97
98   SUIT_Study* GetActiveStudy()
99   {
100     SUIT_Application* app = SUIT_Session::session()->activeApplication();
101     if (app)
102       return app->activeStudy();
103     else
104       return NULL;
105   }
106
107   SUIT_ViewWindow* GetActiveWindow()
108   {
109     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
110       (SUIT_Session::session()->activeApplication());
111     if (app && app->desktop() )
112       return app->desktop()->activeWindow();
113     else
114       return NULL;
115   }
116
117   _PTR(Study) GetActiveStudyDocument()
118   {
119     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(GetActiveStudy());
120     if (aStudy)
121       return aStudy->studyDS();
122     else
123       return _PTR(Study)();
124   }
125
126   _PTR(SObject) FindSObject (CORBA::Object_ptr theObject)
127   {
128     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
129       (SUIT_Session::session()->activeApplication());
130     if (app && !CORBA::is_nil(theObject)) {
131       if(_PTR(Study) aStudy = GetActiveStudyDocument()){
132         CORBA::String_var anIOR = app->orb()->object_to_string(theObject);
133         if (strcmp(anIOR.in(), "") != 0)
134           return aStudy->FindObjectIOR(anIOR.in());
135       }
136     }
137     return _PTR(SObject)();
138   }
139
140   void SetName (_PTR(SObject) theSObject, const QString& theName)
141   {
142     _PTR(Study) aStudy = GetActiveStudyDocument();
143     if (aStudy->GetProperties()->IsLocked())
144       return;
145     SMESHGUI::GetSMESHGen()->SetName(theSObject->GetIOR().c_str(), theName.toLatin1().data());
146   }
147
148   void SetValue (_PTR(SObject) theSObject, const QString& theValue)
149   {
150     _PTR(Study) aStudy = GetActiveStudyDocument();
151     if (aStudy->GetProperties()->IsLocked())
152       return;
153     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
154     _PTR(GenericAttribute) anAttr =
155       aBuilder->FindOrCreateAttribute(theSObject, "AttributeComment");
156     _PTR(AttributeComment) aComment = anAttr;
157     if (aComment)
158       aComment->SetValue(theValue.toLatin1().data());
159   }
160   
161   void setFileName (_PTR(SObject) theSObject, const QString& theValue)
162   {
163     _PTR(Study) aStudy = GetActiveStudyDocument();
164     if (aStudy->GetProperties()->IsLocked())
165       return;
166     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
167     _PTR(GenericAttribute) anAttr =
168       aBuilder->FindOrCreateAttribute(theSObject, "AttributeExternalFileDef");
169     _PTR(AttributeExternalFileDef) aFileName = anAttr;
170     if (aFileName)
171       aFileName->SetValue(theValue.toLatin1().data());
172   }
173   
174   void setFileType (_PTR(SObject) theSObject, const QString& theValue)
175   {
176     _PTR(Study) aStudy = GetActiveStudyDocument();
177     if (aStudy->GetProperties()->IsLocked())
178       return;
179     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
180     _PTR(GenericAttribute) anAttr =
181       aBuilder->FindOrCreateAttribute(theSObject, "AttributeFileType");
182     _PTR(AttributeFileType) aFileType = anAttr;
183     if (aFileType)
184       aFileType->SetValue(theValue.toLatin1().data());
185   }
186
187   CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject,
188                                      _PTR(Study)   theStudy)
189   {
190     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
191       (SUIT_Session::session()->activeApplication());
192     if (theSObject) {
193       _PTR(GenericAttribute) anAttr;
194       if (theSObject->FindAttribute(anAttr, "AttributeIOR")) {
195         _PTR(AttributeIOR) anIOR = anAttr;
196         CORBA::String_var aVal = anIOR->Value().c_str();
197         // string_to_object() DOC: If the input string is not valid ...
198         // a CORBA::SystemException is thrown.
199         if ( aVal && strlen( aVal ) > 0 )
200           return app->orb()->string_to_object(aVal);
201       }
202     }
203     return CORBA::Object::_nil();
204   }
205
206   CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject)
207   {
208     _PTR(Study) aStudy = GetActiveStudyDocument();
209     return SObjectToObject(theSObject,aStudy);
210   }
211
212   _PTR(SObject) ObjectToSObject( CORBA::Object_ptr theObject )
213   {
214     _PTR(SObject) res;
215     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
216       (SUIT_Session::session()->activeApplication());
217     if ( app ) {
218       CORBA::String_var ior = app->orb()->object_to_string( theObject );
219       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
220       if ( study && strlen( ior ) > 0 )
221         res = study->studyDS()->FindObjectIOR( ior.in() );
222     }
223     return res;
224   }
225
226   CORBA::Object_var IObjectToObject (const Handle(SALOME_InteractiveObject)& theIO)
227   {
228     if (!theIO.IsNull()) {
229       if (theIO->hasEntry()) {
230         _PTR(Study) aStudy = GetActiveStudyDocument();
231         _PTR(SObject) anObj = aStudy->FindObjectID(theIO->getEntry());
232         return SObjectToObject(anObj,aStudy);
233       }
234     }
235     return CORBA::Object::_nil();
236   }
237
238   CORBA::Object_var IORToObject (const QString& theIOR)
239   {
240     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
241       (SUIT_Session::session()->activeApplication());
242     return app->orb()->string_to_object(theIOR.toLatin1().data());
243   }
244
245   int GetNameOfSelectedIObjects(LightApp_SelectionMgr* theMgr, QString& theName)
246   {
247     if (!theMgr)
248       return 0;
249
250     SALOME_ListIO selected;
251     theMgr->selectedObjects(selected);
252     int aNbSel = selected.Extent();
253     if (aNbSel == 1) {
254       Handle(SALOME_InteractiveObject) anIObject = selected.First();
255       theName = QString( anIObject->getName() ).trimmed();
256     } else {
257       theName = QObject::tr("SMESH_OBJECTS_SELECTED").arg(aNbSel);
258     }
259     return aNbSel;
260   }
261
262   _PTR(SObject) GetMeshOrSubmesh (_PTR(SObject) theSObject)
263   {
264     GEOM::GEOM_Object_var aShape = SObjectToInterface<GEOM::GEOM_Object>(theSObject);
265     if (!aShape->_is_nil()){ //It s a shape
266       return theSObject->GetFather();
267     }
268     _PTR(SObject) aSObject;
269     if (theSObject->ReferencedObject(aSObject)) {
270       aSObject = theSObject->GetFather();
271       return aSObject->GetFather();
272     }
273     return theSObject->GetFather();
274   }
275
276   void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNotModif, bool isEmptyMesh)
277   {
278     _PTR(Study) aStudy = GetActiveStudyDocument();
279     if (aStudy->GetProperties()->IsLocked())
280       return;
281
282     _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
283     _PTR(GenericAttribute) anAttr =
284       aBuilder->FindOrCreateAttribute(theSObject,"AttributePixMap");
285     _PTR(AttributePixMap) aPixmap = anAttr;
286
287     std::string pmName;
288     if (theIsNotModif)
289       pmName = "ICON_SMESH_TREE_MESH";
290     else if ( isEmptyMesh )
291       pmName = "ICON_SMESH_TREE_MESH_WARN";
292     else
293       pmName = "ICON_SMESH_TREE_MESH_PARTIAL";
294     aPixmap->SetPixMap( pmName );
295
296     _PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject);
297     for (int i = 1; anIter->More(); anIter->Next(), i++) {
298       _PTR(SObject) aSObj = anIter->Value();
299       if (i >= 4) {
300         _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj);
301         for ( ; anIter1->More(); anIter1->Next())
302         {
303           _PTR(SObject) aSObj1 = anIter1->Value();
304
305           anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
306           aPixmap = anAttr;
307
308           std::string entry = aSObj1->GetID();
309           int objType = SMESHGUI_Selection::type( entry.c_str(), aStudy );
310
311           SMESH::SMESH_IDSource_var idSrc = SObjectToInterface<SMESH::SMESH_IDSource>( aSObj1 );
312           if ( !idSrc->_is_nil() )
313           {
314             SMESH::SMESH_GroupOnFilter_var gof =
315               SObjectToInterface<SMESH::SMESH_GroupOnFilter>( aSObj1 );
316             const bool isGroupOnFilter = !gof->_is_nil();
317
318             bool isEmpty = false;
319             if ( !isGroupOnFilter ) // GetTypes() can be very long on isGroupOnFilter!
320             {
321               SMESH::array_of_ElementType_var elemTypes = idSrc->GetTypes();
322               isEmpty = ( elemTypes->length() == 0 );
323             }
324             if ( isEmpty )
325               aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
326             else if ( objType != GROUP )
327               aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
328             else if ( isGroupOnFilter )
329               aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP_ON_FILTER" );
330             else
331               aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
332           }
333           else
334           {
335             if ( !theIsNotModif )
336               aPixmap->SetPixMap( pmName );
337             else if ( objType == GROUP )
338               aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
339             else
340               aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
341           }
342         }
343       }
344     }
345   }
346
347   void ShowHelpFile (const QString& theHelpFileName)
348   {
349     LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
350     if (app) {
351       SMESHGUI* gui = SMESHGUI::GetSMESHGUI();
352       app->onHelpContextModule(gui ? app->moduleName(gui->moduleName()) : QString(""),
353                                theHelpFileName);
354     }
355     else {
356       SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
357                                QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
358                                arg(app->resourceMgr()->stringValue("ExternalBrowser", 
359                                                                    "application")).
360                                arg(theHelpFileName));
361     }
362   }
363
364   //=======================================================================
365   /**
366      Return normale to a given face
367   */
368   //=======================================================================
369   gp_XYZ getNormale( const SMDS_MeshFace* theFace )
370   {
371     gp_XYZ n;
372     int aNbNode = theFace->NbNodes();
373     TColgp_Array1OfXYZ anArrOfXYZ(1,4);
374     SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
375     int i = 1;
376     for ( ; aNodeItr->more() && i <= 4; i++ ) {
377       SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
378       anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
379     }
380     
381     gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
382     gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
383     n  = q1 ^ q2;
384     if ( aNbNode > 3 ) {
385       gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
386       n += q2 ^ q3;
387     }
388     double len = n.Modulus();
389     if ( len > 0 )
390       n /= len;
391     return n;
392   }
393   
394 } // end of namespace SMESH