Salome HOME
Merge from V6_4_BR 05/12/2011
[modules/smesh.git] / src / StdMeshers / StdMeshers_ImportSource.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 StdMeshers_ImportSource1D : implementaion of SMESH idl descriptions
24 //  File   : StdMeshers_ImportSource1D.cxx
25 //  Module : SMESH
26 //
27 #include "StdMeshers_ImportSource.hxx"
28
29 #include "SMESHDS_GroupOnGeom.hxx"
30 #include "SMESHDS_Mesh.hxx"
31 #include "SMESH_Algo.hxx"
32 #include "SMESH_Gen.hxx"
33 #include "SMESH_Group.hxx"
34 #include "SMESH_Mesh.hxx"
35 #include "SMESH_subMeshEventListener.hxx"
36
37 #include "utilities.h"
38
39 #include <Standard_ErrorHandler.hxx>
40
41 #include <boost/shared_ptr.hpp>
42
43 using namespace std;
44
45 //=============================================================================
46 /*!
47  * Creates StdMeshers_ImportSource1D
48  */
49 //=============================================================================
50
51 StdMeshers_ImportSource1D::StdMeshers_ImportSource1D(int         hypId,
52                                                      int         studyId,
53                                                      SMESH_Gen * gen)
54   :SMESH_Hypothesis(hypId, studyId, gen),
55    _toCopyMesh(false),
56    _toCopyGroups(false)
57 {
58   _name = "ImportSource1D";
59   _param_algo_dim = 1; // is used by StdMeshers_Import_1D;
60 }
61
62 //=============================================================================
63 /*!
64  * Creates StdMeshers_ImportSource2D
65  */
66 //=============================================================================
67
68 StdMeshers_ImportSource2D::StdMeshers_ImportSource2D(int         hypId,
69                                                      int         studyId,
70                                                      SMESH_Gen * gen)
71   :StdMeshers_ImportSource1D(hypId, studyId, gen)
72 {
73   _name = "ImportSource2D";
74   _param_algo_dim = 2; // is used by StdMeshers_Import_2D;
75 }
76
77 //=============================================================================
78 /*!
79  *
80  */
81 //=============================================================================
82
83 StdMeshers_ImportSource1D::~StdMeshers_ImportSource1D()
84 {
85 }
86 //=============================================================================
87 /*!
88  *  Sets groups to import elements from
89  */
90 //=============================================================================
91
92 void StdMeshers_ImportSource1D::SetGroups(const std::vector<SMESH_Group*>& groups)
93 {
94   if (_groups != groups)
95   {
96     _groups = groups;
97     NotifySubMeshesHypothesisModification();
98   }
99 }
100
101 void StdMeshers_ImportSource1D::SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups)
102 {
103   if ( !toCopyMesh ) toCopyGroups = false;
104   if ( _toCopyMesh != toCopyMesh || _toCopyGroups != toCopyGroups )
105   {
106     _toCopyMesh = toCopyMesh; _toCopyGroups = toCopyGroups;
107     NotifySubMeshesHypothesisModification();
108   }
109 }
110 void StdMeshers_ImportSource1D::GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const
111 {
112   toCopyMesh = _toCopyMesh; toCopyGroups = _toCopyGroups;
113 }
114   
115 namespace
116 {
117   //================================================================================
118   /*!
119    * \brief Return only alive groups
120    */
121   //================================================================================
122
123   vector<SMESH_Group*> getValidGroups(const vector<SMESH_Group*>& groups,
124                                       StudyContextStruct*         studyContext)
125   {
126     vector<SMESH_Group*> okGroups;
127     for ( int i = 0; i < groups.size(); ++i )
128     {
129       try
130       {
131         // we expect SIGSEGV on a dead group
132         OCC_CATCH_SIGNALS;
133         SMESH_Group* okGroup = 0;
134         map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
135         for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++)
136         {
137           SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups();
138           while ( gIt->more() && !okGroup )
139             if ( gIt->next() == groups[i] )
140               okGroup = groups[i];
141         }
142         if ( okGroup )
143           okGroups.push_back( okGroup );
144       }
145       catch(...)
146       {
147       }
148     }
149     return okGroups;
150   }
151   //================================================================================
152   /*!
153    * \brief Pack meshes into a pair of ints
154    */
155   //================================================================================
156
157   pair<int, int> getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh)
158   {
159     return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() );
160   }
161   //================================================================================
162   /*!
163    * \brief Return a target mesh by a pair of ints
164    */
165   //================================================================================
166
167   SMESH_Mesh* getTgtMeshByKey( const pair<int, int> & resMapKey,
168                                StudyContextStruct*    studyContext)
169   {
170     int tgtID = resMapKey.second;
171     SMESH_Mesh* tgtMesh = 0;
172     map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
173     for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++)
174     {
175       tgtMesh = (*itm).second;
176       if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID )
177         tgtMesh = 0;
178     }
179     return tgtMesh;
180   }
181   //================================================================================
182   /*!
183    * \brief Return a target mesh by a pair of ints
184    */
185   //================================================================================
186
187   int getSrcMeshID( const pair<int, int> & resMapKey )
188   {
189     return resMapKey.first;
190   }
191 }
192
193 //=============================================================================
194 /*!
195  *  Returns groups to import elements from
196  */
197 //=============================================================================
198
199 const std::vector<SMESH_Group*>&  StdMeshers_ImportSource1D::GetGroups() const
200 {
201   // filter off deleted groups
202   vector<SMESH_Group*> okGroups = getValidGroups( _groups,
203                                                   _gen->GetStudyContext(_studyId) );
204   if ( okGroups.size() != _groups.size() )
205     ((StdMeshers_ImportSource1D*)this)->_groups = okGroups;
206
207   return _groups;
208 }
209
210 //================================================================================
211 /*!
212  * \brief Return source meshes
213  */
214 //================================================================================
215
216 std::vector<SMESH_Mesh*> StdMeshers_ImportSource1D::GetSourceMeshes() const
217 {
218   // GetPersistentId()'s of meshes
219   set<int> meshIDs;
220   const vector<SMESH_Group*>& groups = GetGroups();
221   if ( !groups.empty() )
222   {
223     for ( unsigned i = 0; i < groups.size(); ++i )
224     {
225       const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS();
226       int id = gDS->GetMesh()->GetPersistentId();
227       meshIDs.insert( id );
228     }
229   }
230   else
231   {
232     if ( _resultGroups.empty() )
233       ((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups);
234     TResGroupMap::const_iterator key_groups = _resultGroups.begin();
235     for ( ; key_groups != _resultGroups.end(); ++key_groups )
236       meshIDs.insert( getSrcMeshID( key_groups->first ));
237   }
238
239   // Find corresponding meshes
240   vector<SMESH_Mesh*> meshes;
241   if ( !meshIDs.empty() )
242   {
243     StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId);
244     for ( set<int>::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id )
245     {
246       map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
247       for ( ; itm != studyContext->mapMesh.end(); itm++)
248       {
249         SMESH_Mesh* mesh = (*itm).second;
250         if ( mesh->GetMeshDS()->GetPersistentId() == *id )
251         {
252           meshes.push_back( mesh );
253           break;
254         }
255       }
256     }
257   }
258   return meshes;
259 }
260
261 //================================================================================
262 /*!
263  * \brief Return submeshes whose events affect the target mesh
264  */
265 //================================================================================
266
267 std::vector<SMESH_subMesh*>
268 StdMeshers_ImportSource1D::GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const
269 {
270   if ( !srcMesh->HasShapeToMesh() )
271     return vector<SMESH_subMesh*>(1, srcMesh->GetSubMeshContaining(1));
272
273   set<int> shapeIDs;
274   const vector<SMESH_Group*>& groups = GetGroups();
275   const SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
276   for ( size_t i = 0; i < groups.size(); ++i )
277   {
278     SMESHDS_GroupBase * grDS = groups[i]->GetGroupDS();
279     if ( grDS->GetMesh() != srcMeshDS )
280       continue;
281     if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( grDS ))
282     {
283       shapeIDs.insert( srcMeshDS->ShapeToIndex( gog->GetShape() ));
284     }
285     else
286     {
287       SMDS_ElemIteratorPtr elIt = grDS->GetElements();
288       while ( elIt->more() )
289         shapeIDs.insert( elIt->next()->getshapeId() );
290     }
291   }
292   if ( !shapeIDs.empty() && *shapeIDs.begin() < 1 )
293   {
294     shapeIDs.erase( shapeIDs.begin() );
295     shapeIDs.insert( 1 );
296   }
297
298   vector<SMESH_subMesh*> smVec( shapeIDs.size());
299   set<int>::iterator sID = shapeIDs.begin();
300   for ( int i = 0; sID != shapeIDs.end(); ++sID, ++i )
301     smVec[i] = srcMesh->GetSubMeshContaining( *sID );
302
303   return smVec;
304 }
305
306 //=============================================================================
307 /*!
308  * Save _toCopyMesh and _toCopyGroups to a stream
309  */
310 //=============================================================================
311
312 ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save)
313 {
314   resultGroupsToIntVec();
315
316   save << " " << _toCopyMesh << " " << _toCopyGroups;
317   save << " " << _resultGroupsStorage.size();
318   for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i )
319     save << " " << _resultGroupsStorage[i];
320
321   return save;
322 }
323
324 //=============================================================================
325 /*!
326  * Load _toCopyMesh and _toCopyGroups from a stream
327  */
328 //=============================================================================
329
330 istream & StdMeshers_ImportSource1D::LoadFrom(istream & load)
331 {
332   load >> _toCopyMesh >> _toCopyGroups;
333
334   _resultGroupsStorage.clear();
335   int val;
336   if ( load >> val )
337   {
338     _resultGroupsStorage.reserve(val);
339     while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val )
340       _resultGroupsStorage.push_back( val );
341   }
342   return load;
343 }
344
345 //================================================================================
346 /*!
347  * \brief Convert result groups into _resultGroupsStorage
348  */
349 //================================================================================
350
351 void StdMeshers_ImportSource1D::resultGroupsToIntVec()
352 {
353   _resultGroupsStorage.clear();
354   
355   // store result groups
356   TResGroupMap::iterator key2groups = _resultGroups.begin();
357   for ( ; key2groups != _resultGroups.end(); ++key2groups )
358   {
359     const pair<int, int>&          key = key2groups->first;
360     const vector<SMESH_Group*>& groups = key2groups->second;
361     // mesh ids, nb groups
362     _resultGroupsStorage.push_back( key.first );
363     _resultGroupsStorage.push_back( key.second );
364     _resultGroupsStorage.push_back( groups.size() );
365     for ( unsigned i = 0; i < groups.size(); ++i )
366     {
367       // store group names as sequence of ints each standing for a char
368       // of a name; that is to avoid pb with names containing white spaces
369       string name = groups[i]->GetGroupDS()->GetStoreName();
370       _resultGroupsStorage.push_back( name.size() );
371       for ( unsigned j = 0; j < name.size(); ++j )
372         _resultGroupsStorage.push_back( name[j] );
373     }
374   }
375 }
376
377 //================================================================================
378 /*!
379  * \brief Restore source groups and result groups by _resultGroupsStorage
380  */
381 //================================================================================
382
383 void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& groups)
384 {
385   _groups = groups;
386
387   _resultGroups.clear();
388   int i = 0;
389   while ( i < _resultGroupsStorage.size() )
390   {
391     int key1 = _resultGroupsStorage[i++];
392     int key2 = _resultGroupsStorage[i++];
393     pair<int, int> resMapKey( key1, key2 );
394     SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId));
395     // restore mesh ids at least
396     _resultGroups.insert( make_pair (resMapKey,vector<SMESH_Group*>() )); 
397
398     int nbGroups = _resultGroupsStorage[i++];
399     for ( int j = 0; j < nbGroups; ++j )
400     {
401       string::size_type nameSize = _resultGroupsStorage[i++];
402       string groupName(nameSize, '\0');
403       for ( unsigned k = 0; k < nameSize; ++k )
404         groupName[k] = (char) _resultGroupsStorage[i++];
405
406       // find a group by name
407       if ( mesh )
408       {
409         SMESH_Group* group = 0;
410         SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups();
411         while ( !group && gIt->more() )
412         {
413           group = gIt->next();
414           if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() )
415             group = 0;
416         }
417         if ( group )
418           _resultGroups[ resMapKey ].push_back( group );
419       }
420     }
421   }
422 }
423
424 //================================================================================
425 /*!
426  * \brief Remember groups imported from other mesh
427  *  \param groups - result groups
428  *  \param srcMesh - source mesh
429  *  \param tgtMesh - destination mesh
430  */
431 //================================================================================
432
433 void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector<SMESH_Group*>& groups,
434                                                   const SMESHDS_Mesh&              srcMesh,
435                                                   const SMESHDS_Mesh&              tgtMesh)
436 {
437   _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups;
438 }
439
440 //================================================================================
441 /*!
442  * \brief Return groups imported from other mesh
443  *  \param srcMesh - source mesh
444  *  \param tgtMesh - destination mesh
445  *  \retval const std::vector<SMESH_Group*>& - groups
446  */
447 //================================================================================
448
449 std::vector<SMESH_Group*>*
450 StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh,
451                                            const SMESHDS_Mesh& tgtMesh) 
452 {
453   TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh ));
454   if ( key2groups == _resultGroups.end() )
455     return 0;
456   vector<SMESH_Group*> vec = getValidGroups((*key2groups).second,
457                                             _gen->GetStudyContext(_studyId) );
458   if ( vec.size() != key2groups->second.size())
459     key2groups->second = vec;
460
461   return & key2groups->second;
462 }
463
464 //================================================================================
465 /*!
466  * \brief Initialize ImportSource value by the mesh built on the geometry
467  * \param theMesh - the built mesh
468  * \param theShape - the geometry of interest
469  * \retval bool - true if parameter values have been successfully defined
470  */
471 //================================================================================
472
473 bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
474 {
475   return false;
476 }
477
478 //================================================================================
479 /*!
480  * \brief Initialize my parameter values by default parameters.
481  *  \retval bool - true if parameter values have been successfully defined
482  */
483 //================================================================================
484
485 bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* )
486 {
487   return false;
488 }