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_Group*>& 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 list<DriverMED_FamilyPtr> aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first);
66 list<DriverMED_FamilyPtr>::iterator aSMFamsIter = aSMFams.begin();
67 for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
69 DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
71 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
72 while (aFamsIter != aFamilies.end())
74 DriverMED_FamilyPtr aFam1 = *aFamsIter;
75 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
76 if (aFam1->myType == aFam2->myType)
78 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
79 aFam1->Split(aFam2, aCommon);
80 if (!aCommon->IsEmpty())
82 aFamilies.push_back(aCommon);
86 aFamilies.erase(aCurrIter);
88 if (aFam2->IsEmpty()) break;
91 // The rest elements of family
92 if (!aFam2->IsEmpty())
94 aFamilies.push_back(aFam2);
100 list<SMESHDS_Group*>::const_iterator aGroupsIter = theGroups.begin();
101 for (; aGroupsIter != theGroups.end(); aGroupsIter++)
103 DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
104 aFam2->Init(*aGroupsIter);
106 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
107 while (aFamsIter != aFamilies.end())
109 DriverMED_FamilyPtr aFam1 = *aFamsIter;
110 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
111 if (aFam1->myType == aFam2->myType)
113 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
114 aFam1->Split(aFam2, aCommon);
115 if (!aCommon->IsEmpty())
117 aFamilies.push_back(aCommon);
119 if (aFam1->IsEmpty())
121 aFamilies.erase(aCurrIter);
123 if (aFam2->IsEmpty()) break;
126 // The rest elements of group
127 if (!aFam2->IsEmpty())
129 aFamilies.push_back(aFam2);
133 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
134 for (; aFamsIter != aFamilies.end(); aFamsIter++)
136 DriverMED_FamilyPtr aFam = *aFamsIter;
137 if (aFam->myType == SMDSAbs_Node) {
138 aFam->SetId(aNodeFamId++);
139 if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
142 aFam->SetId(aElemFamId--);
143 if (aFam->myType == SMDSAbs_Edge) {
144 if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
146 else if (aFam->myType == SMDSAbs_Face) {
147 if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
149 else if (aFam->myType == SMDSAbs_Volume) {
150 if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
155 // Create families for elements, not belonging to any group
158 DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
159 aFreeNodesFam->SetId(REST_NODES_FAMILY);
160 aFreeNodesFam->myType = SMDSAbs_Node;
161 aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
162 aFamilies.push_back(aFreeNodesFam);
167 DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
168 aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
169 aFreeEdgesFam->myType = SMDSAbs_Edge;
170 aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
171 aFamilies.push_back(aFreeEdgesFam);
176 DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
177 aFreeFacesFam->SetId(REST_FACES_FAMILY);
178 aFreeFacesFam->myType = SMDSAbs_Face;
179 aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
180 aFamilies.push_back(aFreeFacesFam);
183 if (doGroupOfVolumes)
185 DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
186 aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
187 aFreeVolumesFam->myType = SMDSAbs_Volume;
188 aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
189 aFamilies.push_back(aFreeVolumesFam);
192 DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
194 aNullFam->myType = SMDSAbs_All;
195 aFamilies.push_back(aNullFam);
200 //=============================================================================
202 * Create TFamilyInfo for this family
204 //=============================================================================
205 MEDA::PFamilyInfo DriverMED_Family::GetFamilyInfo
206 (const MEDA::PMeshInfo& theMeshInfo) const
212 MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description,
213 MED::TIntVector anAttrIds (1, myId); // Id=0,
214 MED::TIntVector anAttrVals (1, myId); // Value=0
216 MEDA::PFamilyInfo anInfo = MEDA::TWrapper::CrFamilyInfo(theMeshInfo,
220 anAttrDescs,anAttrIds,anAttrVals);
223 // cout << "Groups: ";
224 // set<string>::iterator aGrIter = myGroupNames.begin();
225 // for (; aGrIter != myGroupNames.end(); aGrIter++)
227 // cout << " " << *aGrIter;
231 // cout << "Elements: ";
232 // set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
233 // for (; anIter != myElements.end(); anIter++)
235 // cout << " " << (*anIter)->GetID();
242 //=============================================================================
244 * Initialize the tool by SMESHDS_Group
246 //=============================================================================
247 void DriverMED_Family::Init (SMESHDS_Group* group)
251 group->InitIterator();
252 while (group->More())
254 myElements.insert(group->Next());
258 myType = group->GetType();
261 myGroupNames.clear();
262 myGroupNames.insert(string(group->GetStoreName()));
265 //=============================================================================
267 * Split <theSubMesh> on some parts (families)
268 * on the basis of the elements type.
270 //=============================================================================
271 list<DriverMED_FamilyPtr> DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh,
274 list<DriverMED_FamilyPtr> aFamilies;
275 DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family);
276 DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family);
277 DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family);
278 DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
280 char submeshGrpName[ 30 ];
281 sprintf( submeshGrpName, "SubMesh %d", theId );
283 SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
284 while (aNodesIter->more())
286 const SMDS_MeshNode* aNode = aNodesIter->next();
287 aNodesFamily->AddElement(aNode);
290 SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
291 while (anElemsIter->more())
293 const SMDS_MeshElement* anElem = anElemsIter->next();
294 switch (anElem->GetType())
297 anEdgesFamily->AddElement(anElem);
300 aFacesFamily->AddElement(anElem);
303 aVolumesFamily->AddElement(anElem);
310 if (!aNodesFamily->IsEmpty()) {
311 aNodesFamily->SetType(SMDSAbs_Node);
312 aNodesFamily->AddGroupName(submeshGrpName);
313 aFamilies.push_back(aNodesFamily);
315 if (!anEdgesFamily->IsEmpty()) {
316 anEdgesFamily->SetType(SMDSAbs_Edge);
317 anEdgesFamily->AddGroupName(submeshGrpName);
318 aFamilies.push_back(anEdgesFamily);
320 if (!aFacesFamily->IsEmpty()) {
321 aFacesFamily->SetType(SMDSAbs_Face);
322 aFacesFamily->AddGroupName(submeshGrpName);
323 aFamilies.push_back(aFacesFamily);
325 if (!aVolumesFamily->IsEmpty()) {
326 aVolumesFamily->SetType(SMDSAbs_Volume);
327 aVolumesFamily->AddGroupName(submeshGrpName);
328 aFamilies.push_back(aVolumesFamily);
334 //=============================================================================
336 * Remove from <myElements> elements, common with <by>,
337 * Remove from <by> elements, common with <myElements>,
338 * Create family <common> from common elements, with combined groups list.
340 //=============================================================================
341 void DriverMED_Family::Split (DriverMED_FamilyPtr by,
342 DriverMED_FamilyPtr common)
345 set<const SMDS_MeshElement *>::iterator anIter = by->myElements.begin();
346 for (; anIter != by->myElements.end(); anIter++)
348 if (myElements.find(*anIter) != myElements.end())
350 common->myElements.insert(*anIter);
351 myElements.erase(*anIter);
352 by->myElements.erase(*anIter);
356 if (!common->IsEmpty())
359 common->myGroupNames = myGroupNames;
360 set<string>::iterator aGrNamesIter = by->myGroupNames.begin();
361 for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
363 common->myGroupNames.insert(*aGrNamesIter);
367 common->myType = myType;