Salome HOME
Merge from V6_5_BR 05/06/2012
[modules/smesh.git] / src / StdMeshers / StdMeshers_ImportSource.cxx
1 // Copyright (C) 2007-2012  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   {
272     SMESH_Mesh* srcM = const_cast< SMESH_Mesh* >( srcMesh );
273     return vector<SMESH_subMesh*>(1, srcM->GetSubMesh( srcM->GetShapeToMesh()));
274   }
275   set<int> shapeIDs;
276   const vector<SMESH_Group*>& groups = GetGroups();
277   const SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
278   for ( size_t i = 0; i < groups.size(); ++i )
279   {
280     SMESHDS_GroupBase * grDS = groups[i]->GetGroupDS();
281     if ( grDS->GetMesh() != srcMeshDS )
282       continue;
283     if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( grDS ))
284     {
285       shapeIDs.insert( srcMeshDS->ShapeToIndex( gog->GetShape() ));
286     }
287     else
288     {
289       SMDS_ElemIteratorPtr elIt = grDS->GetElements();
290       while ( elIt->more() )
291         shapeIDs.insert( elIt->next()->getshapeId() );
292     }
293   }
294   if ( !shapeIDs.empty() && *shapeIDs.begin() < 1 )
295   {
296     shapeIDs.erase( shapeIDs.begin() );
297     shapeIDs.insert( 1 );
298   }
299
300   vector<SMESH_subMesh*> smVec( shapeIDs.size());
301   set<int>::iterator sID = shapeIDs.begin();
302   for ( int i = 0; sID != shapeIDs.end(); ++sID, ++i )
303     smVec[i] = srcMesh->GetSubMeshContaining( *sID );
304
305   return smVec;
306 }
307
308 //=============================================================================
309 /*!
310  * Save _toCopyMesh and _toCopyGroups to a stream
311  */
312 //=============================================================================
313
314 ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save)
315 {
316   resultGroupsToIntVec();
317
318   save << " " << _toCopyMesh << " " << _toCopyGroups;
319   save << " " << _resultGroupsStorage.size();
320   for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i )
321     save << " " << _resultGroupsStorage[i];
322
323   return save;
324 }
325
326 //=============================================================================
327 /*!
328  * Load _toCopyMesh and _toCopyGroups from a stream
329  */
330 //=============================================================================
331
332 istream & StdMeshers_ImportSource1D::LoadFrom(istream & load)
333 {
334   load >> _toCopyMesh >> _toCopyGroups;
335
336   _resultGroupsStorage.clear();
337   int val;
338   if ( load >> val )
339   {
340     _resultGroupsStorage.reserve(val);
341     while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val )
342       _resultGroupsStorage.push_back( val );
343   }
344   return load;
345 }
346
347 //================================================================================
348 /*!
349  * \brief Convert result groups into _resultGroupsStorage
350  */
351 //================================================================================
352
353 void StdMeshers_ImportSource1D::resultGroupsToIntVec()
354 {
355   _resultGroupsStorage.clear();
356   
357   // store result groups
358   TResGroupMap::iterator key2groups = _resultGroups.begin();
359   for ( ; key2groups != _resultGroups.end(); ++key2groups )
360   {
361     const pair<int, int>&          key = key2groups->first;
362     const vector<SMESH_Group*>& groups = key2groups->second;
363     // mesh ids, nb groups
364     _resultGroupsStorage.push_back( key.first );
365     _resultGroupsStorage.push_back( key.second );
366     _resultGroupsStorage.push_back( groups.size() );
367     for ( unsigned i = 0; i < groups.size(); ++i )
368     {
369       // store group names as sequence of ints each standing for a char
370       // of a name; that is to avoid pb with names containing white spaces
371       string name = groups[i]->GetGroupDS()->GetStoreName();
372       _resultGroupsStorage.push_back( name.size() );
373       for ( unsigned j = 0; j < name.size(); ++j )
374         _resultGroupsStorage.push_back( name[j] );
375     }
376   }
377 }
378
379 //================================================================================
380 /*!
381  * \brief Restore source groups and result groups by _resultGroupsStorage
382  */
383 //================================================================================
384
385 void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& groups)
386 {
387   _groups = groups;
388
389   _resultGroups.clear();
390   int i = 0;
391   while ( i < _resultGroupsStorage.size() )
392   {
393     int key1 = _resultGroupsStorage[i++];
394     int key2 = _resultGroupsStorage[i++];
395     pair<int, int> resMapKey( key1, key2 );
396     SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId));
397     // restore mesh ids at least
398     _resultGroups.insert( make_pair (resMapKey,vector<SMESH_Group*>() )); 
399
400     int nbGroups = _resultGroupsStorage[i++];
401     for ( int j = 0; j < nbGroups; ++j )
402     {
403       string::size_type nameSize = _resultGroupsStorage[i++];
404       string groupName(nameSize, '\0');
405       for ( unsigned k = 0; k < nameSize; ++k )
406         groupName[k] = (char) _resultGroupsStorage[i++];
407
408       // find a group by name
409       if ( mesh )
410       {
411         SMESH_Group* group = 0;
412         SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups();
413         while ( !group && gIt->more() )
414         {
415           group = gIt->next();
416           if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() )
417             group = 0;
418         }
419         if ( group )
420           _resultGroups[ resMapKey ].push_back( group );
421       }
422     }
423   }
424 }
425
426 //================================================================================
427 /*!
428  * \brief Remember groups imported from other mesh
429  *  \param groups - result groups
430  *  \param srcMesh - source mesh
431  *  \param tgtMesh - destination mesh
432  */
433 //================================================================================
434
435 void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector<SMESH_Group*>& groups,
436                                                   const SMESHDS_Mesh&              srcMesh,
437                                                   const SMESHDS_Mesh&              tgtMesh)
438 {
439   _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups;
440 }
441
442 //================================================================================
443 /*!
444  * \brief Return groups imported from other mesh
445  *  \param srcMesh - source mesh
446  *  \param tgtMesh - destination mesh
447  *  \retval const std::vector<SMESH_Group*>& - groups
448  */
449 //================================================================================
450
451 std::vector<SMESH_Group*>*
452 StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh,
453                                            const SMESHDS_Mesh& tgtMesh) 
454 {
455   TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh ));
456   if ( key2groups == _resultGroups.end() )
457     return 0;
458   vector<SMESH_Group*> vec = getValidGroups((*key2groups).second,
459                                             _gen->GetStudyContext(_studyId) );
460   if ( vec.size() != key2groups->second.size())
461     key2groups->second = vec;
462
463   return & key2groups->second;
464 }
465
466 //================================================================================
467 /*!
468  * \brief Initialize ImportSource value by the mesh built on the geometry
469  * \param theMesh - the built mesh
470  * \param theShape - the geometry of interest
471  * \retval bool - true if parameter values have been successfully defined
472  */
473 //================================================================================
474
475 bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
476 {
477   return false;
478 }
479
480 //================================================================================
481 /*!
482  * \brief Initialize my parameter values by default parameters.
483  *  \retval bool - true if parameter values have been successfully defined
484  */
485 //================================================================================
486
487 bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* )
488 {
489   return false;
490 }