Salome HOME
For MEDReader in // mode : the ghost cell generator is invoked by default
[modules/paravis.git] / src / Plugins / MEDReader / IO / vtkExtractGroup.cxx
1 // Copyright (C) 2010-2016  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay
20
21 #include "vtkExtractGroup.h"
22 #include "MEDFileFieldRepresentationTree.hxx"
23 #include "vtkMEDReader.h"
24
25 #include "vtkAdjacentVertexIterator.h"
26 #include "vtkDataArrayTemplate.h"
27 #include "vtkIntArray.h"
28 #include "vtkCellData.h"
29 #include "vtkPointData.h"
30
31 #include "vtkStreamingDemandDrivenPipeline.h"
32 #include "vtkUnstructuredGrid.h"
33 #include  "vtkMultiBlockDataSet.h"
34
35 #include "vtkInformationStringKey.h"
36 #include "vtkAlgorithmOutput.h"
37 #include "vtkObjectFactory.h"
38 #include "vtkMutableDirectedGraph.h"
39 #include "vtkMultiBlockDataSet.h"
40 #include "vtkDataSet.h"
41 #include "vtkInformationVector.h"
42 #include "vtkInformation.h"
43 #include "vtkDataArraySelection.h"
44 #include "vtkTimeStamp.h"
45 #include "vtkInEdgeIterator.h"
46 #include "vtkInformationDataObjectKey.h"
47 #include "vtkExecutive.h"
48 #include "vtkVariantArray.h"
49 #include "vtkStringArray.h"
50 #include "vtkDoubleArray.h"
51 #include "vtkCharArray.h"
52 #include "vtkUnsignedCharArray.h"
53 #include "vtkDataSetAttributes.h"
54 #include "vtkDemandDrivenPipeline.h"
55 #include "vtkDataObjectTreeIterator.h"
56 #include "vtkThreshold.h"
57 #include "vtkMultiBlockDataGroupFilter.h"
58 #include "vtkCompositeDataToUnstructuredGridFilter.h"
59 #include "vtkInformationDataObjectMetaDataKey.h"
60
61 #include <map>
62 #include <deque>
63
64 vtkStandardNewMacro(vtkExtractGroup);
65
66 ///////////////////
67
68 class ExtractGroupStatus
69 {
70 public:
71   ExtractGroupStatus():_status(false) { }
72   ExtractGroupStatus(const char *name);
73   bool getStatus() const { return _status; }
74   void setStatus(bool status) { _status=status; }
75   void cpyStatusFrom(const ExtractGroupStatus& other) { _status=other._status; }
76   std::string getName() const { return _name; }
77   const char *getKeyOfEntry() const { return _ze_key_name.c_str(); }
78   virtual void printMySelf(std::ostream& os) const;
79   virtual bool isSameAs(const ExtractGroupStatus& other) const;
80 protected:
81 bool _status;
82 std::string _name;
83 std::string _ze_key_name;
84 };
85
86 class ExtractGroupGrp : public ExtractGroupStatus
87 {
88 public:
89   ExtractGroupGrp(const char *name):ExtractGroupStatus(name) { std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); }
90   void setFamilies(const std::vector<std::string>& fams) { _fams=fams; }
91   const std::vector<std::string>& getFamiliesLyingOn() const { return _fams; }
92   bool isSameAs(const ExtractGroupGrp& other) const;
93 public:
94   static const char START[];
95   std::vector<std::string> _fams;
96 };
97
98 class ExtractGroupFam : public ExtractGroupStatus
99 {
100 public:
101   ExtractGroupFam(const char *name);
102   void printMySelf(std::ostream& os) const;
103   void fillIdsToKeep(std::set<int>& s) const;
104   int getId() const { return _id; }
105   bool isSameAs(const ExtractGroupFam& other) const;
106 public:
107   static const char START[];
108 private:
109   int _id;
110 };
111
112 class vtkExtractGroup::vtkExtractGroupInternal
113 {
114 public:
115   void loadFrom(vtkMutableDirectedGraph *sil);
116   int getNumberOfEntries() const;
117   const char *getMeshName() const;
118   const char *getKeyOfEntry(int i) const;
119   bool getStatusOfEntryStr(const char *entry) const;
120   void setStatusOfEntryStr(const char *entry, bool status);
121   void printMySelf(std::ostream& os) const;
122   std::set<int> getIdsToKeep() const;
123   int getIdOfFamily(const std::string& famName) const;
124   static bool IsInformationOK(vtkInformation *info);
125 private:
126   std::map<std::string,int> computeFamStrIdMap() const;
127   const ExtractGroupStatus& getEntry(const char *entry) const;
128   ExtractGroupStatus& getEntry(const char *entry);
129 private:
130   std::vector<ExtractGroupGrp> _groups;
131   std::vector<ExtractGroupFam> _fams;
132   std::string _mesh_name;
133 };
134
135 const char ExtractGroupGrp::START[]="GRP_";
136
137 const char ExtractGroupFam::START[]="FAM_";
138
139 ExtractGroupStatus::ExtractGroupStatus(const char *name):_status(false),_name(name)
140 {
141 }
142
143 void ExtractGroupStatus::printMySelf(std::ostream& os) const
144 {
145   os << "      -" << _ze_key_name << "(";
146   if(_status)
147     os << "X";
148   else
149     os << " ";
150   os << ")" << std::endl;
151 }
152
153 bool ExtractGroupStatus::isSameAs(const ExtractGroupStatus& other) const
154 {
155   return _name==other._name && _ze_key_name==other._ze_key_name;
156 }
157
158 bool ExtractGroupGrp::isSameAs(const ExtractGroupGrp& other) const
159 {
160   bool ret(ExtractGroupStatus::isSameAs(other));
161   if(ret)
162     return _fams==other._fams;
163   else
164     return false;
165 }
166
167 bool vtkExtractGroup::vtkExtractGroupInternal::IsInformationOK(vtkInformation *info)
168 {
169   // Check the information contain meta data key
170   if(!info->Has(vtkMEDReader::META_DATA()))
171     return false;
172
173   // Recover Meta Data
174   vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(vtkMEDReader::META_DATA())));
175   if(!sil)
176     return false;
177   int idNames(0);
178   vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
179   vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
180   if(!verticesNames2)
181     return false;
182   for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
183     {
184       vtkStdString &st(verticesNames2->GetValue(i));
185       if(st=="MeshesFamsGrps")
186         return true;
187     }
188   return false;
189 }
190
191 const char* vtkExtractGroup::GetGrpStart()
192 {
193   return ExtractGroupGrp::START;
194 }
195
196 const char* vtkExtractGroup::GetFamStart()
197 {
198   return ExtractGroupFam::START;
199 }
200
201 const char *vtkExtractGroup::vtkExtractGroupInternal::getMeshName() const
202 {
203   return this->_mesh_name.c_str();
204 }
205
206 void vtkExtractGroup::vtkExtractGroupInternal::loadFrom(vtkMutableDirectedGraph *sil)
207 {
208   std::vector<ExtractGroupGrp> oldGrps(_groups); _groups.clear();
209   std::vector<ExtractGroupFam> oldFams(_fams); _fams.clear();
210   int idNames(0);
211   vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
212   vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
213   vtkIdType id0;
214   bool found(false);
215   for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
216     {
217       vtkStdString &st(verticesNames2->GetValue(i));
218       if(st=="MeshesFamsGrps")
219         {
220           id0=i;
221           found=true;
222         }
223     }
224   if(!found)
225     throw INTERP_KERNEL::Exception("There is an internal error ! The tree on server side has not the expected look !");
226   vtkAdjacentVertexIterator *it0(vtkAdjacentVertexIterator::New());
227   sil->GetAdjacentVertices(id0,it0);
228   int kk(0),ll(0);
229   while(it0->HasNext())
230     {
231       vtkIdType id1(it0->Next());
232       std::string meshName((const char *)verticesNames2->GetValue(id1));
233       this->_mesh_name=meshName;
234       vtkAdjacentVertexIterator *it1(vtkAdjacentVertexIterator::New());
235       sil->GetAdjacentVertices(id1,it1);
236       vtkIdType idZeGrps(it1->Next());//zeGroups
237       vtkAdjacentVertexIterator *itGrps(vtkAdjacentVertexIterator::New());
238       sil->GetAdjacentVertices(idZeGrps,itGrps);
239       while(itGrps->HasNext())
240         {
241           vtkIdType idg(itGrps->Next());
242           ExtractGroupGrp grp((const char *)verticesNames2->GetValue(idg));
243           vtkAdjacentVertexIterator *itGrps2(vtkAdjacentVertexIterator::New());
244           sil->GetAdjacentVertices(idg,itGrps2);
245           std::vector<std::string> famsOnGroup;
246           while(itGrps2->HasNext())
247             {
248               vtkIdType idgf(itGrps2->Next());
249               famsOnGroup.push_back(std::string((const char *)verticesNames2->GetValue(idgf)));
250             }
251           grp.setFamilies(famsOnGroup);
252           itGrps2->Delete();
253           _groups.push_back(grp);
254         }
255       itGrps->Delete();
256       vtkIdType idZeFams(it1->Next());//zeFams
257       it1->Delete();
258       vtkAdjacentVertexIterator *itFams(vtkAdjacentVertexIterator::New());
259       sil->GetAdjacentVertices(idZeFams,itFams);
260       while(itFams->HasNext())
261         {
262           vtkIdType idf(itFams->Next());
263           ExtractGroupFam fam((const char *)verticesNames2->GetValue(idf));
264           _fams.push_back(fam);
265         }
266       itFams->Delete();
267     }
268   it0->Delete();
269   //
270   std::size_t szg(_groups.size()),szf(_fams.size());
271   if(szg==oldGrps.size() && szf==oldFams.size())
272     {
273       bool isSame(true);
274       for(std::size_t i=0;i<szg && isSame;i++)
275         isSame=_groups[i].isSameAs(oldGrps[i]);
276       for(std::size_t i=0;i<szf && isSame;i++)
277         isSame=_fams[i].isSameAs(oldFams[i]);
278       if(isSame)
279         {
280           for(std::size_t i=0;i<szg;i++)
281             _groups[i].cpyStatusFrom(oldGrps[i]);
282           for(std::size_t i=0;i<szf;i++)
283             _fams[i].cpyStatusFrom(oldFams[i]);
284         }
285     }
286 }
287
288 int vtkExtractGroup::vtkExtractGroupInternal::getNumberOfEntries() const
289 {
290   std::size_t sz0(_groups.size()),sz1(_fams.size());
291   return (int)(sz0+sz1);
292 }
293
294 const char *vtkExtractGroup::vtkExtractGroupInternal::getKeyOfEntry(int i) const
295 {
296   int sz0((int)_groups.size());
297   if(i>=0 && i<sz0)
298     return _groups[i].getKeyOfEntry();
299   else
300     return _fams[i-sz0].getKeyOfEntry();
301 }
302
303 bool vtkExtractGroup::vtkExtractGroupInternal::getStatusOfEntryStr(const char *entry) const
304 {
305   const ExtractGroupStatus& elt(getEntry(entry));
306   return elt.getStatus();
307 }
308
309 void vtkExtractGroup::vtkExtractGroupInternal::setStatusOfEntryStr(const char *entry, bool status)
310 {
311   ExtractGroupStatus& elt(getEntry(entry));
312   elt.setStatus(status);
313 }
314
315 const ExtractGroupStatus& vtkExtractGroup::vtkExtractGroupInternal::getEntry(const char *entry) const
316 {
317   std::string entryCpp(entry);
318   for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
319     if(entryCpp==(*it0).getKeyOfEntry())
320       return *it0;
321   for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
322     if(entryCpp==(*it0).getKeyOfEntry())
323       return *it0;
324   std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
325   throw INTERP_KERNEL::Exception(oss.str().c_str());
326 }
327
328 ExtractGroupStatus& vtkExtractGroup::vtkExtractGroupInternal::getEntry(const char *entry)
329 {
330   std::string entryCpp(entry);
331   for(std::vector<ExtractGroupGrp>::iterator it0=_groups.begin();it0!=_groups.end();it0++)
332     if(entryCpp==(*it0).getKeyOfEntry())
333       return *it0;
334   for(std::vector<ExtractGroupFam>::iterator it0=_fams.begin();it0!=_fams.end();it0++)
335     if(entryCpp==(*it0).getKeyOfEntry())
336       return *it0;
337   std::ostringstream oss; oss << "vtkExtractGroupInternal::getEntry : no such entry \"" << entry << "\"!";
338   throw INTERP_KERNEL::Exception(oss.str().c_str());
339 }
340
341 void vtkExtractGroup::vtkExtractGroupInternal::printMySelf(std::ostream& os) const
342 {
343   os << "Groups :" << std::endl;
344   for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
345     (*it0).printMySelf(os);
346   os << "Families :" << std::endl;
347   for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
348     (*it0).printMySelf(os);
349 }
350
351 int vtkExtractGroup::vtkExtractGroupInternal::getIdOfFamily(const std::string& famName) const
352 {
353   for(std::vector<ExtractGroupFam>::const_iterator it=_fams.begin();it!=_fams.end();it++)
354     {
355       if((*it).getName()==famName)
356         return (*it).getId();
357     }
358 }
359
360 ExtractGroupFam::ExtractGroupFam(const char *name):ExtractGroupStatus(name),_id(0)
361 {
362   std::size_t pos(_name.find(MEDFileFieldRepresentationLeavesArrays::ZE_SEP));
363   std::string name0(_name.substr(0,pos)),name1(_name.substr(pos+strlen(MEDFileFieldRepresentationLeavesArrays::ZE_SEP)));
364   std::istringstream iss(name1);
365   iss >> _id;
366   std::ostringstream oss; oss << START << name; _ze_key_name=oss.str(); _name=name0;
367 }
368
369 bool ExtractGroupFam::isSameAs(const ExtractGroupFam& other) const
370 {
371   bool ret(ExtractGroupStatus::isSameAs(other));
372   if(ret)
373     return _id==other._id;
374   else
375     return false;
376 }
377
378 void ExtractGroupFam::printMySelf(std::ostream& os) const
379 {
380   os << "      -" << _ze_key_name << " famName : \"" << _name << "\" id : " << _id << " (";
381   if(_status)
382     os << "X";
383   else
384     os << " ";
385   os << ")" << std::endl;
386 }
387
388 void ExtractGroupFam::fillIdsToKeep(std::set<int>& s) const
389 {
390   s.insert(_id);
391 }
392
393 std::set<int> vtkExtractGroup::vtkExtractGroupInternal::getIdsToKeep() const
394 {
395   std::map<std::string,int> m(this->computeFamStrIdMap());
396   std::set<int> s;
397   for(std::vector<ExtractGroupGrp>::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
398     {
399       if((*it0).getStatus())
400         {
401           const std::vector<std::string>& fams((*it0).getFamiliesLyingOn());
402           for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
403             {
404               std::map<std::string,int>::iterator it2(m.find((*it1)));
405               if(it2!=m.end())
406                 s.insert((*it2).second);
407             }
408         }
409      }
410   for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
411     if((*it0).getStatus())
412       (*it0).fillIdsToKeep(s);
413   return s;
414 }
415
416 std::map<std::string,int> vtkExtractGroup::vtkExtractGroupInternal::computeFamStrIdMap() const
417 {
418   std::map<std::string,int> ret;
419   for(std::vector<ExtractGroupFam>::const_iterator it0=_fams.begin();it0!=_fams.end();it0++)
420     ret[(*it0).getName()]=(*it0).getId();
421   return ret;
422 }
423
424 ////////////////////
425
426 vtkExtractGroup::vtkExtractGroup():SIL(NULL),Internal(new vtkExtractGroupInternal),InsideOut(0)
427 {
428 }
429
430 vtkExtractGroup::~vtkExtractGroup()
431 {
432   delete this->Internal;
433 }
434
435 void vtkExtractGroup::SetInsideOut(int val)
436 {
437   if(this->InsideOut!=val)
438     {
439       this->InsideOut=val;
440       this->Modified();
441     }
442 }
443
444 int vtkExtractGroup::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
445 {
446 //  vtkUnstructuredGridAlgorithm::RequestInformation(request,inputVector,outputVector);
447   try
448     {
449 //      std::cerr << "########################################## vtkExtractGroup::RequestInformation ##########################################" << std::endl;
450 //      request->Print(cout);
451       vtkInformation *outInfo(outputVector->GetInformationObject(0));
452       vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
453       if(!vtkExtractGroup::vtkExtractGroupInternal::IsInformationOK(inputInfo))
454         {
455         vtkErrorMacro("No SIL Data available ! The source of this filter must be MEDReader !");
456         return 0;
457         }
458
459       this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(vtkMEDReader::META_DATA())));
460       this->Internal->loadFrom(this->SIL);
461       //this->Internal->printMySelf(std::cerr);
462     }
463   catch(INTERP_KERNEL::Exception& e)
464     {
465       std::cerr << "Exception has been thrown in vtkExtractGroup::RequestInformation : " << e.what() << std::endl;
466       return 0;
467     }
468   return 1;
469 }
470
471 /*!
472  * Do not use vtkCxxSetObjectMacro macro because input mdg comes from an already managed in the pipeline just a ref on it.
473  */
474 void vtkExtractGroup::SetSIL(vtkMutableDirectedGraph *mdg)
475 {
476   if(this->SIL==mdg)
477     return ;
478   this->SIL=mdg;
479 }
480
481 template<class CellPointExtractor>
482 vtkDataSet *FilterFamilies(vtkSmartPointer<vtkThreshold>& thres,
483                            vtkDataSet *input, const std::set<int>& idsToKeep, bool insideOut, const char *arrNameOfFamilyField,
484                            const char *associationForThreshold, bool& catchAll, bool& catchSmth)
485 {
486   const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
487   const char ZE_SELECTION_ARR_NAME[]="@@ZeSelection@@";
488   vtkDataSet *output(input->NewInstance());
489   output->ShallowCopy(input);
490   thres->SetInputData(output);
491   vtkDataSetAttributes *dscIn(input->GetCellData()),*dscIn2(input->GetPointData());
492   vtkDataSetAttributes *dscOut(output->GetCellData()),*dscOut2(output->GetPointData());
493   //
494   double vMin(insideOut==0?1.:0.),vMax(insideOut==0?2.:1.);
495   thres->ThresholdBetween(vMin,vMax);
496   // OK for the output
497   //
498   CellPointExtractor cpe2(input);
499   vtkDataArray *da(cpe2.Get()->GetScalars(arrNameOfFamilyField));
500   if(!da)
501     return 0;
502   std::string daName(da->GetName());
503   vtkIntArray *dai(vtkIntArray::SafeDownCast(da));
504   if(daName!=arrNameOfFamilyField || !dai)
505     return 0;
506   //
507   int nbOfTuples(dai->GetNumberOfTuples());
508   vtkCharArray *zeSelection(vtkCharArray::New());
509   zeSelection->SetName(ZE_SELECTION_ARR_NAME);
510   zeSelection->SetNumberOfComponents(1);
511   char *pt(new char[nbOfTuples]);
512   zeSelection->SetArray(pt,nbOfTuples,0,VTK_DATA_ARRAY_DELETE);
513   const int *inPtr(dai->GetPointer(0));
514   std::fill(pt,pt+nbOfTuples,0);
515   catchAll=true; catchSmth=false;
516   std::vector<bool> pt2(nbOfTuples,false);
517   for(std::set<int>::const_iterator it=idsToKeep.begin();it!=idsToKeep.end();it++)
518     {
519       bool catchFid(false);
520       for(int i=0;i<nbOfTuples;i++)
521         if(inPtr[i]==*it)
522           { pt2[i]=true; catchFid=true; }
523       if(!catchFid)
524         catchAll=false;
525       else
526         catchSmth=true;
527     }
528   for(int ii=0;ii<nbOfTuples;ii++)
529     if(pt2[ii])
530       pt[ii]=2;
531   CellPointExtractor cpe3(output);
532   int idx(cpe3.Get()->AddArray(zeSelection));
533   cpe3.Get()->SetActiveAttribute(idx,vtkDataSetAttributes::SCALARS);
534   cpe3.Get()->CopyScalarsOff();
535   zeSelection->Delete();
536   //
537   thres->SetInputArrayToProcess(idx,0,0,associationForThreshold,ZE_SELECTION_ARR_NAME);
538   thres->Update();
539   vtkUnstructuredGrid *zeComputedOutput(thres->GetOutput());
540   CellPointExtractor cpe(zeComputedOutput);
541   cpe.Get()->RemoveArray(idx);
542   output->Delete();
543   zeComputedOutput->Register(0);
544   return zeComputedOutput;
545 }
546
547 class CellExtractor
548 {
549 public:
550   CellExtractor(vtkDataSet *ds):_ds(ds) { }
551   vtkDataSetAttributes *Get() { return _ds->GetCellData(); }
552 private:
553   vtkDataSet *_ds;
554 };
555
556 class PointExtractor
557 {
558 public:
559   PointExtractor(vtkDataSet *ds):_ds(ds) { }
560   vtkDataSetAttributes *Get() { return _ds->GetPointData(); }
561 private:
562   vtkDataSet *_ds;
563 };
564
565 int vtkExtractGroup::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
566 {
567   try
568     {
569 //      std::cerr << "########################################## vtkExtractGroup::RequestData        ##########################################" << std::endl;
570 //      request->Print(cout);
571       vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
572       vtkMultiBlockDataSet *inputMB(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
573       if(inputMB->GetNumberOfBlocks()!=1)
574         {
575           std::ostringstream oss; oss << "vtkExtractGroup::RequestData : input has not the right number of parts ! Expected 1 !";
576           if(this->HasObserver("ErrorEvent") )
577             this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
578           else
579             vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
580           vtkObject::BreakOnError();
581           return 0;
582         }
583       vtkDataSet *input(vtkDataSet::SafeDownCast(inputMB->GetBlock(0)));
584       vtkInformation *info(input->GetInformation());
585       vtkInformation *outInfo(outputVector->GetInformationObject(0));
586       vtkMultiBlockDataSet *output(vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
587       std::set<int> idsToKeep(this->Internal->getIdsToKeep());
588       // first shrink the input
589       bool catchAll,catchSmth;
590       vtkSmartPointer<vtkThreshold> thres1(vtkSmartPointer<vtkThreshold>::New()),thres2(vtkSmartPointer<vtkThreshold>::New());
591       vtkDataSet *tryOnCell(FilterFamilies<CellExtractor>(thres1,input,idsToKeep,this->InsideOut,
592                                                           MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME,"vtkDataObject::FIELD_ASSOCIATION_CELLS",catchAll,catchSmth));
593       if(tryOnCell)
594         {
595           if(catchAll)
596             {
597               output->SetBlock(0,tryOnCell);
598               tryOnCell->Delete();//
599               return 1;
600             }
601           else
602             {
603               if(catchSmth)
604                 {
605                   vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres2,input,idsToKeep,this->InsideOut,
606                                                                        MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
607                   if(tryOnNode && catchSmth)
608                     {
609                       output->SetBlock(0,tryOnCell);
610                       output->SetBlock(1,tryOnNode);
611                       tryOnCell->Delete();
612                       tryOnNode->Delete();
613                       return 1;
614                     }
615                   else
616                     {
617                       if(tryOnNode)
618                         tryOnNode->Delete();
619                       output->SetBlock(0,tryOnCell);
620                       tryOnCell->Delete();
621                       return 1;
622                     }
623                 }
624               else
625                 {
626                   vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
627                                                                        MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
628                   if(tryOnNode)
629                     {
630                       tryOnCell->Delete();
631                       output->SetBlock(0,tryOnNode);
632                       tryOnNode->Delete();
633                       return 1;
634                     }
635                   else
636                     {
637                       output->SetBlock(0,tryOnNode);
638                       tryOnCell->Delete();
639                       return 0;
640                     }
641                 }
642             }
643         }
644       else
645         {
646           vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
647                                                                MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
648           if(tryOnNode)
649             {
650               output->ShallowCopy(tryOnNode);
651               tryOnNode->Delete();//
652               return 1;
653             }
654           else
655             {
656               std::ostringstream oss; oss << "vtkExtractGroup::RequestData : The integer array with name \""<< MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME;
657               oss << "\" or \"" << MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME << "\" does not exist ! The extraction of group and/or family is not possible !";
658               if(this->HasObserver("ErrorEvent") )
659                 this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
660               else
661                 vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
662               vtkObject::BreakOnError();
663               return 0;
664             }
665         }
666     }
667   catch(INTERP_KERNEL::Exception& e)
668     {
669       std::cerr << "Exception has been thrown in vtkExtractGroup::RequestData : " << e.what() << std::endl;
670       return 0;
671     }
672 }
673
674 int vtkExtractGroup::GetSILUpdateStamp()
675 {
676   return this->SILTime;
677 }
678
679 void vtkExtractGroup::PrintSelf(ostream& os, vtkIndent indent)
680 {
681   this->Superclass::PrintSelf(os, indent);
682 }
683
684 int vtkExtractGroup::GetNumberOfGroupsFlagsArrays()
685 {
686   int ret(this->Internal->getNumberOfEntries());
687   //std::cerr << "vtkExtractGroup::GetNumberOfFieldsTreeArrays() -> " << ret << std::endl;
688   return ret;
689 }
690
691 const char *vtkExtractGroup::GetGroupsFlagsArrayName(int index)
692 {
693   const char *ret(this->Internal->getKeyOfEntry(index));
694 //  std::cerr << "vtkExtractGroup::GetFieldsTreeArrayName(" << index << ") -> " << ret << std::endl;
695   return ret;
696 }
697
698 int vtkExtractGroup::GetGroupsFlagsArrayStatus(const char *name)
699 {
700   int ret((int)this->Internal->getStatusOfEntryStr(name));
701 //  std::cerr << "vtkExtractGroup::GetGroupsFlagsArrayStatus(" << name << ") -> " << ret << std::endl;
702   return ret;
703 }
704
705 void vtkExtractGroup::SetGroupsFlagsStatus(const char *name, int status)
706 {
707   //std::cerr << "vtkExtractGroup::SetFieldsStatus(" << name << "," << status << ")" << std::endl;
708   if (GetNumberOfGroupsFlagsArrays()<1)
709     return;
710   this->Internal->setStatusOfEntryStr(name,(bool)status);
711   if(std::string(name)==GetGroupsFlagsArrayName(GetNumberOfGroupsFlagsArrays()-1))
712      this->Modified();
713   //this->Internal->printMySelf(std::cerr);
714 }
715
716 const char *vtkExtractGroup::GetMeshName()
717 {
718   return this->Internal->getMeshName();
719 }