Back to index

salome-smesh  6.5.0
DriverMED_Family.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH DriverMED : tool to split groups on families
00024 //  File   : DriverMED_Family.cxx
00025 //  Author : Julia DOROVSKIKH
00026 //  Module : SMESH
00027 //  $Header: /home/server/cvs/SMESH/SMESH_SRC/src/DriverMED/DriverMED_Family.cxx,v 1.18.2.1.6.5.8.1 2012-04-13 09:31:03 vsr Exp $
00028 //
00029 #include "DriverMED_Family.h"
00030 #include "MED_Factory.hxx"
00031 
00032 #include <sstream>      
00033 
00034 using namespace std;
00035 
00036 //=============================================================================
00040 //=============================================================================
00041 DriverMED_Family
00042 ::DriverMED_Family():
00043   myGroupAttributVal(0)
00044 {}
00045 
00046 
00047 //=============================================================================
00048 const ElementsSet& 
00049 DriverMED_Family
00050 ::GetElements () const 
00051 { 
00052   return myElements; 
00053 }
00054 
00055 int 
00056 DriverMED_Family
00057 ::GetId () const 
00058 { 
00059   return myId; 
00060 }
00061 
00062 void 
00063 DriverMED_Family
00064 ::SetId (const int theId) 
00065 { 
00066   myId = theId; 
00067 }
00068 
00069 void
00070 DriverMED_Family
00071 ::AddElement(const SMDS_MeshElement* theElement)
00072 {
00073   myElements.insert(theElement); 
00074 }
00075 
00076 void
00077 DriverMED_Family
00078 ::AddGroupName(std::string theGroupName)
00079 {
00080   myGroupNames.insert(theGroupName); 
00081 }
00082 
00083 void
00084 DriverMED_Family
00085 ::SetType(const SMDSAbs_ElementType theType) 
00086 { 
00087   myTypes.insert( myType = theType );
00088 }
00089 
00090 SMDSAbs_ElementType
00091 DriverMED_Family
00092 ::GetType()
00093 {
00094   return myType; 
00095 }
00096 
00097 const std::set< SMDSAbs_ElementType >&
00098 DriverMED_Family
00099 ::GetTypes() const
00100 {
00101   return myTypes;
00102 }
00103 
00104 bool
00105 DriverMED_Family
00106 ::MemberOf(std::string theGroupName) const
00107 { 
00108   return myGroupNames.find(theGroupName) != myGroupNames.end(); 
00109 }
00110 
00111 const MED::TStringSet& 
00112 DriverMED_Family
00113 ::GetGroupNames () const 
00114 { 
00115   return myGroupNames; 
00116 }
00117 
00118 
00119 int 
00120 DriverMED_Family
00121 ::GetGroupAttributVal() const 
00122 {
00123   return myGroupAttributVal;
00124 } 
00125 
00126 void
00127 DriverMED_Family
00128 ::SetGroupAttributVal( int theValue) 
00129 {
00130   myGroupAttributVal = theValue;
00131 }
00132 
00133 bool
00134 DriverMED_Family
00135 ::IsEmpty () const 
00136 { 
00137   return myElements.empty(); 
00138 }
00139 
00140 //=============================================================================
00146 //=============================================================================
00147 DriverMED_FamilyPtrList 
00148 DriverMED_Family
00149 ::MakeFamilies(const SMESHDS_SubMeshPtrMap& theSubMeshes,
00150                const SMESHDS_GroupBasePtrList& theGroups,
00151                const bool doGroupOfNodes,
00152                const bool doGroupOfEdges,
00153                const bool doGroupOfFaces,
00154                const bool doGroupOfVolumes)
00155 {
00156   DriverMED_FamilyPtrList aFamilies;
00157 
00158   string anAllNodesGroupName = "Group_Of_All_Nodes";
00159   string anAllEdgesGroupName = "Group_Of_All_Edges";
00160   string anAllFacesGroupName = "Group_Of_All_Faces";
00161   string anAllVolumesGroupName = "Group_Of_All_Volumes";
00162 
00163   // Reserve four ids for families of free elements
00164   // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
00165   // 'Free' means here not belonging to any group.
00166   int aNodeFamId = FIRST_NODE_FAMILY;
00167   int aElemFamId = FIRST_ELEM_FAMILY;
00168 
00169   // Process sub-meshes
00170   SMESHDS_SubMeshPtrMap::const_iterator aSMIter = theSubMeshes.begin();
00171   for (; aSMIter != theSubMeshes.end(); aSMIter++)
00172   {
00173     const int anId = aSMIter->first;
00174     SMESHDS_SubMesh* aSubMesh = aSMIter->second;
00175     if ( aSubMesh->IsComplexSubmesh() )
00176       continue; // submesh containing other submeshs
00177     DriverMED_FamilyPtrList aSMFams = SplitByType(aSubMesh,anId);
00178     DriverMED_FamilyPtrList::iterator aSMFamsIter = aSMFams.begin();
00179     for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
00180     {
00181       DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
00182       DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin();
00183       while (aFamsIter != aFamilies.end())
00184       {
00185         DriverMED_FamilyPtr aFam1 = *aFamsIter;
00186         DriverMED_FamilyPtrList::iterator aCurrIter = aFamsIter++;
00187         if (aFam1->myType == aFam2->myType)
00188         {
00189           DriverMED_FamilyPtr aCommon (new DriverMED_Family);
00190           aFam1->Split(aFam2, aCommon);
00191           if (!aCommon->IsEmpty())
00192           {
00193             aFamilies.push_back(aCommon);
00194           }
00195           if (aFam1->IsEmpty())
00196           {
00197             aFamilies.erase(aCurrIter);
00198           }
00199           if (aFam2->IsEmpty()) 
00200             break;
00201         }
00202       }
00203       // The rest elements of family
00204       if (!aFam2->IsEmpty())
00205       {
00206         aFamilies.push_back(aFam2);
00207       }
00208     }
00209   }
00210 
00211   // Process groups
00212   SMESHDS_GroupBasePtrList::const_iterator aGroupsIter = theGroups.begin();
00213   for (; aGroupsIter != theGroups.end(); aGroupsIter++)
00214   {
00215     DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
00216     aFam2->Init(*aGroupsIter);
00217 
00218     DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin();
00219     while (aFamsIter != aFamilies.end())
00220     {
00221       DriverMED_FamilyPtr aFam1 = *aFamsIter;
00222       DriverMED_FamilyPtrList::iterator aCurrIter = aFamsIter++;
00223       if (aFam1->myType == aFam2->myType)
00224       {
00225         DriverMED_FamilyPtr aCommon (new DriverMED_Family);
00226         aFam1->Split(aFam2, aCommon);
00227         if (!aCommon->IsEmpty())
00228         {
00229           aCommon->SetGroupAttributVal(0);
00230           aFamilies.push_back(aCommon);
00231         }
00232         if (aFam1->IsEmpty())
00233         {
00234           aFamilies.erase(aCurrIter);
00235         }
00236         if (aFam2->IsEmpty()) 
00237           break;
00238       }
00239     }
00240     // The rest elements of group
00241     if (!aFam2->IsEmpty())
00242     {
00243       aFamilies.push_back(aFam2);
00244     }
00245   }
00246 
00247   DriverMED_FamilyPtrList::iterator aFamsIter = aFamilies.begin();
00248   for (; aFamsIter != aFamilies.end(); aFamsIter++)
00249   {
00250     DriverMED_FamilyPtr aFam = *aFamsIter;
00251     if (aFam->myType == SMDSAbs_Node) {
00252       aFam->SetId(aNodeFamId++);
00253       if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
00254     }
00255     else {
00256       aFam->SetId(aElemFamId--);
00257       if (aFam->myType == SMDSAbs_Edge) {
00258         if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
00259       }
00260       else if (aFam->myType == SMDSAbs_Face) {
00261         if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
00262       }
00263       else if (aFam->myType == SMDSAbs_Volume) {
00264         if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
00265       }
00266     }
00267   }
00268 
00269   // Create families for elements, not belonging to any group
00270   if (doGroupOfNodes)
00271   {
00272     DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
00273     aFreeNodesFam->SetId(REST_NODES_FAMILY);
00274     aFreeNodesFam->myType = SMDSAbs_Node;
00275     aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
00276     aFamilies.push_back(aFreeNodesFam);
00277   }
00278 
00279   if (doGroupOfEdges)
00280   {
00281     DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
00282     aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
00283     aFreeEdgesFam->myType = SMDSAbs_Edge;
00284     aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
00285     aFamilies.push_back(aFreeEdgesFam);
00286   }
00287 
00288   if (doGroupOfFaces)
00289   {
00290     DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
00291     aFreeFacesFam->SetId(REST_FACES_FAMILY);
00292     aFreeFacesFam->myType = SMDSAbs_Face;
00293     aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
00294     aFamilies.push_back(aFreeFacesFam);
00295   }
00296 
00297   if (doGroupOfVolumes)
00298   {
00299     DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
00300     aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
00301     aFreeVolumesFam->myType = SMDSAbs_Volume;
00302     aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
00303     aFamilies.push_back(aFreeVolumesFam);
00304   }
00305 
00306   DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
00307   aNullFam->SetId(0);
00308   aNullFam->myType = SMDSAbs_All;
00309   aFamilies.push_back(aNullFam);
00310 
00311   return aFamilies;
00312 }
00313 
00314 //=============================================================================
00318 //=============================================================================
00319 MED::PFamilyInfo 
00320 DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper, 
00321                                 const MED::PMeshInfo& theMeshInfo) const
00322 {
00323   ostringstream aStr;
00324   aStr << "FAM_" << myId;
00325   set<string>::const_iterator aGrIter = myGroupNames.begin();
00326   for(; aGrIter != myGroupNames.end(); aGrIter++){
00327     aStr << "_" << *aGrIter;
00328   }
00329   string aValue = aStr.str();
00330   // PAL19785,0019867 - med forbids whitespace to be the last char in the name
00331   int maxSize;
00332   if ( theWrapper->GetVersion() == MED::eV2_1 )
00333     maxSize = MED::GetNOMLength<MED::eV2_1>();
00334   else
00335     maxSize = MED::GetNOMLength<MED::eV2_2>();
00336   int lastCharPos = min( maxSize, (int) aValue.size() ) - 1;
00337   while ( isspace( aValue[ lastCharPos ] ))
00338     aValue.resize( lastCharPos-- );
00339 
00340   MED::PFamilyInfo anInfo;
00341   if(myId == 0 || myGroupAttributVal == 0){
00342     anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
00343                                       aValue,
00344                                       myId,
00345                                       myGroupNames);
00346   }else{
00347     MED::TStringVector anAttrDescs (1, "");  // 1 attribute with empty description,
00348     MED::TIntVector anAttrIds (1, myId);        // Id=0,
00349     MED::TIntVector anAttrVals (1, myGroupAttributVal);
00350     anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
00351                                       aValue,
00352                                       myId,
00353                                       myGroupNames,
00354                                       anAttrDescs,
00355                                       anAttrIds,
00356                                       anAttrVals);
00357   }
00358 
00359 //  cout << endl;
00360 //  cout << "Groups: ";
00361 //  set<string>::iterator aGrIter = myGroupNames.begin();
00362 //  for (; aGrIter != myGroupNames.end(); aGrIter++)
00363 //  {
00364 //    cout << " " << *aGrIter;
00365 //  }
00366 //  cout << endl;
00367 //
00368 //  cout << "Elements: ";
00369 //  set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
00370 //  for (; anIter != myElements.end(); anIter++)
00371 //  {
00372 //    cout << " " << (*anIter)->GetID();
00373 //  }
00374 //  cout << endl;
00375 
00376   return anInfo;
00377 }
00378 
00379 //=============================================================================
00383 //=============================================================================
00384 void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
00385 {
00386   // Elements
00387   myElements.clear();
00388   SMDS_ElemIteratorPtr elemIt = theGroup->GetElements();
00389   while (elemIt->more())
00390   {
00391     myElements.insert(elemIt->next());
00392   }
00393 
00394   // Type
00395   myType = theGroup->GetType();
00396 
00397   // Groups list
00398   myGroupNames.clear();
00399   myGroupNames.insert(string(theGroup->GetStoreName()));
00400 
00401   Quantity_Color aColor = theGroup->GetColor();
00402   double aRed = aColor.Red();
00403   double aGreen = aColor.Green();
00404   double aBlue = aColor.Blue();
00405   int aR = int( aRed*255   );
00406   int aG = int( aGreen*255 );
00407   int aB = int( aBlue*255  );
00408 //   cout << "aRed = " << aR << endl;
00409 //   cout << "aGreen = " << aG << endl;
00410 //   cout << "aBlue = " << aB << endl;
00411   myGroupAttributVal = (int)(aR*1000000 + aG*1000 + aB);
00412   //cout << "myGroupAttributVal = " << myGroupAttributVal << endl;
00413 }
00414 
00415 //=============================================================================
00420 //=============================================================================
00421 DriverMED_FamilyPtrList 
00422 DriverMED_Family
00423 ::SplitByType (SMESHDS_SubMesh* theSubMesh,
00424                const int        theId)
00425 {
00426   DriverMED_FamilyPtrList aFamilies;
00427   DriverMED_FamilyPtr aNodesFamily   (new DriverMED_Family);
00428   DriverMED_FamilyPtr anEdgesFamily  (new DriverMED_Family);
00429   DriverMED_FamilyPtr aFacesFamily   (new DriverMED_Family);
00430   DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
00431 
00432   char submeshGrpName[ 30 ];
00433   sprintf( submeshGrpName, "SubMesh %d", theId );
00434 
00435   SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
00436   while (aNodesIter->more())
00437   {
00438     const SMDS_MeshNode* aNode = aNodesIter->next();
00439     aNodesFamily->AddElement(aNode);
00440   }
00441 
00442   SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
00443   while (anElemsIter->more())
00444   {
00445     const SMDS_MeshElement* anElem = anElemsIter->next();
00446     switch (anElem->GetType())
00447     {
00448     case SMDSAbs_Edge:
00449       anEdgesFamily->AddElement(anElem);
00450       break;
00451     case SMDSAbs_Face:
00452       aFacesFamily->AddElement(anElem);
00453       break;
00454     case SMDSAbs_Volume:
00455       aVolumesFamily->AddElement(anElem);
00456       break;
00457     default:
00458       break;
00459     }
00460   }
00461 
00462   if (!aNodesFamily->IsEmpty()) {
00463     aNodesFamily->SetType(SMDSAbs_Node);
00464     aNodesFamily->AddGroupName(submeshGrpName);
00465     aFamilies.push_back(aNodesFamily);
00466   }
00467   if (!anEdgesFamily->IsEmpty()) {
00468     anEdgesFamily->SetType(SMDSAbs_Edge);
00469     anEdgesFamily->AddGroupName(submeshGrpName);
00470     aFamilies.push_back(anEdgesFamily);
00471   }
00472   if (!aFacesFamily->IsEmpty()) {
00473     aFacesFamily->SetType(SMDSAbs_Face);
00474     aFacesFamily->AddGroupName(submeshGrpName);
00475     aFamilies.push_back(aFacesFamily);
00476   }
00477   if (!aVolumesFamily->IsEmpty()) {
00478     aVolumesFamily->SetType(SMDSAbs_Volume);
00479     aVolumesFamily->AddGroupName(submeshGrpName);
00480     aFamilies.push_back(aVolumesFamily);
00481   }
00482 
00483   return aFamilies;
00484 }
00485 
00486 //=============================================================================
00492 //=============================================================================
00493 void DriverMED_Family::Split (DriverMED_FamilyPtr by,
00494                               DriverMED_FamilyPtr common)
00495 {
00496   // Elements
00497   ElementsSet::iterator anIter = by->myElements.begin();
00498   while ( anIter != by->myElements.end())
00499   {
00500     if (myElements.find(*anIter) != myElements.end())
00501     {
00502       common->myElements.insert(*anIter);
00503       myElements.erase(*anIter);
00504       by->myElements.erase(anIter++);
00505     }
00506     else
00507       anIter++;
00508   }
00509 
00510   if (!common->IsEmpty())
00511   {
00512     // Groups list
00513     common->myGroupNames = myGroupNames;
00514     MED::TStringSet::iterator aGrNamesIter = by->myGroupNames.begin();
00515     for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
00516     {
00517       common->myGroupNames.insert(*aGrNamesIter);
00518     }
00519 
00520     // Type
00521     common->myType = myType;
00522   }
00523 }