1 // Copyright (C) 2010-2012 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "vtkExtractGroup.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkMutableDirectedGraph.h"
24 #include "vtkMultiBlockDataSet.h"
25 #include "vtkInformationVector.h"
26 #include "vtkInformation.h"
27 #include "vtkDataArraySelection.h"
28 #include "vtkMedUtilities.h"
29 #include "vtkTimeStamp.h"
30 #include "vtkInEdgeIterator.h"
31 #include "vtkMedReader.h"
32 #include "vtkInformationDataObjectKey.h"
33 #include "vtkExecutive.h"
34 #include "vtkVariantArray.h"
35 #include "vtkStringArray.h"
36 #include "vtkUnsignedCharArray.h"
37 #include "vtkDataSetAttributes.h"
38 #include "vtkDemandDrivenPipeline.h"
39 #include "vtkCompositeDataIterator.h"
42 #include <vtkstd/deque>
44 vtkCxxRevisionMacro(vtkExtractGroup, "$Revision$");
45 vtkStandardNewMacro(vtkExtractGroup);
47 vtkCxxSetObjectMacro(vtkExtractGroup, SIL, vtkMutableDirectedGraph);
49 vtkExtractGroup::vtkExtractGroup()
52 this->Entities=vtkDataArraySelection::New();
53 this->Families=vtkDataArraySelection::New();
54 this->Groups=vtkDataArraySelection::New();
58 vtkExtractGroup::~vtkExtractGroup()
60 this->Entities->Delete();
61 this->Families->Delete();
62 this->Groups->Delete();
65 int vtkExtractGroup::ModifyRequest(vtkInformation* request, int when)
67 request->Set(vtkDemandDrivenPipeline::REQUEST_REGENERATE_INFORMATION(), 1);
68 return this->Superclass::ModifyRequest(request, when);
71 int vtkExtractGroup::RequestInformation(vtkInformation *request,
72 vtkInformationVector **inputVector, vtkInformationVector *outputVector)
74 vtkInformation* outInfo=outputVector->GetInformationObject(0);
76 vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
78 vtkMutableDirectedGraph* old_SIL=this->GetSIL();
80 if(inputInfo->Has(vtkDataObject::SIL()))
82 this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(
83 vtkDataObject::SIL())));
87 vtkMutableDirectedGraph* sil=vtkMutableDirectedGraph::New();
88 this->BuildDefaultSIL(sil);
93 if(this->GetSIL()!=old_SIL||this->GetSIL()->GetMTime()>this->SILTime)
95 this->ClearSelections();
96 this->SILTime.Modified();
97 outInfo->Set(vtkDataObject::SIL(), this->GetSIL());
103 vtkIdType vtkExtractGroup::FindVertex(const char* name)
105 vtkStringArray* names=vtkStringArray::SafeDownCast(
106 this->GetSIL()->GetVertexData()->GetAbstractArray("Names"));
108 return names->LookupValue(name);
111 void vtkExtractGroup::ClearSelections()
113 this->Families->RemoveAllArrays();
114 this->Entities->RemoveAllArrays();
115 this->Groups->RemoveAllArrays();
118 void vtkExtractGroup::BuildDefaultSIL(vtkMutableDirectedGraph* sil)
122 vtkSmartPointer<vtkVariantArray> childEdge=
123 vtkSmartPointer<vtkVariantArray>::New();
124 childEdge->InsertNextValue(0);
126 vtkSmartPointer<vtkVariantArray> crossEdge=
127 vtkSmartPointer<vtkVariantArray>::New();
128 crossEdge->InsertNextValue(1);
130 // CrossEdge is an edge linking hierarchies.
131 vtkUnsignedCharArray* crossEdgesArray=vtkUnsignedCharArray::New();
132 crossEdgesArray->SetName("CrossEdges");
133 sil->GetEdgeData()->AddArray(crossEdgesArray);
134 crossEdgesArray->Delete();
135 vtkstd::deque<vtkstd::string> names;
137 // Now build the hierarchy.
138 vtkIdType rootId=sil->AddVertex();
139 names.push_back("SIL");
141 // Add a global entry to encode global names for the families
142 vtkIdType globalFamilyRoot=sil->AddChild(rootId, childEdge);
143 names.push_back("Families");
145 // Add a global entry to encode global names for the families
146 vtkIdType globalGroupRoot=sil->AddChild(rootId, childEdge);
147 names.push_back("Groups");
149 // Add the groups subtree
150 vtkIdType groupsRoot=sil->AddChild(rootId, childEdge);
151 names.push_back("GroupTree");
153 // Add the attributes subtree
154 vtkIdType attributesRoot=sil->AddChild(rootId, childEdge);
155 names.push_back("Attributes");
157 // Add a global entry to encode names for the cell types
158 vtkIdType globalEntityRoot=sil->AddChild(rootId, childEdge);
159 names.push_back("Entity");
161 // Add the cell types subtree
162 vtkIdType entityTypesRoot=sil->AddChild(rootId, childEdge);
163 names.push_back("EntityTree");
165 // This array is used to assign names to nodes.
166 vtkStringArray* namesArray=vtkStringArray::New();
167 namesArray->SetName("Names");
168 namesArray->SetNumberOfTuples(sil->GetNumberOfVertices());
169 sil->GetVertexData()->AddArray(namesArray);
170 namesArray->Delete();
171 vtkstd::deque<vtkstd::string>::iterator iter;
173 for(cc=0, iter=names.begin(); iter!=names.end(); ++iter, ++cc)
175 namesArray->SetValue(cc, (*iter).c_str());
180 int vtkExtractGroup::RequestData(vtkInformation *request,
181 vtkInformationVector **inputVector, vtkInformationVector *outputVector)
184 vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
185 vtkMultiBlockDataSet* inmb=vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(
186 vtkDataObject::DATA_OBJECT()));
191 vtkMultiBlockDataSet* outmb=this->GetOutput();
193 outmb->CopyStructure(inmb);
195 vtkCompositeDataIterator* iterator = inmb->NewIterator();
196 iterator->SetVisitOnlyLeaves(true);
197 iterator->InitTraversal();
198 while(!iterator->IsDoneWithTraversal())
200 vtkDataObject* indo = iterator->GetCurrentDataObject();
204 if(indo->GetFieldData()->HasArray("BLOCK_NAME"))
207 vtkStringArray* path = vtkStringArray::SafeDownCast(
208 indo->GetFieldData()->GetAbstractArray("BLOCK_NAME"));
210 if(this->IsBlockSelected(path))
212 vtkMultiBlockDataSet* parent = vtkMedUtilities::GetParent(outmb, path);
213 int nb = parent->GetNumberOfBlocks();
214 parent->SetNumberOfBlocks(nb+1);
215 vtkDataObject *outdo = indo->NewInstance();
216 outdo->ShallowCopy(indo);
217 parent->SetBlock(nb, outdo);
221 iterator->GoToNextItem();
226 this->PruneEmptyBlocks(outmb);
231 void vtkExtractGroup::SetGroupStatus(const char* key, int flag)
233 vtkIdType index=this->Groups->GetArrayIndex(key);
236 index = this->Groups->AddArray(key);
239 int status=this->Groups->GetArraySetting(index);
244 this->Groups->EnableArray(key);
248 this->Groups->DisableArray(key);
252 this->GroupSelectionTime.Modified();
255 void vtkExtractGroup::PruneEmptyBlocks(vtkMultiBlockDataSet* mb)
260 while(nn<mb->GetNumberOfBlocks())
263 vtkDataObject* dataObj=mb->GetBlock(nn);
270 vtkMultiBlockDataSet* child=vtkMultiBlockDataSet::SafeDownCast(dataObj);
273 this->PruneEmptyBlocks(child);
274 if(child->GetNumberOfBlocks()==0)
291 int vtkExtractGroup::IsBlockSelected(vtkStringArray* path)
293 const char* meshName = (path->GetNumberOfValues()>0?
294 path->GetValue(0) : NULL);
295 const char* cellOrPoint = (path->GetNumberOfValues()>1?
296 path->GetValue(1) : NULL);
297 const char* familyName = (path->GetNumberOfValues()>2?
298 path->GetValue(2) : NULL);
300 if(!this->IsFamilySelected(meshName, cellOrPoint, familyName))
305 bool isOnPoint = (strcmp(cellOrPoint, vtkMedUtilities::OnPointName)==0);
307 const char* entityName = (isOnPoint || path->GetNumberOfValues()<=3 ? NULL :
313 return IsEntitySelected(entityName);
317 int vtkExtractGroup::IsEntitySelected(const char* entityKey)
319 return this->Entities->GetArraySetting(entityKey);
322 int vtkExtractGroup::IsFamilySelected(const char* meshName,
323 const char* pointOrCellKey, const char* familyName)
325 if(this->FamilySelectionTime <= this->GroupSelectionTime)
327 this->SelectFamiliesFromGroups();
331 pointOrCell= (strcmp(vtkMedUtilities::OnPointName, pointOrCellKey)==0?
332 vtkMedUtilities::OnPoint
333 : vtkMedUtilities::OnCell);
336 vtkMedUtilities::FamilyKey(meshName, pointOrCell, familyName);
338 return this->Families->GetArraySetting(name.c_str());
341 void vtkExtractGroup::SelectFamiliesFromGroups()
343 this->Families->DisableAllArrays();
344 vtkStringArray* names=vtkStringArray::SafeDownCast(
345 this->GetSIL()->GetVertexData()->GetAbstractArray("Names"));
347 for(int index = 0; index < this->Groups->GetNumberOfArrays(); index++)
349 if(this->Groups->GetArraySetting(index) == 0)
352 const char* name = this->Groups->GetArrayName(index);
353 vtkIdType silindex = this->FindVertex(name);
355 vtkInEdgeIterator* it = vtkInEdgeIterator::New();
357 this->GetSIL()->GetInEdges(silindex, it);
360 vtkIdType famId = it->Next().Source;
361 vtkStdString famName = names->GetValue(famId);
362 if(strncmp(famName, "FAMILY", 6)==0)
364 this->Families->EnableArray(famName.c_str());
370 this->FamilySelectionTime.Modified();
373 void vtkExtractGroup::SetEntityStatus(const char* key, int flag)
375 vtkIdType index=this->Entities->GetArrayIndex(key);
378 index = this->Entities->AddArray(key);
381 int status=this->Entities->GetArraySetting(index);
386 this->Entities->EnableArray(key);
390 this->Entities->DisableArray(key);
396 void vtkExtractGroup::SetFamilyStatus(const char* key, int flag)
398 vtkIdType index=this->Families->GetArrayIndex(key);
403 int status=this->Families->GetArraySetting(index);
408 this->Families->EnableArray(key);
412 this->Families->DisableArray(key);
417 int vtkExtractGroup::GetSILUpdateStamp()
419 return this->SILTime;
422 void vtkExtractGroup::PrintSelf(ostream& os, vtkIndent indent)
424 this->Superclass::PrintSelf(os, indent);