Salome HOME
[EDF26799] : Addition of GetRidOffDebugArrays property to remove numbering output...
[modules/paravis.git] / src / Plugins / MEDReader / plugin / MEDReaderIO / vtkExtractGroup.cxx
1 // Copyright (C) 2010-2022  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 "ExtractGroupHelper.h"
24 #include "vtkMEDReader.h"
25 #include "VTKMEDTraits.hxx"
26
27 #include "vtkAdjacentVertexIterator.h"
28 #include "vtkAOSDataArrayTemplate.h"
29 #include "vtkIntArray.h"
30 #include "vtkLongArray.h"
31 #ifdef WIN32
32 #include "vtkLongLongArray.h"
33 #endif
34 #include "vtkCellData.h"
35 #include "vtkPointData.h"
36
37 #include "vtkStreamingDemandDrivenPipeline.h"
38 #include "vtkUnstructuredGrid.h"
39 #include  "vtkMultiBlockDataSet.h"
40
41 #include "vtkInformationStringKey.h"
42 #include "vtkAlgorithmOutput.h"
43 #include "vtkObjectFactory.h"
44 #include "vtkMutableDirectedGraph.h"
45 #include "vtkMultiBlockDataSet.h"
46 #include "vtkDataSet.h"
47 #include "vtkInformationVector.h"
48 #include "vtkInformation.h"
49 #include "vtkDataArraySelection.h"
50 #include "vtkTimeStamp.h"
51 #include "vtkInEdgeIterator.h"
52 #include "vtkInformationDataObjectKey.h"
53 #include "vtkExecutive.h"
54 #include "vtkVariantArray.h"
55 #include "vtkStringArray.h"
56 #include "vtkDoubleArray.h"
57 #include "vtkCharArray.h"
58 #include "vtkUnsignedCharArray.h"
59 #include "vtkDataSetAttributes.h"
60 #include "vtkDemandDrivenPipeline.h"
61 #include "vtkDataObjectTreeIterator.h"
62 #include "vtkThreshold.h"
63 #include "vtkMultiBlockDataGroupFilter.h"
64 #include "vtkMergeBlocks.h"
65 #include "vtkInformationDataObjectMetaDataKey.h"
66
67 #include <map>
68 #include <deque>
69
70 vtkStandardNewMacro(vtkExtractGroup)
71
72 class vtkExtractGroup::vtkExtractGroupInternal : public ExtractGroupInternal
73 {
74 };
75
76 ////////////////////
77
78 vtkExtractGroup::vtkExtractGroup():SIL(NULL),Internal(new vtkExtractGroupInternal),InsideOut(0)
79 {
80 }
81
82 vtkExtractGroup::~vtkExtractGroup()
83 {
84   delete this->Internal;
85 }
86
87 void vtkExtractGroup::SetInsideOut(int val)
88 {
89   if(this->InsideOut!=val)
90     {
91       this->InsideOut=val;
92       this->Modified();
93     }
94 }
95
96 int vtkExtractGroup::RequestInformation(vtkInformation * /*request*/, vtkInformationVector **inputVector, vtkInformationVector */*outputVector*/)
97 {
98 //  vtkUnstructuredGridAlgorithm::RequestInformation(request,inputVector,outputVector);
99   try
100     {
101 //      std::cerr << "########################################## vtkExtractGroup::RequestInformation ##########################################" << std::endl;
102 //      request->Print(cout);
103       //vtkInformation *outInfo(outputVector->GetInformationObject(0)); // todo: unused
104       vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
105       if(!ExtractGroupInternal::IndependantIsInformationOK(vtkMEDReader::META_DATA(),inputInfo))
106         {
107         vtkErrorMacro("No SIL Data available ! The source of this filter must be MEDReader !");
108         return 0;
109         }
110
111       this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(vtkMEDReader::META_DATA())));
112       this->Internal->loadFrom(this->SIL);
113       //this->Internal->printMySelf(std::cerr);
114     }
115   catch(INTERP_KERNEL::Exception& e)
116     {
117       std::cerr << "Exception has been thrown in vtkExtractGroup::RequestInformation : " << e.what() << std::endl;
118       return 0;
119     }
120   return 1;
121 }
122
123 /*!
124  * Do not use vtkCxxSetObjectMacro macro because input mdg comes from an already managed in the pipeline just a ref on it.
125  */
126 void vtkExtractGroup::SetSIL(vtkMutableDirectedGraph *mdg)
127 {
128   if(this->SIL==mdg)
129     return ;
130   this->SIL=mdg;
131 }
132
133 template<class CellPointExtractor>
134 vtkDataSet *FilterFamilies(vtkSmartPointer<vtkThreshold>& thres,
135                            vtkDataSet *input, const std::set<int>& idsToKeep, bool insideOut, const char *arrNameOfFamilyField,
136                            const char *associationForThreshold, bool& catchAll, bool& catchSmth)
137 {
138   const int VTK_DATA_ARRAY_DELETE=vtkAOSDataArrayTemplate<double>::VTK_DATA_ARRAY_DELETE;
139   const char ZE_SELECTION_ARR_NAME[]="@@ZeSelection@@";
140   vtkDataSet *output(input->NewInstance());
141   output->ShallowCopy(input);
142   thres->SetInputData(output);
143   //vtkDataSetAttributes *dscIn(input->GetCellData()),*dscIn2(input->GetPointData()); // todo: unused
144   //vtkDataSetAttributes *dscOut(output->GetCellData()),*dscOut2(output->GetPointData()); // todo: unused
145   //
146   double vMin(insideOut==0?1.:0.),vMax(insideOut==0?2.:1.);
147   thres->SetUpperThreshold(vMax);
148   thres->SetLowerThreshold(vMin);
149   // OK for the output
150   //
151   CellPointExtractor cpe2(input);
152   vtkDataArray *da(cpe2.Get()->GetScalars(arrNameOfFamilyField));
153   if(!da)
154     return 0;
155   std::string daName(da->GetName());
156   typedef MEDFileVTKTraits<MEDCoupling::mcIdType>::VtkType vtkMCIdTypeArray;
157   vtkMCIdTypeArray *dai(vtkMCIdTypeArray::SafeDownCast(da));
158   if(daName!=arrNameOfFamilyField || !dai)
159     return 0;
160   //
161   int nbOfTuples(dai->GetNumberOfTuples());
162   vtkCharArray *zeSelection(vtkCharArray::New());
163   zeSelection->SetName(ZE_SELECTION_ARR_NAME);
164   zeSelection->SetNumberOfComponents(1);
165   char *pt(new char[nbOfTuples]);
166   zeSelection->SetArray(pt,nbOfTuples,0,VTK_DATA_ARRAY_DELETE);
167   const MEDCoupling::mcIdType *inPtr(dai->GetPointer(0));
168   std::fill(pt,pt+nbOfTuples,0);
169   catchAll=true; catchSmth=false;
170   std::vector<bool> pt2(nbOfTuples,false);
171   for(std::set<int>::const_iterator it=idsToKeep.begin();it!=idsToKeep.end();it++)
172     {
173       bool catchFid(false);
174       for(int i=0;i<nbOfTuples;i++)
175         if(inPtr[i]==*it)
176           { pt2[i]=true; catchFid=true; }
177       if(!catchFid)
178         catchAll=false;
179       else
180         catchSmth=true;
181     }
182   for(int ii=0;ii<nbOfTuples;ii++)
183     if(pt2[ii])
184       pt[ii]=2;
185   CellPointExtractor cpe3(output);
186   int idx(cpe3.Get()->AddArray(zeSelection));
187   cpe3.Get()->SetActiveAttribute(idx,vtkDataSetAttributes::SCALARS);
188   cpe3.Get()->CopyScalarsOff();
189   zeSelection->Delete();
190   //
191   thres->SetInputArrayToProcess(idx,0,0,associationForThreshold,ZE_SELECTION_ARR_NAME);
192   thres->Update();
193   vtkUnstructuredGrid *zeComputedOutput(thres->GetOutput());
194   CellPointExtractor cpe(zeComputedOutput);
195   cpe.Get()->RemoveArray(idx);
196   output->Delete();
197   zeComputedOutput->Register(0);
198   return zeComputedOutput;
199 }
200
201 class CellExtractor
202 {
203 public:
204   CellExtractor(vtkDataSet *ds):_ds(ds) { }
205   vtkDataSetAttributes *Get() { return _ds->GetCellData(); }
206 private:
207   vtkDataSet *_ds;
208 };
209
210 class PointExtractor
211 {
212 public:
213   PointExtractor(vtkDataSet *ds):_ds(ds) { }
214   vtkDataSetAttributes *Get() { return _ds->GetPointData(); }
215 private:
216   vtkDataSet *_ds;
217 };
218 int vtkExtractGroup::RequestData(vtkInformation * /*request*/, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
219 {
220   try
221     {
222       // std::cerr << "########################################## vtkExtractGroup::RequestData        ##########################################" << std::endl;
223       // request->Print(cout);
224       vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
225       vtkMultiBlockDataSet *inputMB(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
226       if(inputMB->GetNumberOfBlocks()!=1)
227         {
228           std::ostringstream oss; oss << "vtkExtractGroup::RequestData : input has not the right number of parts ! Expected 1 !";
229           if(this->HasObserver("ErrorEvent") )
230             this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
231           else
232             vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
233           vtkObject::BreakOnError();
234           return 0;
235         }
236       vtkDataSet *input(vtkDataSet::SafeDownCast(inputMB->GetBlock(0)));
237       //vtkInformation *info(input->GetInformation()); // todo: unused
238       vtkInformation *outInfo(outputVector->GetInformationObject(0));
239       vtkMultiBlockDataSet *output(vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
240       std::set<int> idsToKeep(this->Internal->getIdsToKeep());
241       this->Internal->clearSelection();
242       // first shrink the input
243       bool catchAll,catchSmth;
244       vtkSmartPointer<vtkThreshold> thres1(vtkSmartPointer<vtkThreshold>::New()),thres2(vtkSmartPointer<vtkThreshold>::New());
245       vtkDataSet *tryOnCell(FilterFamilies<CellExtractor>(thres1,input,idsToKeep,this->InsideOut,
246                                                           MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME,"vtkDataObject::FIELD_ASSOCIATION_CELLS",catchAll,catchSmth));
247       if(tryOnCell)
248         {
249           if(catchAll)
250             {
251               output->SetBlock(0,tryOnCell);
252               tryOnCell->Delete();//
253               return 1;
254             }
255           else
256             {
257               if(catchSmth)
258                 {
259                   vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres2,input,idsToKeep,this->InsideOut,
260                                                                        MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
261                   if(tryOnNode && catchSmth)
262                     {
263                       output->SetBlock(0,tryOnCell);
264                       output->SetBlock(1,tryOnNode);
265                       tryOnCell->Delete();
266                       tryOnNode->Delete();
267                       return 1;
268                     }
269                   else
270                     {
271                       if(tryOnNode)
272                         tryOnNode->Delete();
273                       output->SetBlock(0,tryOnCell);
274                       tryOnCell->Delete();
275                       return 1;
276                     }
277                 }
278               else
279                 {
280                   vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
281                                                                        MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
282                   if(tryOnNode)
283                     {
284                       tryOnCell->Delete();
285                       output->SetBlock(0,tryOnNode);
286                       tryOnNode->Delete();
287                       return 1;
288                     }
289                   else
290                     {
291                       output->SetBlock(0,tryOnNode);
292                       tryOnCell->Delete();
293                       return 0;
294                     }
295                 }
296             }
297         }
298       else
299         {
300           vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
301                                                                MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
302           if(tryOnNode)
303             {
304               output->ShallowCopy(tryOnNode);
305               tryOnNode->Delete();//
306               return 1;
307             }
308           else
309             {
310               std::ostringstream oss; oss << "vtkExtractGroup::RequestData : The integer array with name \""<< MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME;
311               oss << "\" or \"" << MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME << "\" does not exist ! The extraction of group and/or family is not possible !";
312               if(this->HasObserver("ErrorEvent") )
313                 this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
314               else
315                 vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
316               vtkObject::BreakOnError();
317               return 0;
318             }
319         }
320     }
321   catch(INTERP_KERNEL::Exception& e)
322     {
323       std::cerr << "Exception has been thrown in vtkExtractGroup::RequestData : " << e.what() << std::endl;
324       return 0;
325     }
326 }
327
328 int vtkExtractGroup::GetSILUpdateStamp()
329 {
330   return (int)this->SILTime;
331 }
332
333 const char* vtkExtractGroup::GetGrpStart()
334 {
335   return ExtractGroupGrp::START;
336 }
337
338 const char* vtkExtractGroup::GetFamStart()
339 {
340   return ExtractGroupFam::START;
341 }
342
343 void vtkExtractGroup::PrintSelf(ostream& os, vtkIndent indent)
344 {
345   this->Superclass::PrintSelf(os, indent);
346 }
347
348 int vtkExtractGroup::GetNumberOfGroupsFlagsArrays()
349 {
350   int ret(this->Internal->getNumberOfEntries());
351   //std::cerr << "vtkExtractGroup::GetNumberOfFieldsTreeArrays() -> " << ret << std::endl;
352   return ret;
353 }
354
355 const char *vtkExtractGroup::GetGroupsFlagsArrayName(int index)
356 {
357   const char *ret(this->Internal->getKeyOfEntry(index));
358 //  std::cerr << "vtkExtractGroup::GetFieldsTreeArrayName(" << index << ") -> " << ret << std::endl;
359   return ret;
360 }
361
362 int vtkExtractGroup::GetGroupsFlagsArrayStatus(const char *name)
363 {
364   int ret((int)this->Internal->getStatusOfEntryStr(name));
365 //  std::cerr << "vtkExtractGroup::GetGroupsFlagsArrayStatus(" << name << ") -> " << ret << std::endl;
366   return ret;
367 }
368
369 void vtkExtractGroup::SetGroupsFlagsStatus(const char *name, int status)
370 {
371   //std::cerr << "vtkExtractGroup::SetFieldsStatus(" << name << "," << status << ")" << std::endl;
372   this->Internal->setStatusOfEntryStr(name,(bool)status);
373   this->Modified();
374   //this->Internal->printMySelf(std::cerr);
375 }
376
377 const char *vtkExtractGroup::GetMeshName()
378 {
379   return this->Internal->getMeshName();
380 }