Salome HOME
Fix regressions
[modules/smesh.git] / src / StdMeshers / StdMeshers_ImportSource.cxx
1 // Copyright (C) 2007-2016  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, or (at your option) any later version.
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                                       bool                        loaded=false)
126   {
127     vector<SMESH_Group*> okGroups;
128     for ( size_t i = 0; i < groups.size(); ++i )
129     {
130       try
131       {
132         // we expect SIGSEGV on a dead group
133         OCC_CATCH_SIGNALS;
134         SMESH_Group* okGroup = 0;
135         map<int, SMESH_Mesh*>::iterator itm = studyContext->mapMesh.begin();
136         for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++)
137         {
138           SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups();
139           while ( gIt->more() && !okGroup )
140             if ( gIt->next() == groups[i] )
141             {
142               okGroup = groups[i];
143               if ( loaded )
144                 itm->second->Load();
145             }
146         }
147         if ( okGroup )
148           okGroups.push_back( okGroup );
149       }
150       catch(...)
151       {
152       }
153     }
154     return okGroups;
155   }
156   //================================================================================
157   /*!
158    * \brief Pack meshes into a pair of ints
159    */
160   //================================================================================
161
162   pair<int, int> getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh)
163   {
164     return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() );
165   }
166   //================================================================================
167   /*!
168    * \brief Return a target mesh by a pair of ints
169    */
170   //================================================================================
171
172   SMESH_Mesh* getTgtMeshByKey( const pair<int, int> & resMapKey,
173                                StudyContextStruct*    studyContext)
174   {
175     int tgtID = resMapKey.second;
176     SMESH_Mesh* tgtMesh = 0;
177     map<int, SMESH_Mesh*>::iterator itm = studyContext->mapMesh.begin();
178     for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++)
179     {
180       tgtMesh = (*itm).second;
181       if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID )
182         tgtMesh = 0;
183     }
184     return tgtMesh;
185   }
186   //================================================================================
187   /*!
188    * \brief Return a target mesh by a pair of ints
189    */
190   //================================================================================
191
192   int getSrcMeshID( const pair<int, int> & resMapKey )
193   {
194     return resMapKey.first;
195   }
196 }
197
198 //=============================================================================
199 /*!
200  *  Returns groups to import elements from
201  *  \param [in] loaded - if \c true, meshes holding the groups are loaded
202  */
203 //=============================================================================
204
205 const std::vector<SMESH_Group*>&  StdMeshers_ImportSource1D::GetGroups(bool loaded) const
206 {
207   // filter off deleted groups
208   vector<SMESH_Group*> okGroups = getValidGroups( _groups,
209                                                   _gen->GetStudyContext(_studyId),
210                                                   loaded);
211   if ( okGroups.size() != _groups.size() )
212     ((StdMeshers_ImportSource1D*)this)->_groups = okGroups;
213
214   return _groups;
215 }
216
217 //================================================================================
218 /*!
219  * \brief Return source meshes
220  */
221 //================================================================================
222
223 std::vector<SMESH_Mesh*> StdMeshers_ImportSource1D::GetSourceMeshes() const
224 {
225   // GetPersistentId()'s of meshes
226   set<int> meshIDs;
227   const vector<SMESH_Group*>& groups = GetGroups();
228   if ( !groups.empty() )
229   {
230     for ( unsigned i = 0; i < groups.size(); ++i )
231     {
232       const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS();
233       int id = gDS->GetMesh()->GetPersistentId();
234       meshIDs.insert( id );
235     }
236   }
237   else
238   {
239     if ( _resultGroups.empty() )
240       ((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups);
241     TResGroupMap::const_iterator key_groups = _resultGroups.begin();
242     for ( ; key_groups != _resultGroups.end(); ++key_groups )
243       meshIDs.insert( getSrcMeshID( key_groups->first ));
244   }
245
246   // Find corresponding meshes
247   vector<SMESH_Mesh*> meshes;
248   if ( !meshIDs.empty() )
249   {
250     StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId);
251     for ( set<int>::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id )
252     {
253       map<int, SMESH_Mesh*>::iterator itm = studyContext->mapMesh.begin();
254       for ( ; itm != studyContext->mapMesh.end(); itm++)
255       {
256         SMESH_Mesh* mesh = (*itm).second;
257         if ( mesh->GetMeshDS()->GetPersistentId() == *id )
258         {
259           meshes.push_back( mesh );
260           break;
261         }
262       }
263     }
264   }
265   return meshes;
266 }
267
268 //================================================================================
269 /*!
270  * \brief Return submeshes whose events affect the target mesh
271  */
272 //================================================================================
273
274 std::vector<SMESH_subMesh*>
275 StdMeshers_ImportSource1D::GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const
276 {
277   if ( !srcMesh->HasShapeToMesh() )
278   {
279     SMESH_Mesh* srcM = const_cast< SMESH_Mesh* >( srcMesh );
280     return vector<SMESH_subMesh*>(1, srcM->GetSubMesh( srcM->GetShapeToMesh()));
281   }
282   set<int> shapeIDs;
283   const vector<SMESH_Group*>& groups = GetGroups();
284   const SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
285   for ( size_t i = 0; i < groups.size(); ++i )
286   {
287     SMESHDS_GroupBase * grDS = groups[i]->GetGroupDS();
288     if ( grDS->GetMesh() != srcMeshDS )
289       continue;
290     if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( grDS ))
291     {
292       shapeIDs.insert( srcMeshDS->ShapeToIndex( gog->GetShape() ));
293     }
294     else
295     {
296       SMDS_ElemIteratorPtr elIt = grDS->GetElements();
297       while ( elIt->more() )
298         shapeIDs.insert( elIt->next()->getshapeId() );
299     }
300   }
301   if ( !shapeIDs.empty() && *shapeIDs.begin() < 1 )
302   {
303     shapeIDs.erase( shapeIDs.begin() );
304     shapeIDs.insert( 1 );
305   }
306
307   vector<SMESH_subMesh*> smVec( shapeIDs.size());
308   set<int>::iterator sID = shapeIDs.begin();
309   for ( int i = 0; sID != shapeIDs.end(); ++sID, ++i )
310     smVec[i] = srcMesh->GetSubMeshContaining( *sID );
311
312   return smVec;
313 }
314
315 //=============================================================================
316 /*!
317  * Save _toCopyMesh and _toCopyGroups to a stream
318  */
319 //=============================================================================
320
321 ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save)
322 {
323   resultGroupsToIntVec();
324
325   save << " " << _toCopyMesh << " " << _toCopyGroups;
326   save << " " << _resultGroupsStorage.size();
327   for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i )
328     save << " " << _resultGroupsStorage[i];
329
330   return save;
331 }
332
333 //=============================================================================
334 /*!
335  * Load _toCopyMesh and _toCopyGroups from a stream
336  */
337 //=============================================================================
338
339 istream & StdMeshers_ImportSource1D::LoadFrom(istream & load)
340 {
341   load >> _toCopyMesh >> _toCopyGroups;
342
343   _resultGroupsStorage.clear();
344   int val;
345   if ( load >> val )
346   {
347     _resultGroupsStorage.reserve(val);
348     while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val )
349       _resultGroupsStorage.push_back( val );
350   }
351   return load;
352 }
353
354 //================================================================================
355 /*!
356  * \brief Convert result groups into _resultGroupsStorage
357  */
358 //================================================================================
359
360 void StdMeshers_ImportSource1D::resultGroupsToIntVec()
361 {
362   _resultGroupsStorage.clear();
363   
364   // store result groups
365   TResGroupMap::iterator key2groups = _resultGroups.begin();
366   for ( ; key2groups != _resultGroups.end(); ++key2groups )
367   {
368     const pair<int, int>&          key = key2groups->first;
369     const vector<SMESH_Group*>& groups = key2groups->second;
370     // mesh ids, nb groups
371     _resultGroupsStorage.push_back( key.first );
372     _resultGroupsStorage.push_back( key.second );
373     _resultGroupsStorage.push_back( groups.size() );
374     for ( unsigned i = 0; i < groups.size(); ++i )
375     {
376       // store group names as sequence of ints each standing for a char
377       // of a name; that is to avoid pb with names containing white spaces
378       string name = groups[i]->GetGroupDS()->GetStoreName();
379       _resultGroupsStorage.push_back( name.size() );
380       for ( unsigned j = 0; j < name.size(); ++j )
381         _resultGroupsStorage.push_back( name[j] );
382     }
383   }
384 }
385
386 //================================================================================
387 /*!
388  * \brief Restore source groups and result groups by _resultGroupsStorage
389  */
390 //================================================================================
391
392 void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& groups)
393 {
394   _groups = groups;
395
396   _resultGroups.clear();
397   size_t i = 0;
398   while ( i < _resultGroupsStorage.size() )
399   {
400     int key1 = _resultGroupsStorage[i++];
401     int key2 = _resultGroupsStorage[i++];
402     pair<int, int> resMapKey( key1, key2 );
403     SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId));
404     // restore mesh ids at least
405     _resultGroups.insert( make_pair (resMapKey,vector<SMESH_Group*>() )); 
406
407     int nbGroups = _resultGroupsStorage[i++];
408     for ( int j = 0; j < nbGroups; ++j )
409     {
410       string::size_type nameSize = _resultGroupsStorage[i++];
411       string groupName(nameSize, '\0');
412       for ( unsigned k = 0; k < nameSize; ++k )
413         groupName[k] = (char) _resultGroupsStorage[i++];
414
415       // find a group by name
416       if ( mesh )
417       {
418         SMESH_Group* group = 0;
419         SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups();
420         while ( !group && gIt->more() )
421         {
422           group = gIt->next();
423           if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() )
424             group = 0;
425         }
426         if ( group )
427           _resultGroups[ resMapKey ].push_back( group );
428       }
429     }
430   }
431 }
432
433 //================================================================================
434 /*!
435  * \brief Remember groups imported from other mesh
436  *  \param groups - result groups
437  *  \param srcMesh - source mesh
438  *  \param tgtMesh - destination mesh
439  */
440 //================================================================================
441
442 void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector<SMESH_Group*>& groups,
443                                                   const SMESHDS_Mesh&              srcMesh,
444                                                   const SMESHDS_Mesh&              tgtMesh)
445 {
446   _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups;
447 }
448
449 //================================================================================
450 /*!
451  * \brief Return groups imported from other mesh
452  *  \param srcMesh - source mesh
453  *  \param tgtMesh - destination mesh
454  *  \retval const std::vector<SMESH_Group*>& - groups
455  */
456 //================================================================================
457
458 std::vector<SMESH_Group*>*
459 StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh,
460                                            const SMESHDS_Mesh& tgtMesh) 
461 {
462   TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh ));
463   if ( key2groups == _resultGroups.end() )
464     return 0;
465   vector<SMESH_Group*> vec = getValidGroups((*key2groups).second,
466                                             _gen->GetStudyContext(_studyId) );
467   if ( vec.size() != key2groups->second.size())
468     key2groups->second = vec;
469
470   return & key2groups->second;
471 }
472
473 //================================================================================
474 /*!
475  * \brief Initialize ImportSource value by the mesh built on the geometry
476  * \param theMesh - the built mesh
477  * \param theShape - the geometry of interest
478  * \retval bool - true if parameter values have been successfully defined
479  */
480 //================================================================================
481
482 bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
483 {
484   return false;
485 }
486
487 //================================================================================
488 /*!
489  * \brief Initialize my parameter values by default parameters.
490  *  \retval bool - true if parameter values have been successfully defined
491  */
492 //================================================================================
493
494 bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* )
495 {
496   return false;
497 }