1 // SMESH DriverMED : tool to split groups on families
3 // Copyright (C) 2003 CEA
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
23 // File : DriverMED_Family.cxx
24 // Author : Julia DOROVSKIKH
28 #include "DriverMED_Family.h"
29 #include "MED_Factory.hxx"
35 //=============================================================================
37 * Split each group from list <aGroups> on some parts (families)
38 * on the basis of the elements membership in other groups from this list.
39 * Resulting families have no common elements.
41 //=============================================================================
42 list<DriverMED_FamilyPtr> DriverMED_Family::MakeFamilies
43 (const map <int, SMESHDS_SubMesh*>& theSubMeshes,
44 const list<SMESHDS_GroupBase*>& theGroups,
45 const bool doGroupOfNodes,
46 const bool doGroupOfEdges,
47 const bool doGroupOfFaces,
48 const bool doGroupOfVolumes)
50 list<DriverMED_FamilyPtr> aFamilies;
52 string anAllNodesGroupName = "Group_Of_All_Nodes";
53 string anAllEdgesGroupName = "Group_Of_All_Edges";
54 string anAllFacesGroupName = "Group_Of_All_Faces";
55 string anAllVolumesGroupName = "Group_Of_All_Volumes";
57 // Reserve four ids for families of free elements
58 // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
59 // 'Free' means here not belonging to any group.
60 int aNodeFamId = FIRST_NODE_FAMILY;
61 int aElemFamId = FIRST_ELEM_FAMILY;
64 map<int, SMESHDS_SubMesh*>::const_iterator aSMIter = theSubMeshes.begin();
65 for (; aSMIter != theSubMeshes.end(); aSMIter++)
67 if ( aSMIter->second->IsComplexSubmesh() )
68 continue; // submesh containing other submeshs
69 list<DriverMED_FamilyPtr> aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first);
70 list<DriverMED_FamilyPtr>::iterator aSMFamsIter = aSMFams.begin();
71 for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
73 DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
75 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
76 while (aFamsIter != aFamilies.end())
78 DriverMED_FamilyPtr aFam1 = *aFamsIter;
79 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
80 if (aFam1->myType == aFam2->myType)
82 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
83 aFam1->Split(aFam2, aCommon);
84 if (!aCommon->IsEmpty())
86 aFamilies.push_back(aCommon);
90 aFamilies.erase(aCurrIter);
92 if (aFam2->IsEmpty()) break;
95 // The rest elements of family
96 if (!aFam2->IsEmpty())
98 aFamilies.push_back(aFam2);
104 list<SMESHDS_GroupBase*>::const_iterator aGroupsIter = theGroups.begin();
105 for (; aGroupsIter != theGroups.end(); aGroupsIter++)
107 DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
108 aFam2->Init(*aGroupsIter);
110 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
111 while (aFamsIter != aFamilies.end())
113 DriverMED_FamilyPtr aFam1 = *aFamsIter;
114 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
115 if (aFam1->myType == aFam2->myType)
117 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
118 aFam1->Split(aFam2, aCommon);
119 if (!aCommon->IsEmpty())
121 aFamilies.push_back(aCommon);
123 if (aFam1->IsEmpty())
125 aFamilies.erase(aCurrIter);
127 if (aFam2->IsEmpty()) break;
130 // The rest elements of group
131 if (!aFam2->IsEmpty())
133 aFamilies.push_back(aFam2);
137 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
138 for (; aFamsIter != aFamilies.end(); aFamsIter++)
140 DriverMED_FamilyPtr aFam = *aFamsIter;
141 if (aFam->myType == SMDSAbs_Node) {
142 aFam->SetId(aNodeFamId++);
143 if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
146 aFam->SetId(aElemFamId--);
147 if (aFam->myType == SMDSAbs_Edge) {
148 if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
150 else if (aFam->myType == SMDSAbs_Face) {
151 if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
153 else if (aFam->myType == SMDSAbs_Volume) {
154 if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
159 // Create families for elements, not belonging to any group
162 DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
163 aFreeNodesFam->SetId(REST_NODES_FAMILY);
164 aFreeNodesFam->myType = SMDSAbs_Node;
165 aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
166 aFamilies.push_back(aFreeNodesFam);
171 DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
172 aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
173 aFreeEdgesFam->myType = SMDSAbs_Edge;
174 aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
175 aFamilies.push_back(aFreeEdgesFam);
180 DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
181 aFreeFacesFam->SetId(REST_FACES_FAMILY);
182 aFreeFacesFam->myType = SMDSAbs_Face;
183 aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
184 aFamilies.push_back(aFreeFacesFam);
187 if (doGroupOfVolumes)
189 DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
190 aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
191 aFreeVolumesFam->myType = SMDSAbs_Volume;
192 aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
193 aFamilies.push_back(aFreeVolumesFam);
196 DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
198 aNullFam->myType = SMDSAbs_All;
199 aFamilies.push_back(aNullFam);
204 //=============================================================================
206 * Create TFamilyInfo for this family
208 //=============================================================================
210 DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper,
211 const MED::PMeshInfo& theMeshInfo) const
217 aStr << "FAM_" << myId;
218 set<string>::iterator aGrIter = myGroupNames.begin();
219 for (; aGrIter != myGroupNames.end(); aGrIter++)
221 aStr << "_" << *aGrIter;
226 MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description,
227 MED::TIntVector anAttrIds (1, myId); // Id=0,
228 MED::TIntVector anAttrVals (1, myId); // Value=0
231 MED::PFamilyInfo anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
242 // cout << "Groups: ";
243 // set<string>::iterator aGrIter = myGroupNames.begin();
244 // for (; aGrIter != myGroupNames.end(); aGrIter++)
246 // cout << " " << *aGrIter;
250 // cout << "Elements: ";
251 // set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
252 // for (; anIter != myElements.end(); anIter++)
254 // cout << " " << (*anIter)->GetID();
261 //=============================================================================
263 * Initialize the tool by SMESHDS_GroupBase
265 //=============================================================================
266 void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
270 SMDS_ElemIteratorPtr elemIt = theGroup->GetElements();
271 while (elemIt->more())
273 myElements.insert(elemIt->next());
277 myType = theGroup->GetType();
280 myGroupNames.clear();
281 myGroupNames.insert(string(theGroup->GetStoreName()));
284 //=============================================================================
286 * Split <theSubMesh> on some parts (families)
287 * on the basis of the elements type.
289 //=============================================================================
290 list<DriverMED_FamilyPtr> DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh,
293 list<DriverMED_FamilyPtr> aFamilies;
294 DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family);
295 DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family);
296 DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family);
297 DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
299 char submeshGrpName[ 30 ];
300 sprintf( submeshGrpName, "SubMesh %d", theId );
302 SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
303 while (aNodesIter->more())
305 const SMDS_MeshNode* aNode = aNodesIter->next();
306 aNodesFamily->AddElement(aNode);
309 SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
310 while (anElemsIter->more())
312 const SMDS_MeshElement* anElem = anElemsIter->next();
313 switch (anElem->GetType())
316 anEdgesFamily->AddElement(anElem);
319 aFacesFamily->AddElement(anElem);
322 aVolumesFamily->AddElement(anElem);
329 if (!aNodesFamily->IsEmpty()) {
330 aNodesFamily->SetType(SMDSAbs_Node);
331 aNodesFamily->AddGroupName(submeshGrpName);
332 aFamilies.push_back(aNodesFamily);
334 if (!anEdgesFamily->IsEmpty()) {
335 anEdgesFamily->SetType(SMDSAbs_Edge);
336 anEdgesFamily->AddGroupName(submeshGrpName);
337 aFamilies.push_back(anEdgesFamily);
339 if (!aFacesFamily->IsEmpty()) {
340 aFacesFamily->SetType(SMDSAbs_Face);
341 aFacesFamily->AddGroupName(submeshGrpName);
342 aFamilies.push_back(aFacesFamily);
344 if (!aVolumesFamily->IsEmpty()) {
345 aVolumesFamily->SetType(SMDSAbs_Volume);
346 aVolumesFamily->AddGroupName(submeshGrpName);
347 aFamilies.push_back(aVolumesFamily);
353 //=============================================================================
355 * Remove from <myElements> elements, common with <by>,
356 * Remove from <by> elements, common with <myElements>,
357 * Create family <common> from common elements, with combined groups list.
359 //=============================================================================
360 void DriverMED_Family::Split (DriverMED_FamilyPtr by,
361 DriverMED_FamilyPtr common)
364 set<const SMDS_MeshElement *>::iterator anIter = by->myElements.begin();
365 while ( anIter != by->myElements.end())
367 if (myElements.find(*anIter) != myElements.end())
369 common->myElements.insert(*anIter);
370 myElements.erase(*anIter);
371 by->myElements.erase(anIter++);
377 if (!common->IsEmpty())
380 common->myGroupNames = myGroupNames;
381 set<string>::iterator aGrNamesIter = by->myGroupNames.begin();
382 for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
384 common->myGroupNames.insert(*aGrNamesIter);
388 common->myType = myType;