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"
40 #include "vtkDataObjectTreeIterator.h"
44 //#include <vtkstd/map>
45 //#include <vtkstd/deque>
47 // vtkCxxRevisionMacro(vtkExtractGroup, "$Revision$");
48 vtkStandardNewMacro(vtkExtractGroup);
50 vtkCxxSetObjectMacro(vtkExtractGroup, SIL, vtkMutableDirectedGraph);
52 vtkExtractGroup::vtkExtractGroup()
55 this->Entities=vtkDataArraySelection::New();
56 this->Families=vtkDataArraySelection::New();
57 this->Groups=vtkDataArraySelection::New();
61 vtkExtractGroup::~vtkExtractGroup()
63 this->Entities->Delete();
64 this->Families->Delete();
65 this->Groups->Delete();
68 int vtkExtractGroup::ModifyRequest(vtkInformation* request, int when)
70 request->Set(vtkDemandDrivenPipeline::REQUEST_REGENERATE_INFORMATION(), 1);
71 return this->Superclass::ModifyRequest(request, when);
74 int vtkExtractGroup::RequestInformation(vtkInformation *request,
75 vtkInformationVector **inputVector, vtkInformationVector *outputVector)
77 vtkInformation* outInfo=outputVector->GetInformationObject(0);
79 vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
81 vtkMutableDirectedGraph* old_SIL=this->GetSIL();
83 if(inputInfo->Has(vtkDataObject::SIL()))
85 this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(
86 vtkDataObject::SIL())));
90 vtkMutableDirectedGraph* sil=vtkMutableDirectedGraph::New();
91 this->BuildDefaultSIL(sil);
96 if(this->GetSIL()!=old_SIL||this->GetSIL()->GetMTime()>this->SILTime)
98 this->ClearSelections();
99 this->SILTime.Modified();
100 outInfo->Set(vtkDataObject::SIL(), this->GetSIL());
106 vtkIdType vtkExtractGroup::FindVertex(const char* name)
108 vtkStringArray* names=vtkStringArray::SafeDownCast(
109 this->GetSIL()->GetVertexData()->GetAbstractArray("Names"));
111 return names->LookupValue(name);
114 void vtkExtractGroup::ClearSelections()
116 this->Families->RemoveAllArrays();
117 this->Entities->RemoveAllArrays();
118 this->Groups->RemoveAllArrays();
121 void vtkExtractGroup::BuildDefaultSIL(vtkMutableDirectedGraph* sil)
125 vtkSmartPointer<vtkVariantArray> childEdge=
126 vtkSmartPointer<vtkVariantArray>::New();
127 childEdge->InsertNextValue(0);
129 vtkSmartPointer<vtkVariantArray> crossEdge=
130 vtkSmartPointer<vtkVariantArray>::New();
131 crossEdge->InsertNextValue(1);
133 // CrossEdge is an edge linking hierarchies.
134 vtkUnsignedCharArray* crossEdgesArray=vtkUnsignedCharArray::New();
135 crossEdgesArray->SetName("CrossEdges");
136 sil->GetEdgeData()->AddArray(crossEdgesArray);
137 crossEdgesArray->Delete();
138 std::deque<std::string> names;
140 // Now build the hierarchy.
141 vtkIdType rootId=sil->AddVertex();
142 names.push_back("SIL");
144 // Add a global entry to encode global names for the families
145 vtkIdType globalFamilyRoot=sil->AddChild(rootId, childEdge);
146 names.push_back("Families");
148 // Add a global entry to encode global names for the families
149 vtkIdType globalGroupRoot=sil->AddChild(rootId, childEdge);
150 names.push_back("Groups");
152 // Add the groups subtree
153 vtkIdType groupsRoot=sil->AddChild(rootId, childEdge);
154 names.push_back("GroupTree");
156 // Add the attributes subtree
157 vtkIdType attributesRoot=sil->AddChild(rootId, childEdge);
158 names.push_back("Attributes");
160 // Add a global entry to encode names for the cell types
161 vtkIdType globalEntityRoot=sil->AddChild(rootId, childEdge);
162 names.push_back("Entity");
164 // Add the cell types subtree
165 vtkIdType entityTypesRoot=sil->AddChild(rootId, childEdge);
166 names.push_back("EntityTree");
168 // This array is used to assign names to nodes.
169 vtkStringArray* namesArray=vtkStringArray::New();
170 namesArray->SetName("Names");
171 namesArray->SetNumberOfTuples(sil->GetNumberOfVertices());
172 sil->GetVertexData()->AddArray(namesArray);
173 namesArray->Delete();
174 std::deque<std::string>::iterator iter;
176 for(cc=0, iter=names.begin(); iter!=names.end(); ++iter, ++cc)
178 namesArray->SetValue(cc, (*iter).c_str());
183 int vtkExtractGroup::RequestData(vtkInformation *request,
184 vtkInformationVector **inputVector, vtkInformationVector *outputVector)
187 vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
188 vtkMultiBlockDataSet* inmb=vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(
189 vtkDataObject::DATA_OBJECT()));
194 vtkMultiBlockDataSet* outmb=this->GetOutput();
196 outmb->CopyStructure(inmb);
198 //vtkCompositeDataIterator* iterator = inmb->NewIterator();
199 vtkDataObjectTreeIterator* iterator = vtkDataObjectTreeIterator::SafeDownCast( inmb->NewIterator() );
200 iterator->SetVisitOnlyLeaves(true);
201 iterator->InitTraversal();
202 while(!iterator->IsDoneWithTraversal())
204 vtkDataObject* indo = iterator->GetCurrentDataObject();
208 if(indo->GetFieldData()->HasArray("BLOCK_NAME"))
211 vtkStringArray* path = vtkStringArray::SafeDownCast(
212 indo->GetFieldData()->GetAbstractArray("BLOCK_NAME"));
214 if(this->IsBlockSelected(path))
216 vtkMultiBlockDataSet* parent = vtkMedUtilities::GetParent(outmb, path);
217 int nb = parent->GetNumberOfBlocks();
218 parent->SetNumberOfBlocks(nb+1);
219 vtkDataObject *outdo = indo->NewInstance();
220 outdo->ShallowCopy(indo);
221 parent->SetBlock(nb, outdo);
225 iterator->GoToNextItem();
230 this->PruneEmptyBlocks(outmb);
235 void vtkExtractGroup::SetGroupStatus(const char* key, int flag)
237 vtkIdType index=this->Groups->GetArrayIndex(key);
240 index = this->Groups->AddArray(key);
243 int status=this->Groups->GetArraySetting(index);
248 this->Groups->EnableArray(key);
252 this->Groups->DisableArray(key);
256 this->GroupSelectionTime.Modified();
259 void vtkExtractGroup::PruneEmptyBlocks(vtkMultiBlockDataSet* mb)
264 while(nn<mb->GetNumberOfBlocks())
267 vtkDataObject* dataObj=mb->GetBlock(nn);
274 vtkMultiBlockDataSet* child=vtkMultiBlockDataSet::SafeDownCast(dataObj);
277 this->PruneEmptyBlocks(child);
278 if(child->GetNumberOfBlocks()==0)
295 int vtkExtractGroup::IsBlockSelected(vtkStringArray* path)
297 const char* meshName = (path->GetNumberOfValues()>0?
298 path->GetValue(0) : NULL);
299 const char* cellOrPoint = (path->GetNumberOfValues()>1?
300 path->GetValue(1) : NULL);
301 const char* familyName = (path->GetNumberOfValues()>2?
302 path->GetValue(2) : NULL);
304 if(!this->IsFamilySelected(meshName, cellOrPoint, familyName))
309 bool isOnPoint = (strcmp(cellOrPoint, vtkMedUtilities::OnPointName)==0);
311 const char* entityName = (isOnPoint || path->GetNumberOfValues()<=3 ? NULL :
317 return IsEntitySelected(entityName);
321 int vtkExtractGroup::IsEntitySelected(const char* entityKey)
323 return this->Entities->GetArraySetting(entityKey);
326 int vtkExtractGroup::IsFamilySelected(const char* meshName,
327 const char* pointOrCellKey, const char* familyName)
329 if(this->FamilySelectionTime <= this->GroupSelectionTime)
331 this->SelectFamiliesFromGroups();
335 pointOrCell= (strcmp(vtkMedUtilities::OnPointName, pointOrCellKey)==0?
336 vtkMedUtilities::OnPoint
337 : vtkMedUtilities::OnCell);
340 vtkMedUtilities::FamilyKey(meshName, pointOrCell, familyName);
342 return this->Families->GetArraySetting(name.c_str());
345 void vtkExtractGroup::SelectFamiliesFromGroups()
347 this->Families->DisableAllArrays();
348 vtkStringArray* names=vtkStringArray::SafeDownCast(
349 this->GetSIL()->GetVertexData()->GetAbstractArray("Names"));
351 for(int index = 0; index < this->Groups->GetNumberOfArrays(); index++)
353 if(this->Groups->GetArraySetting(index) == 0)
356 const char* name = this->Groups->GetArrayName(index);
357 vtkIdType silindex = this->FindVertex(name);
359 vtkInEdgeIterator* it = vtkInEdgeIterator::New();
361 this->GetSIL()->GetInEdges(silindex, it);
364 vtkIdType famId = it->Next().Source;
365 vtkStdString famName = names->GetValue(famId);
366 if(strncmp(famName, "FAMILY", 6)==0)
368 this->Families->EnableArray(famName.c_str());
374 this->FamilySelectionTime.Modified();
377 void vtkExtractGroup::SetEntityStatus(const char* key, int flag)
379 vtkIdType index=this->Entities->GetArrayIndex(key);
382 index = this->Entities->AddArray(key);
385 int status=this->Entities->GetArraySetting(index);
390 this->Entities->EnableArray(key);
394 this->Entities->DisableArray(key);
400 void vtkExtractGroup::SetFamilyStatus(const char* key, int flag)
402 vtkIdType index=this->Families->GetArrayIndex(key);
407 int status=this->Families->GetArraySetting(index);
412 this->Families->EnableArray(key);
416 this->Families->DisableArray(key);
421 int vtkExtractGroup::GetSILUpdateStamp()
423 return this->SILTime;
426 void vtkExtractGroup::PrintSelf(ostream& os, vtkIndent indent)
428 this->Superclass::PrintSelf(os, indent);