Salome HOME
0cfc9e06c59a8d25bc5aaf2a72ea134ead8f8171
[modules/paravis.git] / src / Plugins / VoroGauss / IO / vtkVoroGauss.cxx
1 // Copyright (C) 2017  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 (EDF R&D)
20
21 #include "vtkVoroGauss.h"
22
23 #include "vtkAdjacentVertexIterator.h"
24 #include "vtkIntArray.h"
25 #include "vtkCellData.h"
26 #include "vtkPointData.h"
27 #include "vtkCellType.h"
28 #include "vtkCell.h"
29 #include "vtkCellArray.h"
30 #include "vtkIdTypeArray.h"
31
32 #include "vtkStreamingDemandDrivenPipeline.h"
33 #include "vtkUnstructuredGrid.h"
34 #include  "vtkMultiBlockDataSet.h"
35
36 #include "vtkInformationStringKey.h"
37 #include "vtkAlgorithmOutput.h"
38 #include "vtkObjectFactory.h"
39 #include "vtkMutableDirectedGraph.h"
40 #include "vtkMultiBlockDataSet.h"
41 #include "vtkDataSet.h"
42 #include "vtkInformationVector.h"
43 #include "vtkInformation.h"
44 #include "vtkDataArraySelection.h"
45 #include "vtkTimeStamp.h"
46 #include "vtkInEdgeIterator.h"
47 #include "vtkInformationDataObjectKey.h"
48 #include "vtkInformationDataObjectMetaDataKey.h"
49 #include "vtkInformationDoubleVectorKey.h"
50 #include "vtkExecutive.h"
51 #include "vtkVariantArray.h"
52 #include "vtkStringArray.h"
53 #include "vtkDoubleArray.h"
54 #include "vtkFloatArray.h"
55 #include "vtkCharArray.h"
56 #include "vtkLongArray.h"
57 #include "vtkUnsignedCharArray.h"
58 #include "vtkDataSetAttributes.h"
59 #include "vtkDemandDrivenPipeline.h"
60 #include "vtkDataObjectTreeIterator.h"
61 #include "vtkWarpScalar.h"
62 #include "vtkQuadratureSchemeDefinition.h"
63 #include "vtkInformationQuadratureSchemeDefinitionVectorKey.h"
64 #include "vtkCompositeDataToUnstructuredGridFilter.h"
65 #include "vtkMultiBlockDataGroupFilter.h"
66
67 #include "MEDCouplingMemArray.hxx"
68 #include "MEDCouplingUMesh.hxx"
69 #include "MEDCouplingFieldDouble.hxx"
70 #include "InterpKernelAutoPtr.hxx"
71 #include "InterpKernelGaussCoords.hxx"
72
73 #include <map>
74 #include <set>
75 #include <deque>
76 #include <sstream>
77
78 using MEDCoupling::DataArray;
79 using MEDCoupling::DataArrayInt;
80 using MEDCoupling::DataArrayDouble;
81 using MEDCoupling::MEDCouplingMesh;
82 using MEDCoupling::MEDCouplingUMesh;
83 using MEDCoupling::DynamicCastSafe;
84 using MEDCoupling::MEDCouplingFieldDouble;
85 using MEDCoupling::ON_GAUSS_PT;
86 using MEDCoupling::MCAuto;
87
88 vtkStandardNewMacro(vtkVoroGauss);
89 ///////////////////
90
91 std::map<int,int> ComputeMapOfType()
92 {
93   std::map<int,int> ret;
94   int nbOfTypesInMC(sizeof(MEDCouplingUMesh::MEDCOUPLING2VTKTYPETRADUCER)/sizeof(int));
95   for(int i=0;i<nbOfTypesInMC;i++)
96     {
97       int vtkId(MEDCouplingUMesh::MEDCOUPLING2VTKTYPETRADUCER[i]);
98       if(vtkId!=-1)
99         ret[vtkId]=i;
100     }
101   return ret;
102 }
103
104 std::map<int,int> ComputeRevMapOfType()
105 {
106   std::map<int,int> ret;
107   int nbOfTypesInMC(sizeof(MEDCouplingUMesh::MEDCOUPLING2VTKTYPETRADUCER)/sizeof(int));
108   for(int i=0;i<nbOfTypesInMC;i++)
109     {
110       int vtkId(MEDCouplingUMesh::MEDCOUPLING2VTKTYPETRADUCER[i]);
111       if(vtkId!=-1)
112         ret[i]=vtkId;
113     }
114   return ret;
115 }
116
117 ///////////////////
118
119 vtkInformationDoubleVectorKey *GetMEDReaderMetaDataIfAny()
120 {
121   static const char ZE_KEY[]="vtkMEDReader::GAUSS_DATA";
122   MEDCoupling::GlobalDict *gd(MEDCoupling::GlobalDict::GetInstance());
123   if(!gd->hasKey(ZE_KEY))
124     return 0;
125   std::string ptSt(gd->value(ZE_KEY));
126   void *pt(0);
127   std::istringstream iss(ptSt); iss >> pt;
128   return reinterpret_cast<vtkInformationDoubleVectorKey *>(pt);
129 }
130
131 bool IsInformationOK(vtkInformation *info, std::vector<double>& data)
132 {
133   vtkInformationDoubleVectorKey *key(GetMEDReaderMetaDataIfAny());
134   if(!key)
135     return false;
136   // Check the information contain meta data key
137   if(!info->Has(key))
138     return false;
139   int lgth(key->Length(info));
140   const double *data2(info->Get(key));
141   data.insert(data.end(),data2,data2+lgth);
142   return true;
143 }
144
145 void ExtractInfo(vtkInformationVector *inputVector, vtkUnstructuredGrid *& usgIn)
146 {
147   vtkInformation *inputInfo(inputVector->GetInformationObject(0));
148   vtkDataSet *input(0);
149   vtkDataSet *input0(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
150   vtkMultiBlockDataSet *input1(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
151   if(input0)
152     input=input0;
153   else
154     {
155       if(!input1)
156         throw INTERP_KERNEL::Exception("Input dataSet must be a DataSet or single elt multi block dataset expected !");
157       if(input1->GetNumberOfBlocks()!=1)
158         throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with not exactly one block ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
159       vtkDataObject *input2(input1->GetBlock(0));
160       if(!input2)
161         throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block but this single element is NULL !");
162       vtkDataSet *input2c(vtkDataSet::SafeDownCast(input2));
163       if(!input2c)
164         throw INTERP_KERNEL::Exception("Input dataSet is a multiblock dataset with exactly one block but this single element is not a dataset ! Use MergeBlocks or ExtractBlocks filter before calling this filter !");
165       input=input2c;
166     }
167   if(!input)
168     throw INTERP_KERNEL::Exception("Input data set is NULL !");
169   usgIn=vtkUnstructuredGrid::SafeDownCast(input);
170   if(!usgIn)
171     throw INTERP_KERNEL::Exception("Input data set is not an unstructured mesh ! This filter works only on unstructured meshes !");
172 }
173
174 DataArrayInt *ConvertVTKArrayToMCArrayInt(vtkDataArray *data)
175 {
176   if(!data)
177     throw INTERP_KERNEL::Exception("ConvertVTKArrayToMCArrayInt : internal error !");
178   int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents());
179   std::size_t nbElts(nbTuples*nbComp);
180   MCAuto<DataArrayInt> ret(DataArrayInt::New());
181   ret->alloc(nbTuples,nbComp);
182   for(int i=0;i<nbComp;i++)
183     {
184       const char *comp(data->GetComponentName(i));
185       if(comp)
186         ret->setInfoOnComponent(i,comp);
187     }
188   int *ptOut(ret->getPointer());
189   vtkIntArray *d0(vtkIntArray::SafeDownCast(data));
190   if(d0)
191     {
192       const int *pt(d0->GetPointer(0));
193       std::copy(pt,pt+nbElts,ptOut);
194       return ret.retn();
195     }
196   vtkLongArray *d1(vtkLongArray::SafeDownCast(data));
197   if(d1)
198     {
199       const long *pt(d1->GetPointer(0));
200       std::copy(pt,pt+nbElts,ptOut);
201       return ret.retn();
202     }
203   vtkIdTypeArray *d2(vtkIdTypeArray::SafeDownCast(data));
204   if(d2)
205     {
206       const int *pt(d2->GetPointer(0));
207       std::copy(pt,pt+nbElts,ptOut);
208       return ret.retn();
209     }
210   std::ostringstream oss;
211   oss << "ConvertVTKArrayToMCArrayInt : unrecognized array \"" << typeid(*data).name() << "\" type !";
212   throw INTERP_KERNEL::Exception(oss.str());
213 }
214
215 DataArrayDouble *ConvertVTKArrayToMCArrayDouble(vtkDataArray *data)
216 {
217   if(!data)
218     throw INTERP_KERNEL::Exception("ConvertVTKArrayToMCArrayDouble : internal error !");
219   int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents());
220   std::size_t nbElts(nbTuples*nbComp);
221   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
222   ret->alloc(nbTuples,nbComp);
223   for(int i=0;i<nbComp;i++)
224     {
225       const char *comp(data->GetComponentName(i));
226       if(comp)
227         ret->setInfoOnComponent(i,comp);
228     }
229   double *ptOut(ret->getPointer());
230   vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data));
231   if(d0)
232     {
233       const float *pt(d0->GetPointer(0));
234       for(std::size_t i=0;i<nbElts;i++)
235         ptOut[i]=pt[i];
236       return ret.retn();
237     }
238   vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data));
239   if(d1)
240     {
241       const double *pt(d1->GetPointer(0));
242       std::copy(pt,pt+nbElts,ptOut);
243       return ret.retn();
244     }
245   std::ostringstream oss;
246   oss << "ConvertVTKArrayToMCArrayDouble : unrecognized array \"" << typeid(*data).name() << "\" type !";
247   throw INTERP_KERNEL::Exception(oss.str());
248 }
249
250 DataArray *ConvertVTKArrayToMCArray(vtkDataArray *data)
251 {
252   if(!data)
253     throw INTERP_KERNEL::Exception("ConvertVTKArrayToMCArray : internal error !");
254   vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data));
255   vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data));
256   if(d0 || d1)
257     return ConvertVTKArrayToMCArrayDouble(data);
258   vtkIntArray *d2(vtkIntArray::SafeDownCast(data));
259   vtkLongArray *d3(vtkLongArray::SafeDownCast(data));
260   if(d2 || d3)
261     return ConvertVTKArrayToMCArrayInt(data);
262   std::ostringstream oss;
263   oss << "ConvertVTKArrayToMCArray : unrecognized array \"" << typeid(*data).name() << "\" type !";
264   throw INTERP_KERNEL::Exception(oss.str());
265 }
266
267 DataArrayDouble *BuildCoordsFrom(vtkPointSet *ds)
268 {
269   if(!ds)
270     throw INTERP_KERNEL::Exception("BuildCoordsFrom : internal error !");
271   vtkPoints *pts(ds->GetPoints());
272   if(!pts)
273     throw INTERP_KERNEL::Exception("BuildCoordsFrom : internal error 2 !");
274   vtkDataArray *data(pts->GetData());
275   if(!data)
276     throw INTERP_KERNEL::Exception("BuildCoordsFrom : internal error 3 !");
277   MCAuto<DataArrayDouble> coords(ConvertVTKArrayToMCArrayDouble(data));
278   return coords.retn();
279 }
280
281 void ConvertFromUnstructuredGrid(vtkUnstructuredGrid *ds, std::vector< MCAuto<MEDCouplingUMesh> >& ms, std::vector< MCAuto<DataArrayInt> >& ids)
282 {
283   MCAuto<DataArrayDouble> coords(BuildCoordsFrom(ds));
284   vtkIdType nbCells(ds->GetNumberOfCells());
285   vtkCellArray *ca(ds->GetCells());
286   if(!ca)
287     return ;
288   vtkIdType nbEnt(ca->GetNumberOfConnectivityEntries());
289   vtkIdType *caPtr(ca->GetPointer());
290   vtkUnsignedCharArray *ct(ds->GetCellTypesArray());
291   if(!ct)
292     throw INTERP_KERNEL::Exception("ConvertFromUnstructuredGrid : internal error");
293   vtkIdTypeArray *cla(ds->GetCellLocationsArray());
294   const vtkIdType *claPtr(cla->GetPointer(0));
295   if(!cla)
296     throw INTERP_KERNEL::Exception("ConvertFromUnstructuredGrid : internal error 2");
297   const unsigned char *ctPtr(ct->GetPointer(0));
298   std::map<int,int> m(ComputeMapOfType());
299   MCAuto<DataArrayInt> lev(DataArrayInt::New()) ;  lev->alloc(nbCells,1);
300   int *levPtr(lev->getPointer());
301   for(vtkIdType i=0;i<nbCells;i++)
302     {
303       std::map<int,int>::iterator it(m.find(ctPtr[i]));
304       if(it!=m.end())
305         {
306           const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)(*it).second));
307           levPtr[i]=cm.getDimension();
308         }
309       else
310         {
311           std::ostringstream oss; oss << "ConvertFromUnstructuredGrid : at pos #" << i << " unrecognized VTK cell with type =" << ctPtr[i];
312           throw INTERP_KERNEL::Exception(oss.str());
313         }
314     }
315   MCAuto<DataArrayInt> levs(lev->getDifferentValues());
316   vtkIdTypeArray *faces(ds->GetFaces()),*faceLoc(ds->GetFaceLocations());
317   for(const int *curLev=levs->begin();curLev!=levs->end();curLev++)
318     {
319       MCAuto<MEDCouplingUMesh> m0(MEDCouplingUMesh::New("",*curLev));
320       m0->setCoords(coords); m0->allocateCells();
321       MCAuto<DataArrayInt> cellIdsCurLev(lev->findIdsEqual(*curLev));
322       for(const int *cellId=cellIdsCurLev->begin();cellId!=cellIdsCurLev->end();cellId++)
323         {
324           std::map<int,int>::iterator it(m.find(ctPtr[*cellId]));
325           vtkIdType offset(claPtr[*cellId]);
326           vtkIdType sz(caPtr[offset]);
327           INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)(*it).second);
328           if(ct!=INTERP_KERNEL::NORM_POLYHED)
329             {
330               std::vector<int> conn2(sz);
331               for(int kk=0;kk<sz;kk++)
332                 conn2[kk]=caPtr[offset+1+kk];
333               m0->insertNextCell(ct,sz,&conn2[0]);
334             }
335           else
336             {
337               if(!faces || !faceLoc)
338                 throw INTERP_KERNEL::Exception("ConvertFromUnstructuredGrid : faces are expected when there are polyhedra !");
339               const vtkIdType *facPtr(faces->GetPointer(0)),*facLocPtr(faceLoc->GetPointer(0));
340               std::vector<int> conn;
341               int off0(facLocPtr[*cellId]);
342               int nbOfFaces(facPtr[off0++]);
343               for(int k=0;k<nbOfFaces;k++)
344                 {
345                   int nbOfNodesInFace(facPtr[off0++]);
346                   std::copy(facPtr+off0,facPtr+off0+nbOfNodesInFace,std::back_inserter(conn));
347                   off0+=nbOfNodesInFace;
348                   if(k<nbOfFaces-1)
349                     conn.push_back(-1);
350                 }
351               m0->insertNextCell(ct,conn.size(),&conn[0]);
352             }
353         }
354       ms.push_back(m0); ids.push_back(cellIdsCurLev);
355     }
356 }
357
358 vtkSmartPointer<vtkUnstructuredGrid> ConvertUMeshFromMCToVTK(const MEDCouplingUMesh *mVor)
359 {
360   std::map<int,int> zeMapRev(ComputeRevMapOfType());
361   int nbCells(mVor->getNumberOfCells());
362   vtkSmartPointer<vtkUnstructuredGrid> ret(vtkSmartPointer<vtkUnstructuredGrid>::New());
363   ret->Initialize();
364   ret->Allocate();
365   vtkSmartPointer<vtkPoints> points(vtkSmartPointer<vtkPoints>::New());
366   {
367     const DataArrayDouble *vorCoords(mVor->getCoords());
368     vtkSmartPointer<vtkDoubleArray> da(vtkSmartPointer<vtkDoubleArray>::New());
369     da->SetNumberOfComponents(vorCoords->getNumberOfComponents());
370     da->SetNumberOfTuples(vorCoords->getNumberOfTuples());
371     std::copy(vorCoords->begin(),vorCoords->end(),da->GetPointer(0));
372     points->SetData(da);
373   }
374   mVor->checkConsistencyLight();
375   switch(mVor->getMeshDimension())
376     {
377     case 3:
378       {
379         int *cPtr(nullptr),*dPtr(nullptr);
380         unsigned char *aPtr(nullptr);
381         vtkSmartPointer<vtkUnsignedCharArray> cellTypes(vtkSmartPointer<vtkUnsignedCharArray>::New());
382         {
383           cellTypes->SetNumberOfComponents(1);
384           cellTypes->SetNumberOfTuples(nbCells);
385           aPtr=cellTypes->GetPointer(0);
386         }
387         vtkSmartPointer<vtkIdTypeArray> cellLocations(vtkSmartPointer<vtkIdTypeArray>::New());
388         {
389           cellLocations->SetNumberOfComponents(1);
390           cellLocations->SetNumberOfTuples(nbCells);
391           cPtr=cellLocations->GetPointer(0);
392         }
393         vtkSmartPointer<vtkIdTypeArray> cells(vtkSmartPointer<vtkIdTypeArray>::New());
394         {
395           MCAuto<DataArrayInt> tmp2(mVor->computeEffectiveNbOfNodesPerCell());
396           cells->SetNumberOfComponents(1);
397           cells->SetNumberOfTuples(tmp2->accumulate(0)+nbCells);
398           dPtr=cells->GetPointer(0);
399         }
400         const int *connPtr(mVor->getNodalConnectivity()->begin()),*connIPtr(mVor->getNodalConnectivityIndex()->begin());
401         int k(0),kk(0);
402         std::vector<vtkIdType> ee,ff;
403         for(int i=0;i<nbCells;i++,connIPtr++)
404           {
405             INTERP_KERNEL::NormalizedCellType ct(static_cast<INTERP_KERNEL::NormalizedCellType>(connPtr[connIPtr[0]]));
406             *aPtr++=zeMapRev[connPtr[connIPtr[0]]];
407             if(ct!=INTERP_KERNEL::NORM_POLYHED)
408               {
409                 int sz(connIPtr[1]-connIPtr[0]-1);
410                 *dPtr++=sz;
411                 dPtr=std::copy(connPtr+connIPtr[0]+1,connPtr+connIPtr[1],dPtr);
412                 *cPtr++=k; k+=sz+1;
413                 ee.push_back(kk);
414               }
415             else
416               {
417                 std::set<int> s(connPtr+connIPtr[0]+1,connPtr+connIPtr[1]); s.erase(-1);
418                 int nbFace(std::count(connPtr+connIPtr[0]+1,connPtr+connIPtr[1],-1)+1);
419                 ff.push_back(nbFace);
420                 const int *work(connPtr+connIPtr[0]+1);
421                 for(int j=0;j<nbFace;j++)
422                   {
423                     const int *work2=std::find(work,connPtr+connIPtr[1],-1);
424                     ff.push_back(std::distance(work,work2));
425                     ff.insert(ff.end(),work,work2);
426                     work=work2+1;
427                   }
428                 *dPtr++=(int)s.size();
429                 dPtr=std::copy(s.begin(),s.end(),dPtr);
430                 *cPtr++=k; k+=(int)s.size()+1;
431                 ee.push_back(kk); kk+=connIPtr[1]-connIPtr[0]+1;
432               }
433           }
434         //
435         vtkSmartPointer<vtkIdTypeArray> faceLocations(vtkSmartPointer<vtkIdTypeArray>::New());
436         {
437           faceLocations->SetNumberOfComponents(1);
438           faceLocations->SetNumberOfTuples(ee.size());
439           std::copy(ee.begin(),ee.end(),faceLocations->GetPointer(0));
440         }
441         vtkSmartPointer<vtkIdTypeArray> faces(vtkSmartPointer<vtkIdTypeArray>::New());
442         {
443           faces->SetNumberOfComponents(1);
444           faces->SetNumberOfTuples(ff.size());
445           std::copy(ff.begin(),ff.end(),faces->GetPointer(0));
446         }
447         vtkSmartPointer<vtkCellArray> cells2(vtkSmartPointer<vtkCellArray>::New());
448         cells2->SetCells(nbCells,cells);
449         ret->SetCells(cellTypes,cellLocations,cells2,faceLocations,faces);
450         break;
451       }
452     case 2:
453       {
454         vtkSmartPointer<vtkUnsignedCharArray> cellTypes(vtkSmartPointer<vtkUnsignedCharArray>::New());
455         {
456           cellTypes->SetNumberOfComponents(1);
457           cellTypes->SetNumberOfTuples(nbCells);
458           unsigned char *ptr(cellTypes->GetPointer(0));
459           std::fill(ptr,ptr+nbCells,zeMapRev[(int)INTERP_KERNEL::NORM_POLYGON]);
460         }
461         int *cPtr(0),*dPtr(0);
462         vtkSmartPointer<vtkIdTypeArray> cellLocations(vtkSmartPointer<vtkIdTypeArray>::New());
463         {
464           cellLocations->SetNumberOfComponents(1);
465           cellLocations->SetNumberOfTuples(nbCells);
466           cPtr=cellLocations->GetPointer(0);
467         }
468         vtkSmartPointer<vtkIdTypeArray> cells(vtkSmartPointer<vtkIdTypeArray>::New());
469         {
470           cells->SetNumberOfComponents(1);
471           cells->SetNumberOfTuples(mVor->getNodalConnectivity()->getNumberOfTuples());
472           dPtr=cells->GetPointer(0);
473         }
474         const int *connPtr(mVor->getNodalConnectivity()->begin()),*connIPtr(mVor->getNodalConnectivityIndex()->begin());
475         int k(0);
476         for(int i=0;i<nbCells;i++,connIPtr++)
477           {
478             *dPtr++=connIPtr[1]-connIPtr[0]-1;
479             dPtr=std::copy(connPtr+connIPtr[0]+1,connPtr+connIPtr[1],dPtr);
480             *cPtr++=k; k+=connIPtr[1]-connIPtr[0];
481           }
482         vtkSmartPointer<vtkCellArray> cells2(vtkSmartPointer<vtkCellArray>::New());
483         cells2->SetCells(nbCells,cells);
484         ret->SetCells(cellTypes,cellLocations,cells2);
485         break;
486       }
487     case 1:
488       {
489         vtkSmartPointer<vtkUnsignedCharArray> cellTypes(vtkSmartPointer<vtkUnsignedCharArray>::New());
490         {
491           cellTypes->SetNumberOfComponents(1);
492           cellTypes->SetNumberOfTuples(nbCells);
493           unsigned char *ptr(cellTypes->GetPointer(0));
494           std::fill(ptr,ptr+nbCells,zeMapRev[(int)INTERP_KERNEL::NORM_SEG2]);
495         }
496         int *cPtr(0),*dPtr(0);
497         vtkSmartPointer<vtkIdTypeArray> cellLocations(vtkSmartPointer<vtkIdTypeArray>::New());
498         {
499           cellLocations->SetNumberOfComponents(1);
500           cellLocations->SetNumberOfTuples(nbCells);
501           cPtr=cellLocations->GetPointer(0);
502         }
503         vtkSmartPointer<vtkIdTypeArray> cells(vtkSmartPointer<vtkIdTypeArray>::New());
504         {
505           cells->SetNumberOfComponents(1);
506           cells->SetNumberOfTuples(mVor->getNodalConnectivity()->getNumberOfTuples());
507           dPtr=cells->GetPointer(0);
508         }
509         const int *connPtr(mVor->getNodalConnectivity()->begin()),*connIPtr(mVor->getNodalConnectivityIndex()->begin());
510         for(int i=0;i<nbCells;i++,connIPtr++)
511           {
512             *dPtr++=2;
513             dPtr=std::copy(connPtr+connIPtr[0]+1,connPtr+connIPtr[1],dPtr);
514             *cPtr++=3*i;
515           }
516         vtkSmartPointer<vtkCellArray> cells2(vtkSmartPointer<vtkCellArray>::New());
517         cells2->SetCells(nbCells,cells);
518         ret->SetCells(cellTypes,cellLocations,cells2);
519         break;
520       }
521     default:
522       throw INTERP_KERNEL::Exception("Not implemented yet !");
523     }
524   ret->SetPoints(points);
525   return ret;
526 }
527
528 class OffsetKeeper
529 {
530 public:
531   OffsetKeeper():_vtk_arr(0) { }
532   void pushBack(vtkDataArray *da) { _da_on.push_back(da); }
533   void setVTKArray(vtkIdTypeArray *arr) { 
534     MCAuto<DataArrayInt> offmc(ConvertVTKArrayToMCArrayInt(arr));
535     _off_arr=offmc; _vtk_arr=arr; }
536   const std::vector<vtkDataArray *>& getArrayGauss() const { return _da_on; }
537   const DataArrayInt *getOffsets() const { return _off_arr; }
538   vtkIdTypeArray *getVTKOffsets() const { return _vtk_arr; }
539 private:
540   std::vector<vtkDataArray *> _da_on;
541   MCAuto<DataArrayInt> _off_arr;
542   vtkIdTypeArray *_vtk_arr;
543 };
544
545 void FillAdvInfoFrom(int vtkCT, const std::vector<double>& GaussAdvData, int nbGaussPt, int nbNodesPerCell, std::vector<double>& refCoo,std::vector<double>& posInRefCoo)
546 {
547   int nbOfCTS((int)GaussAdvData[0]),pos(1);
548   for(int i=0;i<nbOfCTS;i++)
549     {
550       int lgth((int)GaussAdvData[pos]);
551       int curCT((int)GaussAdvData[pos+1]),dim((int)GaussAdvData[pos+2]);
552       if(curCT!=vtkCT)
553         {
554           pos+=lgth+1;
555           continue;
556         }
557       int lgthExp(nbNodesPerCell*dim+nbGaussPt*dim);
558       if(lgth!=lgthExp+2)//+2 for cell type and dimension !
559         {
560           std::ostringstream oss; oss << "FillAdvInfoFrom : Internal error. Unmatch with MEDReader version ? Expect size " << lgthExp << " and have " << lgth << " !";
561           throw INTERP_KERNEL::Exception(oss.str());
562         }
563       refCoo.insert(refCoo.end(),GaussAdvData.begin()+pos+3,GaussAdvData.begin()+pos+3+nbNodesPerCell*dim);
564       posInRefCoo.insert(posInRefCoo.end(),GaussAdvData.begin()+pos+3+nbNodesPerCell*dim,GaussAdvData.begin()+pos+3+nbNodesPerCell*dim+nbGaussPt*dim);
565       //std::copy(refCoo.begin(),refCoo.end(),std::ostream_iterator<double>(std::cerr," ")); std::cerr << std::endl;
566       //std::copy(posInRefCoo.begin(),posInRefCoo.end(),std::ostream_iterator<double>(std::cerr," ")); std::cerr << std::endl;
567       return ;
568     }
569   std::ostringstream oss; oss << "FillAdvInfoFrom : Internal error ! Not found cell type " << vtkCT << " in advanced Gauss info !";
570   throw INTERP_KERNEL::Exception(oss.str());
571 }
572
573 template<class T, class U>
574 vtkSmartPointer<T> ExtractFieldFieldArr(T *elt2, int sizeOfOutArr, int nbOfCellsOfInput, const int *offsetsPtr, const int *nbPtsPerCellPtr)
575 {
576   vtkSmartPointer<T> elt3(vtkSmartPointer<T>::New());
577   int nbc(elt2->GetNumberOfComponents());
578   elt3->SetNumberOfComponents(nbc);
579   elt3->SetNumberOfTuples(sizeOfOutArr);
580   for(int i=0;i<nbc;i++)
581     {
582       const char *name(elt2->GetComponentName(i));
583       if(name)
584         elt3->SetComponentName(i,name);
585     }
586   elt3->SetName(elt2->GetName());
587   //
588   U *ptr(elt3->GetPointer(0));
589   const U *srcPtr(elt2->GetPointer(0));
590   for(int i=0;i<nbOfCellsOfInput;i++)
591     ptr=std::copy(srcPtr+nbc*offsetsPtr[i],srcPtr+nbc*(offsetsPtr[i]+nbPtsPerCellPtr[i]),ptr);
592   return elt3;
593 }
594
595 template<class T, class U>
596 vtkSmartPointer<T> ExtractCellFieldArr(T *elt2, int sizeOfOutArr, int nbOfCellsOfInput, const int *idsPtr, const int *nbPtsPerCellPtr)
597 {
598   vtkSmartPointer<T> elt3(vtkSmartPointer<T>::New());
599   int nbc(elt2->GetNumberOfComponents());
600   elt3->SetNumberOfComponents(nbc);
601   elt3->SetNumberOfTuples(sizeOfOutArr);
602   for(int i=0;i<nbc;i++)
603     {
604       const char *name(elt2->GetComponentName(i));
605       if(name)
606         elt3->SetComponentName(i,name);
607     }
608   elt3->SetName(elt2->GetName());
609   //
610   U *ptr(elt3->GetPointer(0));
611   const U *srcPtr(elt2->GetPointer(0));
612   for(int i=0;i<nbOfCellsOfInput;i++)
613     for(int j=0;j<nbPtsPerCellPtr[i];j++)
614       ptr=std::copy(srcPtr+nbc*idsPtr[i],srcPtr+nbc*(idsPtr[i]+1),ptr);
615   return elt3;
616 }
617
618 vtkSmartPointer<vtkUnstructuredGrid> Voronize(const MEDCouplingUMesh *m, const DataArrayInt *ids, vtkIdTypeArray *vtkOff, const DataArrayInt *offsetsBase, const std::vector<vtkDataArray *>& arrGauss, const std::vector<double>& GaussAdvData, const std::vector<vtkDataArray *>& arrsOnCells)
619 {
620   if(arrGauss.empty())
621     throw INTERP_KERNEL::Exception("Voronize : no Gauss array !");
622   int nbTuples(arrGauss[0]->GetNumberOfTuples());
623   for(std::vector<vtkDataArray *>::const_iterator it=arrGauss.begin();it!=arrGauss.end();it++)
624     {
625       if((*it)->GetNumberOfTuples()!=nbTuples)
626         {
627           std::ostringstream oss; oss << "Mismatch of number of tuples in Gauss arrays for array \"" << (*it)->GetName() << "\"";
628           throw INTERP_KERNEL::Exception(oss.str());
629         }
630     }
631   // Look at vtkOff has in the stomac
632   vtkInformation *info(vtkOff->GetInformation());
633   if(!info)
634     throw INTERP_KERNEL::Exception("info is null ! Internal error ! Looks bad !");
635   vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY());
636   if(!key->Has(info))
637     throw INTERP_KERNEL::Exception("No quadrature key in info included in offets array ! Internal error ! Looks bad !");
638   int dictSize(key->Size(info));
639   INTERP_KERNEL::AutoPtr<vtkQuadratureSchemeDefinition *> dict(new vtkQuadratureSchemeDefinition *[dictSize]);
640   key->GetRange(info,dict,0,0,dictSize);
641   // Voronoize
642   MCAuto<MEDCouplingFieldDouble> field(MEDCouplingFieldDouble::New(ON_GAUSS_PT));
643   field->setMesh(m);
644   // Gauss Part
645   int nbOfCellsOfInput(m->getNumberOfCells());
646   MCAuto<DataArrayInt> nbPtsPerCellArr(DataArrayInt::New()); nbPtsPerCellArr->alloc(nbOfCellsOfInput,1);
647   std::map<int,int> zeMapRev(ComputeRevMapOfType()),zeMap(ComputeMapOfType());
648   std::set<INTERP_KERNEL::NormalizedCellType> agt(m->getAllGeoTypes());
649   for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=agt.begin();it!=agt.end();it++)
650     {
651       const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it));
652       std::map<int,int>::const_iterator it2(zeMapRev.find((int)*it));
653       if(it2==zeMapRev.end())
654         throw INTERP_KERNEL::Exception("Internal error ! no type conversion available !");
655       vtkQuadratureSchemeDefinition *gaussLoc(dict[(*it2).second]);
656       if(!gaussLoc)
657         {
658           std::ostringstream oss; oss << "For cell type " << cm.getRepr() << " no Gauss info !";
659           throw INTERP_KERNEL::Exception(oss.str());
660         }
661       int np(gaussLoc->GetNumberOfQuadraturePoints()),nbPtsPerCell((int)cm.getNumberOfNodes());
662       const double *sfw(gaussLoc->GetShapeFunctionWeights()),*w(gaussLoc->GetQuadratureWeights());;
663       std::vector<double> refCoo,posInRefCoo,wCpp(w,w+np);
664       FillAdvInfoFrom((*it2).second,GaussAdvData,np,nbPtsPerCell,refCoo,posInRefCoo);
665       field->setGaussLocalizationOnType(*it,refCoo,posInRefCoo,wCpp);
666       MCAuto<DataArrayInt> ids2(m->giveCellsWithType(*it));
667       nbPtsPerCellArr->setPartOfValuesSimple3(np,ids2->begin(),ids2->end(),0,1,1);
668     }
669   int zeSizeOfOutCellArr(nbPtsPerCellArr->accumulate(0));
670   { MCAuto<DataArrayDouble> fakeArray(DataArrayDouble::New()); fakeArray->alloc(zeSizeOfOutCellArr,1); field->setArray(fakeArray); }
671   field->checkConsistencyLight();
672   MCAuto<MEDCouplingFieldDouble> vor(field->voronoize(1e-12));// The key is here !
673   MEDCouplingUMesh *mVor(dynamic_cast<MEDCouplingUMesh *>(vor->getMesh()));
674   //
675   vtkSmartPointer<vtkUnstructuredGrid> ret(ConvertUMeshFromMCToVTK(mVor));
676   // now fields...
677   MCAuto<DataArrayInt> myOffsets(offsetsBase->selectByTupleIdSafe(ids->begin(),ids->end()));
678   const int *myOffsetsPtr(myOffsets->begin()),*nbPtsPerCellArrPtr(nbPtsPerCellArr->begin());
679   for(std::vector<vtkDataArray *>::const_iterator it=arrGauss.begin();it!=arrGauss.end();it++)
680     {
681       vtkDataArray *elt(*it);
682       vtkDoubleArray *elt2(vtkDoubleArray::SafeDownCast(elt));
683       vtkIntArray *elt3(vtkIntArray::SafeDownCast(elt));
684       vtkIdTypeArray *elt4(vtkIdTypeArray::SafeDownCast(elt));
685       if(elt2)
686         {
687           vtkSmartPointer<vtkDoubleArray> arr(ExtractFieldFieldArr<vtkDoubleArray,double>(elt2,zeSizeOfOutCellArr,nbOfCellsOfInput,myOffsetsPtr,nbPtsPerCellArrPtr));
688           ret->GetCellData()->AddArray(arr);
689           continue;
690         }
691       if(elt3)
692         {
693           vtkSmartPointer<vtkIntArray> arr(ExtractFieldFieldArr<vtkIntArray,int>(elt3,zeSizeOfOutCellArr,nbOfCellsOfInput,myOffsetsPtr,nbPtsPerCellArrPtr));
694           ret->GetCellData()->AddArray(arr);
695           continue;
696         }
697       if(elt4)
698         {
699           vtkSmartPointer<vtkIdTypeArray> arr(ExtractFieldFieldArr<vtkIdTypeArray,int>(elt4,zeSizeOfOutCellArr,nbOfCellsOfInput,myOffsetsPtr,nbPtsPerCellArrPtr));
700           ret->GetCellData()->AddArray(arr);
701           continue;
702         }
703     }
704   for(std::vector<vtkDataArray *>::const_iterator it=arrsOnCells.begin();it!=arrsOnCells.end();it++)
705     {
706       vtkDataArray *elt(*it);
707       vtkDoubleArray *elt2(vtkDoubleArray::SafeDownCast(elt));
708       vtkIntArray *elt3(vtkIntArray::SafeDownCast(elt));
709       vtkIdTypeArray *elt4(vtkIdTypeArray::SafeDownCast(elt));
710       if(elt2)
711         {
712           vtkSmartPointer<vtkDoubleArray> arr(ExtractCellFieldArr<vtkDoubleArray,double>(elt2,zeSizeOfOutCellArr,nbOfCellsOfInput,ids->begin(),nbPtsPerCellArrPtr));
713           ret->GetCellData()->AddArray(arr);
714           continue;
715         }
716       if(elt3)
717         {
718           vtkSmartPointer<vtkIntArray> arr(ExtractCellFieldArr<vtkIntArray,int>(elt3,zeSizeOfOutCellArr,nbOfCellsOfInput,ids->begin(),nbPtsPerCellArrPtr));
719           ret->GetCellData()->AddArray(arr);
720           continue;
721         }
722       if(elt4)
723         {
724           vtkSmartPointer<vtkIdTypeArray> arr(ExtractCellFieldArr<vtkIdTypeArray,int>(elt4,zeSizeOfOutCellArr,nbOfCellsOfInput,ids->begin(),nbPtsPerCellArrPtr));
725           ret->GetCellData()->AddArray(arr);
726           continue;
727         }
728     }
729   return ret;
730 }
731
732 vtkSmartPointer<vtkUnstructuredGrid> ComputeVoroGauss(vtkUnstructuredGrid *usgIn, const std::vector<double>& GaussAdvData)
733 {
734   OffsetKeeper zeOffsets;
735   std::string zeArrOffset;
736   std::vector<std::string> cellFieldNamesToDestroy;
737   {
738     int nArrays(usgIn->GetFieldData()->GetNumberOfArrays());
739     for(int i=0;i<nArrays;i++)
740       {
741         vtkDataArray *array(usgIn->GetFieldData()->GetArray(i));
742         if(!array)
743           continue;
744         const char* arrayOffsetName(array->GetInformation()->Get(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME()));
745         if(!arrayOffsetName)
746           continue;
747         std::string arrOffsetNameCpp(arrayOffsetName);
748         cellFieldNamesToDestroy.push_back(arrOffsetNameCpp);
749         if(arrOffsetNameCpp.find("ELGA@")==std::string::npos)
750           continue;
751         if(zeArrOffset.empty())
752           zeArrOffset=arrOffsetNameCpp;
753         else
754           if(zeArrOffset!=arrOffsetNameCpp)
755             {
756               throw INTERP_KERNEL::Exception("ComputeVoroGauss : error in QUADRATURE_OFFSET_ARRAY_NAME for Gauss fields array !");
757             }
758         zeOffsets.pushBack(array);
759       }
760     if(zeArrOffset.empty())
761       throw INTERP_KERNEL::Exception("ComputeVoroGauss : no Gauss points fields in DataSet !");
762   }
763   std::vector< MCAuto<MEDCouplingUMesh> > ms;
764   std::vector< MCAuto<DataArrayInt> > ids;
765   ConvertFromUnstructuredGrid(usgIn,ms,ids);
766   {
767     vtkDataArray *offTmp(usgIn->GetCellData()->GetArray(zeArrOffset.c_str()));
768     if(!offTmp)
769       {
770         std::ostringstream oss; oss << "ComputeVoroGauss : cell field " << zeArrOffset << " not found !";
771         throw INTERP_KERNEL::Exception(oss.str());
772       }
773     vtkIdTypeArray *offsets(vtkIdTypeArray::SafeDownCast(offTmp));
774     if(!offsets)
775       {
776         std::ostringstream oss; oss << "ComputeVoroGauss : cell field " << zeArrOffset << " exists but not with the right type of data !";
777         throw INTERP_KERNEL::Exception(oss.str());
778       }
779     ///
780     zeOffsets.setVTKArray(offsets);
781   }
782   //
783   std::vector<vtkDataArray *> arrsOnCells;
784   {
785     int nArrays(usgIn->GetCellData()->GetNumberOfArrays());
786     for(int i=0;i<nArrays;i++)
787       {
788         vtkDataArray *array(usgIn->GetCellData()->GetArray(i));
789         if(!array)
790           continue;
791         std::string name(array->GetName());
792         if(std::find(cellFieldNamesToDestroy.begin(),cellFieldNamesToDestroy.end(),name)==cellFieldNamesToDestroy.end())
793           {
794             arrsOnCells.push_back(array);
795           }
796       }
797     {
798       vtkDataArray *doNotKeepThis(zeOffsets.getVTKOffsets());
799       std::vector<vtkDataArray *>::iterator it2(std::find(arrsOnCells.begin(),arrsOnCells.end(),doNotKeepThis));
800       if(it2!=arrsOnCells.end())
801         arrsOnCells.erase(it2);
802     }
803   }
804   //
805   std::size_t sz(ms.size());
806   std::vector< vtkSmartPointer<vtkUnstructuredGrid> > res;
807   for(std::size_t i=0;i<sz;i++)
808     {
809       MCAuto<MEDCouplingUMesh> mmc(ms[i]);
810       MCAuto<DataArrayInt> myIds(ids[i]);
811       vtkSmartPointer<vtkUnstructuredGrid> vor(Voronize(mmc,myIds,zeOffsets.getVTKOffsets(),zeOffsets.getOffsets(),zeOffsets.getArrayGauss(),GaussAdvData,arrsOnCells));
812       res.push_back(vor);
813     }
814   if(res.empty())
815     throw INTERP_KERNEL::Exception("Dataset is empty !");
816   vtkSmartPointer<vtkMultiBlockDataGroupFilter> mb(vtkSmartPointer<vtkMultiBlockDataGroupFilter>::New());
817   vtkSmartPointer<vtkCompositeDataToUnstructuredGridFilter> cd(vtkSmartPointer<vtkCompositeDataToUnstructuredGridFilter>::New());
818   for(std::vector< vtkSmartPointer<vtkUnstructuredGrid> >::const_iterator it=res.begin();it!=res.end();it++)
819     mb->AddInputData(*it);
820   cd->SetInputConnection(mb->GetOutputPort());
821   cd->SetMergePoints(0);
822   cd->Update();
823   vtkSmartPointer<vtkUnstructuredGrid> ret;
824   ret=cd->GetOutput();
825   return ret;
826 }
827
828 ////////////////////
829
830 vtkVoroGauss::vtkVoroGauss()
831 {
832   this->SetNumberOfInputPorts(1);
833   this->SetNumberOfOutputPorts(1);
834 }
835
836 vtkVoroGauss::~vtkVoroGauss()
837 {
838 }
839
840 int vtkVoroGauss::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
841
842   //std::cerr << "########################################## vtkVoroGauss::RequestInformation ##########################################" << std::endl;
843   try
844     {
845       vtkUnstructuredGrid *usgIn(0);
846       ExtractInfo(inputVector[0],usgIn);
847     }
848   catch(INTERP_KERNEL::Exception& e)
849     {
850       std::ostringstream oss;
851       oss << "Exception has been thrown in vtkVoroGauss::RequestInformation : " << e.what() << std::endl;
852       if(this->HasObserver("ErrorEvent") )
853         this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
854       else
855         vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
856       vtkObject::BreakOnError();
857       return 0;
858     }
859   return 1;
860 }
861
862 int vtkVoroGauss::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
863 {
864   //std::cerr << "########################################## vtkVoroGauss::RequestData        ##########################################" << std::endl;
865   try
866     {
867       
868       std::vector<double> GaussAdvData;
869       bool isOK(IsInformationOK(inputVector[0]->GetInformationObject(0),GaussAdvData));
870       if(!isOK)
871         throw INTERP_KERNEL::Exception("Sorry but no advanced gauss info found ! Expect to be called right after a MEDReader containing Gauss Points !");
872       vtkUnstructuredGrid *usgIn(0);
873       ExtractInfo(inputVector[0],usgIn);
874       //
875       vtkSmartPointer<vtkUnstructuredGrid> ret(ComputeVoroGauss(usgIn,GaussAdvData));
876       vtkInformation *inInfo(inputVector[0]->GetInformationObject(0));
877       vtkInformation *outInfo(outputVector->GetInformationObject(0));
878       vtkUnstructuredGrid *output(vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
879       output->ShallowCopy(ret);
880     }
881   catch(INTERP_KERNEL::Exception& e)
882     {
883       std::ostringstream oss;
884       oss << "Exception has been thrown in vtkVoroGauss::RequestData : " << e.what() << std::endl;
885       if(this->HasObserver("ErrorEvent") )
886         this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
887       else
888         vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
889       vtkObject::BreakOnError();
890       return 0;
891     }
892   return 1;
893 }
894
895 void vtkVoroGauss::PrintSelf(ostream& os, vtkIndent indent)
896 {
897   this->Superclass::PrintSelf(os, indent);
898 }