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