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"
31 //=============================================================================
33 * Split each group from list <aGroups> on some parts (families)
34 * on the basis of the elements membership in other groups from this list.
35 * Resulting families have no common elements.
37 //=============================================================================
38 list<DriverMED_FamilyPtr> DriverMED_Family::MakeFamilies
39 (const map <int, SMESHDS_SubMesh*>& theSubMeshes,
40 const list<SMESHDS_Group*>& theGroups,
41 const bool doGroupOfNodes,
42 const bool doGroupOfEdges,
43 const bool doGroupOfFaces,
44 const bool doGroupOfVolumes)
46 list<DriverMED_FamilyPtr> aFamilies;
48 string anAllNodesGroupName = "Group_Of_All_Nodes";
49 string anAllEdgesGroupName = "Group_Of_All_Edges";
50 string anAllFacesGroupName = "Group_Of_All_Faces";
51 string anAllVolumesGroupName = "Group_Of_All_Volumes";
53 // Reserve four ids for families of free elements
54 // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
55 // 'Free' means here not belonging to any group.
56 int aNodeFamId = FIRST_NODE_FAMILY;
57 int aElemFamId = FIRST_ELEM_FAMILY;
60 map<int, SMESHDS_SubMesh*>::const_iterator aSMIter = theSubMeshes.begin();
61 for (; aSMIter != theSubMeshes.end(); aSMIter++)
63 list<DriverMED_FamilyPtr> aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first);
64 list<DriverMED_FamilyPtr>::iterator aSMFamsIter = aSMFams.begin();
65 for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
67 DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
69 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
70 while (aFamsIter != aFamilies.end())
72 DriverMED_FamilyPtr aFam1 = *aFamsIter;
73 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
74 if (aFam1->myType == aFam2->myType)
76 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
77 aFam1->Split(aFam2, aCommon);
78 if (!aCommon->IsEmpty())
80 aFamilies.push_back(aCommon);
84 aFamilies.erase(aCurrIter);
86 if (aFam2->IsEmpty()) break;
89 // The rest elements of family
90 if (!aFam2->IsEmpty())
92 aFamilies.push_back(aFam2);
98 list<SMESHDS_Group*>::const_iterator aGroupsIter = theGroups.begin();
99 for (; aGroupsIter != theGroups.end(); aGroupsIter++)
101 DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
102 aFam2->Init(*aGroupsIter);
104 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
105 while (aFamsIter != aFamilies.end())
107 DriverMED_FamilyPtr aFam1 = *aFamsIter;
108 list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
109 if (aFam1->myType == aFam2->myType)
111 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
112 aFam1->Split(aFam2, aCommon);
113 if (!aCommon->IsEmpty())
115 aFamilies.push_back(aCommon);
117 if (aFam1->IsEmpty())
119 aFamilies.erase(aCurrIter);
121 if (aFam2->IsEmpty()) break;
124 // The rest elements of group
125 if (!aFam2->IsEmpty())
127 aFamilies.push_back(aFam2);
131 list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
132 for (; aFamsIter != aFamilies.end(); aFamsIter++)
134 DriverMED_FamilyPtr aFam = *aFamsIter;
135 if (aFam->myType == SMDSAbs_Node) {
136 aFam->SetId(aNodeFamId++);
137 if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
140 aFam->SetId(aElemFamId--);
141 if (aFam->myType == SMDSAbs_Edge) {
142 if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
144 else if (aFam->myType == SMDSAbs_Face) {
145 if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
147 else if (aFam->myType == SMDSAbs_Volume) {
148 if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
153 // Create families for elements, not belonging to any group
156 DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
157 aFreeNodesFam->SetId(REST_NODES_FAMILY);
158 aFreeNodesFam->myType = SMDSAbs_Node;
159 aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
160 aFamilies.push_back(aFreeNodesFam);
165 DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
166 aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
167 aFreeEdgesFam->myType = SMDSAbs_Edge;
168 aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
169 aFamilies.push_back(aFreeEdgesFam);
174 DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
175 aFreeFacesFam->SetId(REST_FACES_FAMILY);
176 aFreeFacesFam->myType = SMDSAbs_Face;
177 aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
178 aFamilies.push_back(aFreeFacesFam);
181 if (doGroupOfVolumes)
183 DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
184 aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
185 aFreeVolumesFam->myType = SMDSAbs_Volume;
186 aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
187 aFamilies.push_back(aFreeVolumesFam);
190 DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
192 aNullFam->myType = SMDSAbs_All;
193 aFamilies.push_back(aNullFam);
198 //=============================================================================
200 * Create TFamilyInfo for this family
202 //=============================================================================
203 MEDA::PFamilyInfo DriverMED_Family::GetFamilyInfo
204 (const MEDA::PMeshInfo& theMeshInfo) const
210 MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description,
211 MED::TIntVector anAttrIds (1, myId); // Id=0,
212 MED::TIntVector anAttrVals (1, myId); // Value=0
214 MEDA::PFamilyInfo anInfo = MEDA::TWrapper::CrFamilyInfo(theMeshInfo,
218 anAttrDescs,anAttrIds,anAttrVals);
221 // cout << "Groups: ";
222 // set<string>::iterator aGrIter = myGroupNames.begin();
223 // for (; aGrIter != myGroupNames.end(); aGrIter++)
225 // cout << " " << *aGrIter;
229 // cout << "Elements: ";
230 // set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
231 // for (; anIter != myElements.end(); anIter++)
233 // cout << " " << (*anIter)->GetID();
240 //=============================================================================
242 * Initialize the tool by SMESHDS_Group
244 //=============================================================================
245 void DriverMED_Family::Init (SMESHDS_Group* group)
249 group->InitIterator();
250 while (group->More())
252 myElements.insert(group->Next());
256 myType = group->GetType();
259 myGroupNames.clear();
260 myGroupNames.insert(string(group->GetStoreName()));
263 //=============================================================================
265 * Split <theSubMesh> on some parts (families)
266 * on the basis of the elements type.
268 //=============================================================================
269 list<DriverMED_FamilyPtr> DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh,
272 list<DriverMED_FamilyPtr> aFamilies;
273 DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family);
274 DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family);
275 DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family);
276 DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
278 char submeshGrpName[ 30 ];
279 sprintf( submeshGrpName, "SubMesh %d", theId );
281 SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
282 while (aNodesIter->more())
284 const SMDS_MeshNode* aNode = aNodesIter->next();
285 aNodesFamily->AddElement(aNode);
288 SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
289 while (anElemsIter->more())
291 const SMDS_MeshElement* anElem = anElemsIter->next();
292 switch (anElem->GetType())
295 anEdgesFamily->AddElement(anElem);
298 aFacesFamily->AddElement(anElem);
301 aVolumesFamily->AddElement(anElem);
308 if (!aNodesFamily->IsEmpty()) {
309 aNodesFamily->SetType(SMDSAbs_Node);
310 aNodesFamily->AddGroupName(submeshGrpName);
311 aFamilies.push_back(aNodesFamily);
313 if (!anEdgesFamily->IsEmpty()) {
314 anEdgesFamily->SetType(SMDSAbs_Edge);
315 anEdgesFamily->AddGroupName(submeshGrpName);
316 aFamilies.push_back(anEdgesFamily);
318 if (!aFacesFamily->IsEmpty()) {
319 aFacesFamily->SetType(SMDSAbs_Face);
320 aFacesFamily->AddGroupName(submeshGrpName);
321 aFamilies.push_back(aFacesFamily);
323 if (!aVolumesFamily->IsEmpty()) {
324 aVolumesFamily->SetType(SMDSAbs_Volume);
325 aVolumesFamily->AddGroupName(submeshGrpName);
326 aFamilies.push_back(aVolumesFamily);
332 //=============================================================================
334 * Remove from <myElements> elements, common with <by>,
335 * Remove from <by> elements, common with <myElements>,
336 * Create family <common> from common elements, with combined groups list.
338 //=============================================================================
339 void DriverMED_Family::Split (DriverMED_FamilyPtr by,
340 DriverMED_FamilyPtr common)
343 set<const SMDS_MeshElement *>::iterator anIter = by->myElements.begin();
344 for (; anIter != by->myElements.end(); anIter++)
346 if (myElements.find(*anIter) != myElements.end())
348 common->myElements.insert(*anIter);
349 myElements.erase(*anIter);
350 by->myElements.erase(*anIter);
354 if (!common->IsEmpty())
357 common->myGroupNames = myGroupNames;
358 set<string>::iterator aGrNamesIter = by->myGroupNames.begin();
359 for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
361 common->myGroupNames.insert(*aGrNamesIter);
365 common->myType = myType;