Back to index

salome-paravis  6.5.0
vtkExtractGroup.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2010-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "vtkExtractGroup.h"
00021 
00022 #include "vtkObjectFactory.h"
00023 #include "vtkMutableDirectedGraph.h"
00024 #include "vtkMultiBlockDataSet.h"
00025 #include "vtkInformationVector.h"
00026 #include "vtkInformation.h"
00027 #include "vtkDataArraySelection.h"
00028 #include "vtkMedUtilities.h"
00029 #include "vtkTimeStamp.h"
00030 #include "vtkInEdgeIterator.h"
00031 #include "vtkMedReader.h"
00032 #include "vtkInformationDataObjectKey.h"
00033 #include "vtkExecutive.h"
00034 #include "vtkVariantArray.h"
00035 #include "vtkStringArray.h"
00036 #include "vtkUnsignedCharArray.h"
00037 #include "vtkDataSetAttributes.h"
00038 #include "vtkDemandDrivenPipeline.h"
00039 #include "vtkCompositeDataIterator.h"
00040 
00041 #include <vtkstd/map>
00042 #include <vtkstd/deque>
00043 
00044 vtkCxxRevisionMacro(vtkExtractGroup, "$Revision: 1.1.4.3.12.1 $");
00045 vtkStandardNewMacro(vtkExtractGroup);
00046 
00047 vtkCxxSetObjectMacro(vtkExtractGroup, SIL, vtkMutableDirectedGraph);
00048 
00049 vtkExtractGroup::vtkExtractGroup()
00050 {
00051   this->SIL=NULL;
00052   this->Entities=vtkDataArraySelection::New();
00053   this->Families=vtkDataArraySelection::New();
00054   this->Groups=vtkDataArraySelection::New();
00055   this->PruneOutput=0;
00056 }
00057 
00058 vtkExtractGroup::~vtkExtractGroup()
00059 {
00060   this->Entities->Delete();
00061   this->Families->Delete();
00062   this->Groups->Delete();
00063 }
00064 
00065 int vtkExtractGroup::ModifyRequest(vtkInformation* request, int when)
00066 {
00067   request->Set(vtkDemandDrivenPipeline::REQUEST_REGENERATE_INFORMATION(), 1);
00068   return this->Superclass::ModifyRequest(request, when);
00069 }
00070 
00071 int vtkExtractGroup::RequestInformation(vtkInformation *request,
00072     vtkInformationVector **inputVector, vtkInformationVector *outputVector)
00073 {
00074   vtkInformation* outInfo=outputVector->GetInformationObject(0);
00075 
00076   vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
00077 
00078   vtkMutableDirectedGraph* old_SIL=this->GetSIL();
00079 
00080   if(inputInfo->Has(vtkDataObject::SIL()))
00081     {
00082     this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(
00083         vtkDataObject::SIL())));
00084     }
00085   else
00086     {
00087     vtkMutableDirectedGraph* sil=vtkMutableDirectedGraph::New();
00088     this->BuildDefaultSIL(sil);
00089     this->SetSIL(sil);
00090     sil->Delete();
00091     }
00092 
00093   if(this->GetSIL()!=old_SIL||this->GetSIL()->GetMTime()>this->SILTime)
00094     {
00095     this->ClearSelections();
00096     this->SILTime.Modified();
00097     outInfo->Set(vtkDataObject::SIL(), this->GetSIL());
00098     }
00099 
00100   return 1;
00101 }
00102 
00103 vtkIdType vtkExtractGroup::FindVertex(const char* name)
00104 {
00105   vtkStringArray* names=vtkStringArray::SafeDownCast(
00106       this->GetSIL()->GetVertexData()->GetAbstractArray("Names"));
00107 
00108   return names->LookupValue(name);
00109 }
00110 
00111 void vtkExtractGroup::ClearSelections()
00112 {
00113   this->Families->RemoveAllArrays();
00114   this->Entities->RemoveAllArrays();
00115   this->Groups->RemoveAllArrays();
00116 }
00117 
00118 void vtkExtractGroup::BuildDefaultSIL(vtkMutableDirectedGraph* sil)
00119 {
00120   sil->Initialize();
00121 
00122   vtkSmartPointer<vtkVariantArray> childEdge=
00123       vtkSmartPointer<vtkVariantArray>::New();
00124   childEdge->InsertNextValue(0);
00125 
00126   vtkSmartPointer<vtkVariantArray> crossEdge=
00127       vtkSmartPointer<vtkVariantArray>::New();
00128   crossEdge->InsertNextValue(1);
00129 
00130   // CrossEdge is an edge linking hierarchies.
00131   vtkUnsignedCharArray* crossEdgesArray=vtkUnsignedCharArray::New();
00132   crossEdgesArray->SetName("CrossEdges");
00133   sil->GetEdgeData()->AddArray(crossEdgesArray);
00134   crossEdgesArray->Delete();
00135   vtkstd::deque<vtkstd::string> names;
00136 
00137   // Now build the hierarchy.
00138   vtkIdType rootId=sil->AddVertex();
00139   names.push_back("SIL");
00140 
00141   // Add a global entry to encode global names for the families
00142   vtkIdType globalFamilyRoot=sil->AddChild(rootId, childEdge);
00143   names.push_back("Families");
00144 
00145   // Add a global entry to encode global names for the families
00146   vtkIdType globalGroupRoot=sil->AddChild(rootId, childEdge);
00147   names.push_back("Groups");
00148 
00149   // Add the groups subtree
00150   vtkIdType groupsRoot=sil->AddChild(rootId, childEdge);
00151   names.push_back("GroupTree");
00152 
00153   // Add the attributes subtree
00154   vtkIdType attributesRoot=sil->AddChild(rootId, childEdge);
00155   names.push_back("Attributes");
00156 
00157   // Add a global entry to encode names for the cell types
00158   vtkIdType globalEntityRoot=sil->AddChild(rootId, childEdge);
00159   names.push_back("Entity");
00160 
00161   // Add the cell types subtree
00162   vtkIdType entityTypesRoot=sil->AddChild(rootId, childEdge);
00163   names.push_back("EntityTree");
00164 
00165   // This array is used to assign names to nodes.
00166   vtkStringArray* namesArray=vtkStringArray::New();
00167   namesArray->SetName("Names");
00168   namesArray->SetNumberOfTuples(sil->GetNumberOfVertices());
00169   sil->GetVertexData()->AddArray(namesArray);
00170   namesArray->Delete();
00171   vtkstd::deque<vtkstd::string>::iterator iter;
00172   vtkIdType cc;
00173   for(cc=0, iter=names.begin(); iter!=names.end(); ++iter, ++cc)
00174     {
00175     namesArray->SetValue(cc, (*iter).c_str());
00176     }
00177 
00178 }
00179 
00180 int vtkExtractGroup::RequestData(vtkInformation *request,
00181     vtkInformationVector **inputVector, vtkInformationVector *outputVector)
00182 
00183 {
00184   vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
00185   vtkMultiBlockDataSet* inmb=vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(
00186       vtkDataObject::DATA_OBJECT()));
00187 
00188   if(inmb==NULL)
00189     return 0;
00190 
00191   vtkMultiBlockDataSet* outmb=this->GetOutput();
00192 
00193   outmb->CopyStructure(inmb);
00194 
00195   vtkCompositeDataIterator* iterator = inmb->NewIterator();
00196   iterator->SetVisitOnlyLeaves(true);
00197   iterator->InitTraversal();
00198   while(!iterator->IsDoneWithTraversal())
00199     {
00200     vtkDataObject* indo = iterator->GetCurrentDataObject();
00201     if(indo == NULL)
00202       continue;
00203 
00204     if(indo->GetFieldData()->HasArray("BLOCK_NAME"))
00205       {
00206 
00207       vtkStringArray* path = vtkStringArray::SafeDownCast(
00208           indo->GetFieldData()->GetAbstractArray("BLOCK_NAME"));
00209 
00210       if(this->IsBlockSelected(path))
00211         {
00212         vtkMultiBlockDataSet* parent = vtkMedUtilities::GetParent(outmb, path);
00213         int nb = parent->GetNumberOfBlocks();
00214         parent->SetNumberOfBlocks(nb+1);
00215         vtkDataObject *outdo = indo->NewInstance();
00216         outdo->ShallowCopy(indo);
00217         parent->SetBlock(nb, outdo);
00218         outdo->Delete();
00219         }
00220       }
00221     iterator->GoToNextItem();
00222     }
00223 
00224   if(PruneOutput)
00225     {
00226     this->PruneEmptyBlocks(outmb);
00227     }
00228   return 1;
00229 }
00230 
00231 void vtkExtractGroup::SetGroupStatus(const char* key, int flag)
00232 {
00233   vtkIdType index=this->Groups->GetArrayIndex(key);
00234   if(index==-1)
00235     {
00236     index = this->Groups->AddArray(key);
00237     this->Modified();
00238     }
00239   int status=this->Groups->GetArraySetting(index);
00240   if(status!=flag)
00241     {
00242     if(flag)
00243       {
00244       this->Groups->EnableArray(key);
00245       }
00246     else
00247       {
00248       this->Groups->DisableArray(key);
00249       }
00250     this->Modified();
00251     }
00252   this->GroupSelectionTime.Modified();
00253 }
00254 
00255 void vtkExtractGroup::PruneEmptyBlocks(vtkMultiBlockDataSet* mb)
00256 {
00257   if(mb==NULL)
00258     return;
00259   vtkIdType nn=0;
00260   while(nn<mb->GetNumberOfBlocks())
00261     {
00262     bool remove=false;
00263     vtkDataObject* dataObj=mb->GetBlock(nn);
00264     if(dataObj==NULL)
00265       {
00266       remove=true;
00267       }
00268     else
00269       {
00270       vtkMultiBlockDataSet* child=vtkMultiBlockDataSet::SafeDownCast(dataObj);
00271       if(child!=NULL)
00272         {
00273         this->PruneEmptyBlocks(child);
00274         if(child->GetNumberOfBlocks()==0)
00275           {
00276           remove=true;
00277           }
00278         }
00279       }
00280     if(remove)
00281       {
00282       mb->RemoveBlock(nn);
00283       }
00284     else
00285       {
00286       nn++;
00287       }
00288     }
00289 }
00290 
00291 int vtkExtractGroup::IsBlockSelected(vtkStringArray* path)
00292 {
00293   const char* meshName = (path->GetNumberOfValues()>0?
00294                           path->GetValue(0) : NULL);
00295   const char* cellOrPoint = (path->GetNumberOfValues()>1?
00296                              path->GetValue(1) : NULL);
00297   const char* familyName = (path->GetNumberOfValues()>2?
00298                             path->GetValue(2) : NULL);
00299 
00300   if(!this->IsFamilySelected(meshName, cellOrPoint, familyName))
00301     {
00302     return 0;
00303     }
00304 
00305   bool isOnPoint = (strcmp(cellOrPoint, vtkMedUtilities::OnPointName)==0);
00306 
00307   const char* entityName = (isOnPoint || path->GetNumberOfValues()<=3 ? NULL :
00308                             path->GetValue(3));
00309 
00310   if(isOnPoint)
00311     return true;
00312 
00313   return IsEntitySelected(entityName);
00314 
00315 }
00316 
00317 int vtkExtractGroup::IsEntitySelected(const char* entityKey)
00318 {
00319   return this->Entities->GetArraySetting(entityKey);
00320 }
00321 
00322 int vtkExtractGroup::IsFamilySelected(const char* meshName,
00323     const char* pointOrCellKey, const char* familyName)
00324 {
00325   if(this->FamilySelectionTime <= this->GroupSelectionTime)
00326     {
00327     this->SelectFamiliesFromGroups();
00328     }
00329 
00330   int
00331       pointOrCell= (strcmp(vtkMedUtilities::OnPointName, pointOrCellKey)==0?
00332                     vtkMedUtilities::OnPoint
00333                     : vtkMedUtilities::OnCell);
00334 
00335   std::string name=
00336       vtkMedUtilities::FamilyKey(meshName, pointOrCell, familyName);
00337 
00338   return this->Families->GetArraySetting(name.c_str());
00339 }
00340 
00341 void vtkExtractGroup::SelectFamiliesFromGroups()
00342 {
00343   this->Families->DisableAllArrays();
00344   vtkStringArray* names=vtkStringArray::SafeDownCast(
00345       this->GetSIL()->GetVertexData()->GetAbstractArray("Names"));
00346 
00347   for(int index = 0; index < this->Groups->GetNumberOfArrays(); index++)
00348     {
00349     if(this->Groups->GetArraySetting(index) == 0)
00350       continue;
00351 
00352     const char* name = this->Groups->GetArrayName(index);
00353     vtkIdType silindex = this->FindVertex(name);
00354 
00355     vtkInEdgeIterator* it = vtkInEdgeIterator::New();
00356 
00357     this->GetSIL()->GetInEdges(silindex, it);
00358     while(it->HasNext())
00359       {
00360       vtkIdType famId = it->Next().Source;
00361       vtkStdString famName = names->GetValue(famId);
00362       if(strncmp(famName, "FAMILY", 6)==0)
00363         {
00364         this->Families->EnableArray(famName.c_str());
00365         }
00366       }
00367     it->Delete();
00368     }
00369 
00370   this->FamilySelectionTime.Modified();
00371 }
00372 
00373 void vtkExtractGroup::SetEntityStatus(const char* key, int flag)
00374 {
00375   vtkIdType index=this->Entities->GetArrayIndex(key);
00376   if(index==-1)
00377     {
00378     index = this->Entities->AddArray(key);
00379     this->Modified();
00380     }
00381   int status=this->Entities->GetArraySetting(index);
00382   if(status!=flag)
00383     {
00384     if(flag)
00385       {
00386       this->Entities->EnableArray(key);
00387       }
00388     else
00389       {
00390       this->Entities->DisableArray(key);
00391       }
00392     this->Modified();
00393     }
00394 }
00395 
00396 void vtkExtractGroup::SetFamilyStatus(const char* key, int flag)
00397 {
00398   vtkIdType index=this->Families->GetArrayIndex(key);
00399   if(index==-1)
00400     {
00401     return;
00402     }
00403   int status=this->Families->GetArraySetting(index);
00404   if(status!=flag)
00405     {
00406     if(flag)
00407       {
00408       this->Families->EnableArray(key);
00409       }
00410     else
00411       {
00412       this->Families->DisableArray(key);
00413       }
00414     }
00415 }
00416 
00417 int vtkExtractGroup::GetSILUpdateStamp()
00418 {
00419   return this->SILTime;
00420 }
00421 
00422 void vtkExtractGroup::PrintSelf(ostream& os, vtkIndent indent)
00423 {
00424   this->Superclass::PrintSelf(os, indent);
00425 }