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 //=============================================================================
39 //=============================================================================
46 //=============================================================================
49 ::GetElements () const
63 ::SetId (const int theId)
70 ::AddElement(const SMDS_MeshElement* theElement)
72 myElements.insert(theElement);
77 ::AddGroupName(std::string theGroupName)
79 myGroupNames.insert(theGroupName);
84 ::SetType(const SMDSAbs_ElementType theType)
98 ::MemberOf(std::string theGroupName) const
100 return myGroupNames.find(theGroupName) != myGroupNames.end();
103 const MED::TStringSet&
105 ::GetGroupNames () const
113 ::GetGroupAttributVal() const
115 return myGroupAttributVal;
120 ::SetGroupAttributVal( int theValue)
122 myGroupAttributVal = theValue;
129 return myElements.empty();
132 //=============================================================================
134 * Split each group from list <aGroups> on some parts (families)
135 * on the basis of the elements membership in other groups from this list.
136 * Resulting families have no common elements.
138 //=============================================================================
139 DriverMED_FamilyPtrList
141 ::MakeFamilies(const SMESHDS_SubMeshPtrMap& theSubMeshes,
142 const SMESHDS_GroupBasePtrList& theGroups,
143 const bool doGroupOfNodes,
144 const bool doGroupOfEdges,
145 const bool doGroupOfFaces,
146 const bool doGroupOfVolumes)
148 DriverMED_FamilyPtrList aFamilies;
150 string anAllNodesGroupName = "Group_Of_All_Nodes";
151 string anAllEdgesGroupName = "Group_Of_All_Edges";
152 string anAllFacesGroupName = "Group_Of_All_Faces";
153 string anAllVolumesGroupName = "Group_Of_All_Volumes";
155 // Reserve four ids for families of free elements
156 // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
157 // 'Free' means here not belonging to any group.
158 int aNodeFamId = FIRST_NODE_FAMILY;
159 int aElemFamId = FIRST_ELEM_FAMILY;
161 // Process sub-meshes
162 SMESHDS_SubMeshPtrMap::const_iterator aSMIter = theSubMeshes.begin();
163 for (; aSMIter != theSubMeshes.end(); aSMIter++)
165 const int anId = aSMIter->first;
166 SMESHDS_SubMesh* aSubMesh = aSMIter->second;
167 if ( aSubMesh->IsComplexSubmesh() )
168 continue; // submesh containing other submeshs
169 DriverMED_FamilyPtrList aSMFams = SplitByType(aSubMesh,anId);
170 DriverMED_FamilyPtrList::iterator aSMFamsIter = aSMFams.begin();
171 for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
173 DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
174 DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin();
175 while (aFamsIter != aFamilies.end())
177 DriverMED_FamilyPtr aFam1 = *aFamsIter;
178 DriverMED_FamilyPtrList::iterator aCurrIter = aFamsIter++;
179 if (aFam1->myType == aFam2->myType)
181 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
182 aFam1->Split(aFam2, aCommon);
183 if (!aCommon->IsEmpty())
185 aFamilies.push_back(aCommon);
187 if (aFam1->IsEmpty())
189 aFamilies.erase(aCurrIter);
191 if (aFam2->IsEmpty())
195 // The rest elements of family
196 if (!aFam2->IsEmpty())
198 aFamilies.push_back(aFam2);
204 SMESHDS_GroupBasePtrList::const_iterator aGroupsIter = theGroups.begin();
205 for (; aGroupsIter != theGroups.end(); aGroupsIter++)
207 DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
208 aFam2->Init(*aGroupsIter);
210 DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin();
211 while (aFamsIter != aFamilies.end())
213 DriverMED_FamilyPtr aFam1 = *aFamsIter;
214 DriverMED_FamilyPtrList::iterator aCurrIter = aFamsIter++;
215 if (aFam1->myType == aFam2->myType)
217 DriverMED_FamilyPtr aCommon (new DriverMED_Family);
218 aFam1->Split(aFam2, aCommon);
219 if (!aCommon->IsEmpty())
221 aCommon->SetGroupAttributVal(0);
222 aFamilies.push_back(aCommon);
224 if (aFam1->IsEmpty())
226 aFamilies.erase(aCurrIter);
228 if (aFam2->IsEmpty())
232 // The rest elements of group
233 if (!aFam2->IsEmpty())
235 aFamilies.push_back(aFam2);
239 DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin();
240 for (; aFamsIter != aFamilies.end(); aFamsIter++)
242 DriverMED_FamilyPtr aFam = *aFamsIter;
243 if (aFam->myType == SMDSAbs_Node) {
244 aFam->SetId(aNodeFamId++);
245 if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
248 aFam->SetId(aElemFamId--);
249 if (aFam->myType == SMDSAbs_Edge) {
250 if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
252 else if (aFam->myType == SMDSAbs_Face) {
253 if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
255 else if (aFam->myType == SMDSAbs_Volume) {
256 if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
261 // Create families for elements, not belonging to any group
264 DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
265 aFreeNodesFam->SetId(REST_NODES_FAMILY);
266 aFreeNodesFam->myType = SMDSAbs_Node;
267 aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
268 aFamilies.push_back(aFreeNodesFam);
273 DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
274 aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
275 aFreeEdgesFam->myType = SMDSAbs_Edge;
276 aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
277 aFamilies.push_back(aFreeEdgesFam);
282 DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
283 aFreeFacesFam->SetId(REST_FACES_FAMILY);
284 aFreeFacesFam->myType = SMDSAbs_Face;
285 aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
286 aFamilies.push_back(aFreeFacesFam);
289 if (doGroupOfVolumes)
291 DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
292 aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
293 aFreeVolumesFam->myType = SMDSAbs_Volume;
294 aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
295 aFamilies.push_back(aFreeVolumesFam);
298 DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
300 aNullFam->myType = SMDSAbs_All;
301 aFamilies.push_back(aNullFam);
306 //=============================================================================
308 * Create TFamilyInfo for this family
310 //=============================================================================
312 DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper,
313 const MED::PMeshInfo& theMeshInfo) const
316 aStr << "FAM_" << myId;
317 set<string>::const_iterator aGrIter = myGroupNames.begin();
318 for(; aGrIter != myGroupNames.end(); aGrIter++){
319 aStr << "_" << *aGrIter;
322 MED::PFamilyInfo anInfo;
323 string aValue = aStr.str();
325 anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
330 MED::TStringVector anAttrDescs (1, ""); // 1 attribute with empty description,
331 MED::TIntVector anAttrIds (1, myId); // Id=0,
332 MED::TIntVector anAttrVals (1);
333 anAttrVals[0] = myGroupAttributVal != 0? myGroupAttributVal: myId;
334 anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
344 // cout << "Groups: ";
345 // set<string>::iterator aGrIter = myGroupNames.begin();
346 // for (; aGrIter != myGroupNames.end(); aGrIter++)
348 // cout << " " << *aGrIter;
352 // cout << "Elements: ";
353 // set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
354 // for (; anIter != myElements.end(); anIter++)
356 // cout << " " << (*anIter)->GetID();
363 //=============================================================================
365 * Initialize the tool by SMESHDS_GroupBase
367 //=============================================================================
368 void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
372 SMDS_ElemIteratorPtr elemIt = theGroup->GetElements();
373 while (elemIt->more())
375 myElements.insert(elemIt->next());
379 myType = theGroup->GetType();
382 myGroupNames.clear();
383 myGroupNames.insert(string(theGroup->GetStoreName()));
385 myGroupAttributVal = 0;
387 if (theGroup->GetColorGroup()!=0)
389 myGroupAttributVal = theGroup->GetColorGroup();
394 //=============================================================================
396 * Split <theSubMesh> on some parts (families)
397 * on the basis of the elements type.
399 //=============================================================================
400 DriverMED_FamilyPtrList
402 ::SplitByType (SMESHDS_SubMesh* theSubMesh,
405 DriverMED_FamilyPtrList aFamilies;
406 DriverMED_FamilyPtr aNodesFamily (new DriverMED_Family);
407 DriverMED_FamilyPtr anEdgesFamily (new DriverMED_Family);
408 DriverMED_FamilyPtr aFacesFamily (new DriverMED_Family);
409 DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
411 char submeshGrpName[ 30 ];
412 sprintf( submeshGrpName, "SubMesh %d", theId );
414 SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
415 while (aNodesIter->more())
417 const SMDS_MeshNode* aNode = aNodesIter->next();
418 aNodesFamily->AddElement(aNode);
421 SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
422 while (anElemsIter->more())
424 const SMDS_MeshElement* anElem = anElemsIter->next();
425 switch (anElem->GetType())
428 anEdgesFamily->AddElement(anElem);
431 aFacesFamily->AddElement(anElem);
434 aVolumesFamily->AddElement(anElem);
441 if (!aNodesFamily->IsEmpty()) {
442 aNodesFamily->SetType(SMDSAbs_Node);
443 aNodesFamily->AddGroupName(submeshGrpName);
444 aFamilies.push_back(aNodesFamily);
446 if (!anEdgesFamily->IsEmpty()) {
447 anEdgesFamily->SetType(SMDSAbs_Edge);
448 anEdgesFamily->AddGroupName(submeshGrpName);
449 aFamilies.push_back(anEdgesFamily);
451 if (!aFacesFamily->IsEmpty()) {
452 aFacesFamily->SetType(SMDSAbs_Face);
453 aFacesFamily->AddGroupName(submeshGrpName);
454 aFamilies.push_back(aFacesFamily);
456 if (!aVolumesFamily->IsEmpty()) {
457 aVolumesFamily->SetType(SMDSAbs_Volume);
458 aVolumesFamily->AddGroupName(submeshGrpName);
459 aFamilies.push_back(aVolumesFamily);
465 //=============================================================================
467 * Remove from <myElements> elements, common with <by>,
468 * Remove from <by> elements, common with <myElements>,
469 * Create family <common> from common elements, with combined groups list.
471 //=============================================================================
472 void DriverMED_Family::Split (DriverMED_FamilyPtr by,
473 DriverMED_FamilyPtr common)
476 ElementsSet::iterator anIter = by->myElements.begin();
477 while ( anIter != by->myElements.end())
479 if (myElements.find(*anIter) != myElements.end())
481 common->myElements.insert(*anIter);
482 myElements.erase(*anIter);
483 by->myElements.erase(anIter++);
489 if (!common->IsEmpty())
492 common->myGroupNames = myGroupNames;
493 MED::TStringSet::iterator aGrNamesIter = by->myGroupNames.begin();
494 for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
496 common->myGroupNames.insert(*aGrNamesIter);
500 common->myType = myType;