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"
33 //=============================================================================
35 * Split each group from list <aGroups> on some parts (families)
36 * on the basis of the elements membership in other groups from this list.
37 * Resulting families have no common elements.
39 //=============================================================================
40 list<DriverMED_FamilyPtr> DriverMED_Family::MakeFamilies
41 (const map <int, SMESHDS_SubMesh*>& theSubMeshes,
42 const list<SMESHDS_GroupBase*>& theGroups,
43 const bool doGroupOfNodes,
44 const bool doGroupOfEdges,
45 const bool doGroupOfFaces,
46 const bool doGroupOfVolumes)
48 list<DriverMED_FamilyPtr> aFamilies;
50 string anAllNodesGroupName = "Group_Of_All_Nodes";
51 string anAllEdgesGroupName = "Group_Of_All_Edges";
52 string anAllFacesGroupName = "Group_Of_All_Faces";
53 string anAllVolumesGroupName = "Group_Of_All_Volumes";
55 // Reserve four ids for families of free elements
56 // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
57 // 'Free' means here not belonging to any group.
58 int aNodeFamId = FIRST_NODE_FAMILY;
59 int aElemFamId = FIRST_ELEM_FAMILY;
62 map<int, SMESHDS_SubMesh*>::const_iterator aSMIter = theSubMeshes.begin();
63 for (; aSMIter != theSubMeshes.end(); aSMIter++)
65 if ( aSMIter->second->IsComplexSubmesh() )
66 continue; // submesh containing other submeshs
67 list<DriverMED_FamilyPtr> aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first);
68 list<DriverMED_FamilyPtr>::iterator aSMFamsIter = aSMFams.begin();
69 for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
71 DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
73 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
74 while (aFamsIter != aFamilies.end())
76 DriverMED_FamilyPtr aFam1 = *aFamsIter;
77 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
78 if (aFam1->myType == aFam2->myType)
80 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
81 aFam1->Split(aFam2, aCommon);
82 if (!aCommon->IsEmpty())
84 aFamilies.push_back(aCommon);
88 aFamilies.erase(aCurrIter);
90 if (aFam2->IsEmpty()) break;
93 // The rest elements of family
94 if (!aFam2->IsEmpty())
96 aFamilies.push_back(aFam2);
102 list<SMESHDS_GroupBase*>::const_iterator aGroupsIter = theGroups.begin();
103 for (; aGroupsIter != theGroups.end(); aGroupsIter++)
105 DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
106 aFam2->Init(*aGroupsIter);
108 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
109 while (aFamsIter != aFamilies.end())
111 DriverMED_FamilyPtr aFam1 = *aFamsIter;
112 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
113 if (aFam1->myType == aFam2->myType)
115 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
116 aFam1->Split(aFam2, aCommon);
117 if (!aCommon->IsEmpty())
119 aFamilies.push_back(aCommon);
121 if (aFam1->IsEmpty())
123 aFamilies.erase(aCurrIter);
125 if (aFam2->IsEmpty()) break;
128 // The rest elements of group
129 if (!aFam2->IsEmpty())
131 aFamilies.push_back(aFam2);
135 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
136 for (; aFamsIter != aFamilies.end(); aFamsIter++)
138 DriverMED_FamilyPtr aFam = *aFamsIter;
139 if (aFam->myType == SMDSAbs_Node) {
140 aFam->SetId(aNodeFamId++);
141 if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
144 aFam->SetId(aElemFamId--);
145 if (aFam->myType == SMDSAbs_Edge) {
146 if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
148 else if (aFam->myType == SMDSAbs_Face) {
149 if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
151 else if (aFam->myType == SMDSAbs_Volume) {
152 if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
157 // Create families for elements, not belonging to any group
160 DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
161 aFreeNodesFam->SetId(REST_NODES_FAMILY);
162 aFreeNodesFam->myType = SMDSAbs_Node;
163 aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
164 aFamilies.push_back(aFreeNodesFam);
169 DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
170 aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
171 aFreeEdgesFam->myType = SMDSAbs_Edge;
172 aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
173 aFamilies.push_back(aFreeEdgesFam);
178 DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
179 aFreeFacesFam->SetId(REST_FACES_FAMILY);
180 aFreeFacesFam->myType = SMDSAbs_Face;
181 aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
182 aFamilies.push_back(aFreeFacesFam);
185 if (doGroupOfVolumes)
187 DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
188 aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
189 aFreeVolumesFam->myType = SMDSAbs_Volume;
190 aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
191 aFamilies.push_back(aFreeVolumesFam);
194 DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
196 aNullFam->myType = SMDSAbs_All;
197 aFamilies.push_back(aNullFam);
202 //=============================================================================
204 * Create TFamilyInfo for this family
206 //=============================================================================
207 MEDA::PFamilyInfo DriverMED_Family::GetFamilyInfo
208 (const MEDA::PMeshInfo& theMeshInfo) const
214 MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description,
215 MED::TIntVector anAttrIds (1, myId); // Id=0,
216 MED::TIntVector anAttrVals (1, myId); // Value=0
218 MEDA::PFamilyInfo anInfo = MEDA::TWrapper::CrFamilyInfo(theMeshInfo,
222 anAttrDescs,anAttrIds,anAttrVals);
225 // cout << "Groups: ";
226 // set<string>::iterator aGrIter = myGroupNames.begin();
227 // for (; aGrIter != myGroupNames.end(); aGrIter++)
229 // cout << " " << *aGrIter;
233 // cout << "Elements: ";
234 // set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
235 // for (; anIter != myElements.end(); anIter++)
237 // cout << " " << (*anIter)->GetID();
244 //=============================================================================
246 * Initialize the tool by SMESHDS_GroupBase
248 //=============================================================================
249 void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
253 SMDS_ElemIteratorPtr elemIt = theGroup->GetElements();
254 while (elemIt->more())
256 myElements.insert(elemIt->next());
260 myType = theGroup->GetType();
263 myGroupNames.clear();
264 myGroupNames.insert(string(theGroup->GetStoreName()));
267 //=============================================================================
269 * Split <theSubMesh> on some parts (families)
270 * on the basis of the elements type.
272 //=============================================================================
273 list<DriverMED_FamilyPtr> DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh,
276 list<DriverMED_FamilyPtr> aFamilies;
277 DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family);
278 DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family);
279 DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family);
280 DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
282 char submeshGrpName[ 30 ];
283 sprintf( submeshGrpName, "SubMesh %d", theId );
285 SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
286 while (aNodesIter->more())
288 const SMDS_MeshNode* aNode = aNodesIter->next();
289 aNodesFamily->AddElement(aNode);
292 SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
293 while (anElemsIter->more())
295 const SMDS_MeshElement* anElem = anElemsIter->next();
296 switch (anElem->GetType())
299 anEdgesFamily->AddElement(anElem);
302 aFacesFamily->AddElement(anElem);
305 aVolumesFamily->AddElement(anElem);
312 if (!aNodesFamily->IsEmpty()) {
313 aNodesFamily->SetType(SMDSAbs_Node);
314 aNodesFamily->AddGroupName(submeshGrpName);
315 aFamilies.push_back(aNodesFamily);
317 if (!anEdgesFamily->IsEmpty()) {
318 anEdgesFamily->SetType(SMDSAbs_Edge);
319 anEdgesFamily->AddGroupName(submeshGrpName);
320 aFamilies.push_back(anEdgesFamily);
322 if (!aFacesFamily->IsEmpty()) {
323 aFacesFamily->SetType(SMDSAbs_Face);
324 aFacesFamily->AddGroupName(submeshGrpName);
325 aFamilies.push_back(aFacesFamily);
327 if (!aVolumesFamily->IsEmpty()) {
328 aVolumesFamily->SetType(SMDSAbs_Volume);
329 aVolumesFamily->AddGroupName(submeshGrpName);
330 aFamilies.push_back(aVolumesFamily);
336 //=============================================================================
338 * Remove from <myElements> elements, common with <by>,
339 * Remove from <by> elements, common with <myElements>,
340 * Create family <common> from common elements, with combined groups list.
342 //=============================================================================
343 void DriverMED_Family::Split (DriverMED_FamilyPtr by,
344 DriverMED_FamilyPtr common)
347 set<const SMDS_MeshElement *>::iterator anIter = by->myElements.begin();
348 for (; anIter != by->myElements.end(); anIter++)
350 if (myElements.find(*anIter) != myElements.end())
352 common->myElements.insert(*anIter);
353 myElements.erase(*anIter);
354 by->myElements.erase(*anIter);
358 if (!common->IsEmpty())
361 common->myGroupNames = myGroupNames;
362 set<string>::iterator aGrNamesIter = by->myGroupNames.begin();
363 for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
365 common->myGroupNames.insert(*aGrNamesIter);
369 common->myType = myType;