1 // Copyright (C) 2010-2015 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, or (at your option) any later version.
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
19 // Author : Anthony Geay
21 #include "vtkExtractCellType.h"
22 #include "MEDFileFieldRepresentationTree.hxx"
23 #include "MEDFileFieldOverView.hxx"
25 #include "vtkAdjacentVertexIterator.h"
26 #include "vtkIntArray.h"
27 #include "vtkCellData.h"
28 #include "vtkPointData.h"
30 #include "vtkStreamingDemandDrivenPipeline.h"
31 #include "vtkUnstructuredGrid.h"
32 #include "vtkMultiBlockDataSet.h"
34 #include "vtkInformationStringKey.h"
35 #include "vtkAlgorithmOutput.h"
36 #include "vtkObjectFactory.h"
37 #include "vtkMutableDirectedGraph.h"
38 #include "vtkMultiBlockDataSet.h"
39 #include "vtkDataSet.h"
40 #include "vtkInformationVector.h"
41 #include "vtkInformation.h"
42 #include "vtkDataArraySelection.h"
43 #include "vtkTimeStamp.h"
44 #include "vtkInEdgeIterator.h"
45 #include "vtkInformationDataObjectKey.h"
46 #include "vtkExecutive.h"
47 #include "vtkVariantArray.h"
48 #include "vtkStringArray.h"
49 #include "vtkDoubleArray.h"
50 #include "vtkCharArray.h"
51 #include "vtkUnsignedCharArray.h"
52 #include "vtkDataSetAttributes.h"
53 #include "vtkDemandDrivenPipeline.h"
54 #include "vtkDataObjectTreeIterator.h"
55 #include "vtkThreshold.h"
60 vtkStandardNewMacro(vtkExtractCellType);
62 vtkCxxSetObjectMacro(vtkExtractCellType, SIL, vtkMutableDirectedGraph);
66 class ExtractCellTypeStatus
69 ExtractCellTypeStatus():_status(false),_vtkt(-1),_mct(INTERP_KERNEL::NORM_ERROR) { }
70 ExtractCellTypeStatus(int vtkt, INTERP_KERNEL::NormalizedCellType mct);
71 bool isSame(int vtkt, INTERP_KERNEL::NormalizedCellType mct) const { return _vtkt==vtkt && _mct==mct; }
72 bool getStatus() const { return _status; }
73 void setStatus(bool status) const { _status=status; }
74 void cpyStatusFrom(const ExtractCellTypeStatus& other) { _status=other._status; }
75 std::string getKey() const { return _type_str; }
76 const char *getKeyOfEntry() const { return _type_str.c_str(); }
77 int getVTKCellType() const { return _vtkt; }
78 void printMySelf(std::ostream& os) const;
79 bool isSameAs(const ExtractCellTypeStatus& other) const;
80 void feedSIL(vtkMutableDirectedGraph *sil, vtkIdType root, vtkVariantArray *childEdge, std::vector<std::string>& names) const;
84 INTERP_KERNEL::NormalizedCellType _mct;
85 std::string _type_str;
88 class vtkExtractCellType::vtkExtractCellTypeInternal
91 vtkExtractCellTypeInternal():_ref_mtime(0) { }
92 int getNumberOfEntries() const;
93 const char *getKeyOfEntry(int i) const;
94 bool getStatusOfEntryStr(const char *entry) const;
95 void setStatusOfEntryStr(const char *entry, bool status) const;
96 void feedSIL(vtkMutableDirectedGraph *sil) const;
97 std::vector<int> getIdsToKeep() const;
98 void printMySelf(std::ostream& os) const;
99 bool setRefTime(vtkObject *input) const;
101 void loadFrom(const std::map<int,INTERP_KERNEL::NormalizedCellType>& m);
103 const ExtractCellTypeStatus& getEntry(const char *entry) const;
104 bool checkSame(const std::map<int,INTERP_KERNEL::NormalizedCellType>& m) const;
106 std::vector<ExtractCellTypeStatus> _types;
107 mutable unsigned long _ref_mtime;
110 bool vtkExtractCellType::vtkExtractCellTypeInternal::setRefTime(vtkObject *input) const
112 unsigned long mtime(input->GetMTime());
122 std::vector<int> vtkExtractCellType::vtkExtractCellTypeInternal::getIdsToKeep() const
124 std::vector<int> ret;
125 for(std::vector<ExtractCellTypeStatus>::const_iterator it=_types.begin();it!=_types.end();it++)
127 if((*it).getStatus())
128 ret.push_back((*it).getVTKCellType());
133 void vtkExtractCellType::vtkExtractCellTypeInternal::feedSIL(vtkMutableDirectedGraph *sil) const
135 vtkSmartPointer<vtkVariantArray> childEdge(vtkSmartPointer<vtkVariantArray>::New());
136 childEdge->InsertNextValue(0);
137 vtkSmartPointer<vtkVariantArray> crossEdge(vtkSmartPointer<vtkVariantArray>::New());
138 crossEdge->InsertNextValue(1);
139 // CrossEdge is an edge linking hierarchies.
140 vtkUnsignedCharArray* crossEdgesArray=vtkUnsignedCharArray::New();
141 crossEdgesArray->SetName("CrossEdges");
142 sil->GetEdgeData()->AddArray(crossEdgesArray);
143 crossEdgesArray->Delete();
144 std::vector<std::string> names;
145 // Add global fields root
146 vtkIdType root(sil->AddVertex());
147 names.push_back("CellTypesTree");
149 for(std::vector<ExtractCellTypeStatus>::const_iterator it=_types.begin();it!=_types.end();it++)
151 (*it).feedSIL(sil,root,childEdge,names);
153 // This array is used to assign names to nodes.
154 vtkStringArray *namesArray(vtkStringArray::New());
155 namesArray->SetName("Names");
156 namesArray->SetNumberOfTuples(sil->GetNumberOfVertices());
157 sil->GetVertexData()->AddArray(namesArray);
158 namesArray->Delete();
159 std::vector<std::string>::const_iterator iter;
161 for(cc=0, iter=names.begin(); iter!=names.end(); ++iter, ++cc)
162 namesArray->SetValue(cc,(*iter).c_str());
165 void vtkExtractCellType::vtkExtractCellTypeInternal::loadFrom(const std::map<int,INTERP_KERNEL::NormalizedCellType>& m)
170 std::size_t sz(m.size()),ii(0);
172 for(std::map<int,INTERP_KERNEL::NormalizedCellType>::const_iterator it=m.begin();it!=m.end();it++,ii++)
174 ExtractCellTypeStatus elt((*it).first,(*it).second);
179 int vtkExtractCellType::vtkExtractCellTypeInternal::getNumberOfEntries() const
181 return (int) _types.size();
184 const char *vtkExtractCellType::vtkExtractCellTypeInternal::getKeyOfEntry(int i) const
186 return _types[i].getKeyOfEntry();
189 bool vtkExtractCellType::vtkExtractCellTypeInternal::checkSame(const std::map<int,INTERP_KERNEL::NormalizedCellType>& m) const
191 std::size_t sz(m.size());
192 if(sz!=_types.size())
195 std::map<int,INTERP_KERNEL::NormalizedCellType>::const_iterator it(m.begin());
196 for(std::size_t i=0;i<sz && ret;i++,it++)
197 ret=_types[i].isSame((*it).first,(*it).second);
201 const ExtractCellTypeStatus& vtkExtractCellType::vtkExtractCellTypeInternal::getEntry(const char *entry) const
203 std::string entryCpp(entry);
204 for(std::vector<ExtractCellTypeStatus>::const_iterator it0=_types.begin();it0!=_types.end();it0++)
205 if(entryCpp==(*it0).getKey())
207 std::ostringstream oss; oss << "vtkExtractCellTypeInternal::getEntry : no such entry \"" << entry << "\"!";
208 throw INTERP_KERNEL::Exception(oss.str().c_str());
211 bool vtkExtractCellType::vtkExtractCellTypeInternal::getStatusOfEntryStr(const char *entry) const
215 const ExtractCellTypeStatus& elt(getEntry(entry));
216 return elt.getStatus();
218 catch (INTERP_KERNEL::Exception e)
220 //std::cerr << vtkDebugMacro"Exception has been thrown in vtkExtractCellType::vtkExtractCellTypeInternal::getStatusOfEntryStr : " << e.what() << std::endl;
225 void vtkExtractCellType::vtkExtractCellTypeInternal::setStatusOfEntryStr(const char *entry, bool status) const
229 const ExtractCellTypeStatus& elt(getEntry(entry));
230 elt.setStatus(status);
232 catch (INTERP_KERNEL::Exception e)
234 //std::cerr << "Exception has been thrown in vtkExtractCellType::vtkExtractCellTypeInternal::setStatusOfEntryStr : " << e.what() << std::endl;
238 void vtkExtractCellType::vtkExtractCellTypeInternal::printMySelf(std::ostream& os) const
240 for(std::vector<ExtractCellTypeStatus>::const_iterator it0=_types.begin();it0!=_types.end();it0++)
241 (*it0).printMySelf(os);
244 ExtractCellTypeStatus::ExtractCellTypeStatus(int vtkt, INTERP_KERNEL::NormalizedCellType mct):_status(false),_vtkt(vtkt),_mct(mct)
246 std::string name(INTERP_KERNEL::CellModel::GetCellModel(mct).getRepr());
247 _type_str=name.substr(5);//skip "NORM_"
250 void ExtractCellTypeStatus::printMySelf(std::ostream& os) const
252 os << " -" << _type_str << "(";
257 os << ")" << std::endl;
260 bool ExtractCellTypeStatus::isSameAs(const ExtractCellTypeStatus& other) const
262 return _vtkt==other._vtkt && _mct==other._mct;
265 void ExtractCellTypeStatus::feedSIL(vtkMutableDirectedGraph *sil, vtkIdType root, vtkVariantArray *childEdge, std::vector<std::string>& names) const
267 vtkIdType InfoGeoType(sil->AddChild(root,childEdge));
268 names.push_back(_type_str);
269 vtkIdType InfoVTKID(sil->AddChild(InfoGeoType,childEdge));
270 std::ostringstream oss; oss << _vtkt;
271 names.push_back(oss.str());
276 vtkExtractCellType::vtkExtractCellType():SIL(NULL),Internal(new vtkExtractCellTypeInternal),InsideOut(0)
280 vtkExtractCellType::~vtkExtractCellType()
284 delete this->Internal;
287 void vtkExtractCellType::SetInsideOut(int val)
289 if(this->InsideOut!=val)
296 int vtkExtractCellType::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
300 //std::cerr << "########################################## vtkExtractCellType::RequestInformation ##########################################" << std::endl;
301 vtkInformation *outInfo(outputVector->GetInformationObject(0));
302 vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
303 vtkDataSet *input(0);
305 vtkDataObject *inp(inputInfo->Get(vtkDataObject::DATA_OBJECT()));
306 if(vtkDataSet::SafeDownCast(inp))
307 input=vtkDataSet::SafeDownCast(inp);
310 vtkMultiBlockDataSet *inputTmp(vtkMultiBlockDataSet::SafeDownCast(inp));
313 if(inputTmp->GetNumberOfBlocks()!=1)
315 vtkDebugMacro("vtkExtractCellType::RequestInformation : input vtkMultiBlockDataSet must contain exactly 1 block !");
318 vtkDataSet *blk0(vtkDataSet::SafeDownCast(inputTmp->GetBlock(0)));
321 vtkDebugMacro("vtkExtractCellType::RequestInformation : the single block in input vtkMultiBlockDataSet must be a vtkDataSet instance !");
328 vtkDebugMacro("vtkExtractCellType::RequestInformation : supported input are vtkDataSet or vtkMultiBlockDataSet !");
333 if(this->Internal->setRefTime(input))
335 vtkIdType nbOfCells(input->GetNumberOfCells());
336 std::map<int,INTERP_KERNEL::NormalizedCellType> m;
337 for(vtkIdType cellId=0;cellId<nbOfCells;cellId++)
339 int vtkCt(input->GetCellType(cellId));
340 const std::map<int,INTERP_KERNEL::NormalizedCellType>::const_iterator it(m.find(vtkCt));
343 const unsigned char *pos(std::find(ParaMEDMEM::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,ParaMEDMEM::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+ParaMEDMEM::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH,vtkCt));
344 if(pos==ParaMEDMEM::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+ParaMEDMEM::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH)
346 vtkDebugMacro("vtkExtractCellType::RequestInformation : cell #" << cellId << " has unrecognized type !");
349 m[vtkCt]=(INTERP_KERNEL::NormalizedCellType)std::distance(ParaMEDMEM::MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,pos);
352 this->Internal->loadFrom(m);
355 this->SIL=vtkMutableDirectedGraph::New();
356 this->Internal->feedSIL(this->SIL);
358 outInfo->Set(vtkDataObject::SIL(),this->SIL);
361 catch(INTERP_KERNEL::Exception& e)
363 std::cerr << "Exception has been thrown in vtkExtractCellType::RequestInformation : " << e.what() << std::endl;
369 vtkDataSet *FilterFamilies(vtkDataSet *input, const std::vector<int>& idsToKeep, bool insideOut)
371 const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
372 const char ZE_SELECTION_ARR_NAME[]="@@ZeSelection@@";
373 vtkDataSet *output(input->NewInstance());
374 output->ShallowCopy(input);
375 vtkSmartPointer<vtkThreshold> thres(vtkSmartPointer<vtkThreshold>::New());
376 thres->SetInputData(output);
377 vtkDataSetAttributes *dscIn(input->GetCellData()),*dscIn2(input->GetPointData());
378 vtkDataSetAttributes *dscOut(output->GetCellData()),*dscOut2(output->GetPointData());
380 double vMin(insideOut==0?1.:0.),vMax(insideOut==0?2.:1.);
381 thres->ThresholdBetween(vMin,vMax);
383 vtkIdType nbOfCells(input->GetNumberOfCells());
384 vtkCharArray *zeSelection(vtkCharArray::New());
385 zeSelection->SetName(ZE_SELECTION_ARR_NAME);
386 zeSelection->SetNumberOfComponents(1);
387 char *pt(new char[nbOfCells]);
388 zeSelection->SetArray(pt,nbOfCells,0,VTK_DATA_ARRAY_DELETE);
389 std::fill(pt,pt+nbOfCells,0);
390 std::vector<bool> pt2(nbOfCells,false);
391 for(std::vector<int>::const_iterator it=idsToKeep.begin();it!=idsToKeep.end();it++)
393 for(vtkIdType ii=0;ii<nbOfCells;ii++)
395 if(input->GetCellType(ii)==*it)
399 for(int ii=0;ii<nbOfCells;ii++)
402 int idx(output->GetCellData()->AddArray(zeSelection));
403 output->GetCellData()->SetActiveAttribute(idx,vtkDataSetAttributes::SCALARS);
404 output->GetCellData()->CopyScalarsOff();
405 zeSelection->Delete();
407 thres->SetInputArrayToProcess(idx,0,0,"vtkDataObject::FIELD_ASSOCIATION_CELLS",ZE_SELECTION_ARR_NAME);
409 vtkUnstructuredGrid *zeComputedOutput(thres->GetOutput());
410 zeComputedOutput->GetCellData()->RemoveArray(idx);
412 zeComputedOutput->Register(0);
413 return zeComputedOutput;
416 int vtkExtractCellType::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
420 //std::cerr << "########################################## vtkExtractCellType::RequestData ##########################################" << std::endl;
421 vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
422 vtkDataSet *input(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
423 vtkInformation *info(input->GetInformation());
424 vtkInformation *outInfo(outputVector->GetInformationObject(0));
425 vtkDataSet *output(vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
426 std::vector<int> idsToKeep(this->Internal->getIdsToKeep());
427 vtkDataSet *tryOnCell(FilterFamilies(input,idsToKeep,this->InsideOut));
428 // first shrink the input
429 output->ShallowCopy(tryOnCell);
432 catch(INTERP_KERNEL::Exception& e)
434 std::cerr << "Exception has been thrown in vtkExtractCellType::RequestData : " << e.what() << std::endl;
440 int vtkExtractCellType::GetSILUpdateStamp()
442 return this->SILTime;
445 void vtkExtractCellType::PrintSelf(ostream& os, vtkIndent indent)
447 this->Superclass::PrintSelf(os, indent);
450 int vtkExtractCellType::GetNumberOfGeoTypesArrays()
452 int ret(this->Internal->getNumberOfEntries());
453 //std::cerr << "vtkExtractCellType::GetNumberOfGeoTypesArrays() -> " << ret << std::endl;
457 const char *vtkExtractCellType::GetGeoTypesArrayName(int index)
459 const char *ret(this->Internal->getKeyOfEntry(index));
460 //std::cerr << "vtkExtractCellType::GetGeoTypesArrayName(" << index << ") -> " << ret << std::endl;
464 int vtkExtractCellType::GetGeoTypesArrayStatus(const char *name)
466 int ret((int)this->Internal->getStatusOfEntryStr(name));
467 //std::cerr << "vtkExtractCellType::GetGeoTypesArrayStatus(" << name << ") -> " << ret << std::endl;
471 void vtkExtractCellType::SetGeoTypesStatus(const char *name, int status)
473 //std::cerr << "vtkExtractCellType::SetGeoTypesStatus(" << name << "," << status << ")" << std::endl;
474 if (GetNumberOfGeoTypesArrays()<1)
476 this->Internal->setStatusOfEntryStr(name,(bool)status);
477 if(std::string(name)==GetGeoTypesArrayName(GetNumberOfGeoTypesArrays()-1))
480 //this->Internal->printMySelf(std::cerr);