1 // Copyright (C) 2016 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 (EDF R&D)
21 #include "vtkMEDWriter.h"
23 #include "vtkAdjacentVertexIterator.h"
24 #include "vtkIntArray.h"
25 #include "vtkCellData.h"
26 #include "vtkPointData.h"
27 #include "vtkFloatArray.h"
29 #include "vtkStreamingDemandDrivenPipeline.h"
30 #include "vtkInformationDataObjectMetaDataKey.h"
31 #include "vtkUnstructuredGrid.h"
32 #include "vtkMultiBlockDataSet.h"
33 #include "vtkRectilinearGrid.h"
34 #include "vtkInformationStringKey.h"
35 #include "vtkAlgorithmOutput.h"
36 #include "vtkObjectFactory.h"
37 #include "vtkMutableDirectedGraph.h"
38 #include "vtkMultiBlockDataSet.h"
39 #include "vtkPolyData.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 "vtkWarpScalar.h"
58 #include "MEDFileMesh.hxx"
59 #include "MEDFileField.hxx"
60 #include "MEDFileData.hxx"
61 #include "MEDCouplingMemArray.hxx"
62 #include "MEDCouplingFieldDouble.hxx"
63 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
69 using ParaMEDMEM::MEDFileData;
70 using ParaMEDMEM::MEDFileMesh;
71 using ParaMEDMEM::MEDFileCMesh;
72 using ParaMEDMEM::MEDFileUMesh;
73 using ParaMEDMEM::MEDFileFields;
74 using ParaMEDMEM::MEDFileMeshes;
76 using ParaMEDMEM::MEDFileIntField1TS;
77 using ParaMEDMEM::MEDFileField1TS;
78 using ParaMEDMEM::MEDFileIntFieldMultiTS;
79 using ParaMEDMEM::MEDFileFieldMultiTS;
80 using ParaMEDMEM::MEDFileAnyTypeFieldMultiTS;
81 using ParaMEDMEM::DataArray;
82 using ParaMEDMEM::DataArrayInt;
83 using ParaMEDMEM::DataArrayDouble;
84 using ParaMEDMEM::MEDCouplingMesh;
85 using ParaMEDMEM::MEDCouplingUMesh;
86 using ParaMEDMEM::MEDCouplingCMesh;
87 using ParaMEDMEM::MEDCouplingFieldDouble;
88 using ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr;
90 vtkStandardNewMacro(vtkMEDWriter);
94 class MZCException : public std::exception
97 MZCException(const std::string& s):_reason(s) { }
98 virtual const char *what() const throw() { return _reason.c_str(); }
99 virtual ~MZCException() throw() { }
106 std::map<int,int> ComputeMapOfType()
108 std::map<int,int> ret;
109 int nbOfTypesInMC(sizeof(MEDCouplingUMesh::PARAMEDMEM2VTKTYPETRADUCER)/sizeof(int));
110 for(int i=0;i<nbOfTypesInMC;i++)
112 int vtkId(MEDCouplingUMesh::PARAMEDMEM2VTKTYPETRADUCER[i]);
119 std::string GetMeshNameWithContext(const std::vector<int>& context)
121 static const char DFT_MESH_NAME[]="Mesh";
123 return DFT_MESH_NAME;
124 std::ostringstream oss; oss << DFT_MESH_NAME;
125 for(std::vector<int>::const_iterator it=context.begin();it!=context.end();it++)
130 DataArrayInt *ConvertVTKArrayToMCArrayInt(vtkDataArray *data)
133 throw MZCException("ConvertVTKArrayToMCArrayInt : internal error !");
134 int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents());
135 std::size_t nbElts(nbTuples*nbComp);
136 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
137 ret->alloc(nbTuples,nbComp);
138 for(int i=0;i<nbComp;i++)
140 const char *comp(data->GetComponentName(i));
142 ret->setInfoOnComponent(i,comp);
144 int *ptOut(ret->getPointer());
145 vtkIntArray *d0(vtkIntArray::SafeDownCast(data));
148 const int *pt(d0->GetPointer(0));
149 std::copy(pt,pt+nbElts,ptOut);
152 std::ostringstream oss;
153 oss << "ConvertVTKArrayToMCArrayInt : unrecognized array \"" << typeid(*data).name() << "\" type !";
154 throw MZCException(oss.str());
157 DataArrayDouble *ConvertVTKArrayToMCArrayDouble(vtkDataArray *data)
160 throw MZCException("ConvertVTKArrayToMCArrayDouble : internal error !");
161 int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents());
162 std::size_t nbElts(nbTuples*nbComp);
163 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
164 ret->alloc(nbTuples,nbComp);
165 for(int i=0;i<nbComp;i++)
167 const char *comp(data->GetComponentName(i));
169 ret->setInfoOnComponent(i,comp);
171 double *ptOut(ret->getPointer());
172 vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data));
175 const float *pt(d0->GetPointer(0));
176 for(std::size_t i=0;i<nbElts;i++)
180 vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data));
183 const double *pt(d1->GetPointer(0));
184 std::copy(pt,pt+nbElts,ptOut);
187 std::ostringstream oss;
188 oss << "ConvertVTKArrayToMCArrayDouble : unrecognized array \"" << typeid(*data).name() << "\" type !";
189 throw MZCException(oss.str());
192 DataArray *ConvertVTKArrayToMCArray(vtkDataArray *data)
195 throw MZCException("ConvertVTKArrayToMCArray : internal error !");
196 vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data));
197 vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data));
199 return ConvertVTKArrayToMCArrayDouble(data);
200 vtkIntArray *d2(vtkIntArray::SafeDownCast(data));
202 return ConvertVTKArrayToMCArrayInt(data);
203 std::ostringstream oss;
204 oss << "ConvertVTKArrayToMCArray : unrecognized array \"" << typeid(*data).name() << "\" type !";
205 throw MZCException(oss.str());
208 MEDCouplingUMesh *BuildMeshFromCellArray(vtkCellArray *ca, DataArrayDouble *coords, int meshDim, INTERP_KERNEL::NormalizedCellType type)
210 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh(MEDCouplingUMesh::New("",meshDim));
211 subMesh->setCoords(coords); subMesh->allocateCells();
212 int nbCells(ca->GetNumberOfCells());
215 vtkIdType nbEntries(ca->GetNumberOfConnectivityEntries());
216 const vtkIdType *conn(ca->GetPointer());
217 for(int i=0;i<nbCells;i++)
220 subMesh->insertNextCell(type,sz,conn);
223 return subMesh.retn();
226 MEDCouplingUMesh *BuildMeshFromCellArrayTriangleStrip(vtkCellArray *ca, DataArrayDouble *coords, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& ids)
228 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh(MEDCouplingUMesh::New("",2));
229 subMesh->setCoords(coords); subMesh->allocateCells();
230 int nbCells(ca->GetNumberOfCells());
233 vtkIdType nbEntries(ca->GetNumberOfConnectivityEntries());
234 const vtkIdType *conn(ca->GetPointer());
235 ids=DataArrayInt::New() ; ids->alloc(0,1);
236 for(int i=0;i<nbCells;i++)
242 for(int j=0;j<nbTri;j++,conn++)
244 subMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn);
245 ids->pushBackSilent(i);
250 std::ostringstream oss; oss << "BuildMeshFromCellArrayTriangleStrip : on cell #" << i << " the triangle stip looks bab !";
251 throw MZCException(oss.str());
255 return subMesh.retn();
261 MicroField(const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& m, const std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> >& cellFs):_m(m),_cellFs(cellFs) { }
262 MicroField(const std::vector< MicroField >& vs);
263 void setNodeFields(const std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> >& nf) { _nodeFs=nf; }
264 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> getMesh() const { return _m; }
265 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > getCellFields() const { return _cellFs; }
267 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _m;
268 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > _cellFs;
269 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > _nodeFs;
272 MicroField::MicroField(const std::vector< MicroField >& vs)
274 std::size_t sz(vs.size());
275 std::vector<const MEDCouplingUMesh *> vs2(sz);
276 std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > > arrs2(sz);
278 for(std::size_t ii=0;ii<sz;ii++)
280 vs2[ii]=vs[ii].getMesh();
281 arrs2[ii]=vs[ii].getCellFields();
283 nbElts=arrs2[ii].size();
285 if(arrs2[ii].size()!=nbElts)
286 throw MZCException("MicroField cstor : internal error !");
288 _cellFs.resize(nbElts);
289 for(int ii=0;ii<nbElts;ii++)
291 std::vector<const DataArray *> arrsTmp(sz);
292 for(std::size_t jj=0;jj<sz;jj++)
294 arrsTmp[jj]=arrs2[jj][ii];
296 _cellFs[ii]=DataArray::Aggregate(arrsTmp);
298 _m=MEDCouplingUMesh::MergeUMeshesOnSameCoords(vs2);
301 void AppendMCFieldFrom(ParaMEDMEM::TypeOfField tf, MEDCouplingMesh *mesh, MEDFileData *mfd, MEDCouplingAutoRefCountObjectPtr<DataArray> da, const DataArrayInt *n2oPtr)
303 static const char FAMFIELD_FOR_CELLS[]="FamilyIdCell";
304 static const char FAMFIELD_FOR_NODES[]="FamilyIdNode";
305 if(!da || !mesh || !mfd)
306 throw MZCException("AppendMCFieldFrom : internal error !");
307 MEDFileFields *fs(mfd->getFields());
308 MEDFileMeshes *ms(mfd->getMeshes());
310 throw MZCException("AppendMCFieldFrom : internal error 2 !");
311 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> dad(ParaMEDMEM::DynamicCast<DataArray,DataArrayDouble>(da));
312 DataArrayDouble *dadPtr(dad);
313 std::string fieldName;
316 fieldName=dadPtr->getName();
317 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(tf));
318 f->setName(fieldName);
323 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> dad2(dadPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
327 MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fmts(MEDFileFieldMultiTS::New());
328 MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> f1ts(MEDFileField1TS::New());
329 f1ts->setFieldNoProfileSBT(f);
330 fmts->pushBackTimeStep(f1ts);
334 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dai(ParaMEDMEM::DynamicCast<DataArray,DataArrayInt>(da));
335 DataArrayInt *daiPtr(dai);
338 fieldName=daiPtr->getName();
339 if((fieldName!=FAMFIELD_FOR_CELLS || tf!=ParaMEDMEM::ON_CELLS) && (fieldName!=FAMFIELD_FOR_NODES || tf!=ParaMEDMEM::ON_NODES))
341 MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f(MEDCouplingFieldDouble::New(tf));
342 f->setName(fieldName);
344 MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTS> fmts(MEDFileIntFieldMultiTS::New());
345 MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> f1ts(MEDFileIntField1TS::New());
347 f1ts->setFieldNoProfileSBT(f,daiPtr);
350 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dai2(daiPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
351 f1ts->setFieldNoProfileSBT(f,dai2);
353 fmts->pushBackTimeStep(f1ts);
357 else if(fieldName==FAMFIELD_FOR_CELLS && tf==ParaMEDMEM::ON_CELLS)
359 MEDFileMesh *mm(ms->getMeshWithName(mesh->getName()));
361 throw MZCException("AppendMCFieldFrom : internal error 3 !");
363 mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),daiPtr);
366 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dai2(daiPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
367 mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),dai2);
370 else if(fieldName==FAMFIELD_FOR_NODES || tf==ParaMEDMEM::ON_NODES)
372 MEDFileMesh *mm(ms->getMeshWithName(mesh->getName()));
374 throw MZCException("AppendMCFieldFrom : internal error 4 !");
376 mm->setFamilyFieldArr(1,daiPtr);
379 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dai2(daiPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end()));
380 mm->setFamilyFieldArr(1,dai2);
386 void PutAtLevelDealOrder(MEDFileData *mfd, int meshDimRel, const MicroField& mf)
389 throw MZCException("PutAtLevelDealOrder : internal error !");
390 MEDFileMesh *mm(mfd->getMeshes()->getMeshAtPos(0));
391 MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
393 throw MZCException("PutAtLevelDealOrder : internal error 2 !");
394 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(mf.getMesh());
395 mesh->setName(mfd->getMeshes()->getMeshAtPos(0)->getName());
396 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(mesh->sortCellsInMEDFileFrmt());
397 const DataArrayInt *o2nPtr(o2n);
398 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o;
399 mmu->setMeshAtLevel(meshDimRel,mesh);
400 const DataArrayInt *n2oPtr(0);
403 n2o=o2n->invertArrayO2N2N2O(mesh->getNumberOfCells());
405 if(n2oPtr && n2oPtr->isIdentity2(mesh->getNumberOfCells()))
408 mm->setRenumFieldArr(meshDimRel,n2o);
411 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cells(mf.getCellFields());
412 for(std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> >::const_iterator it=cells.begin();it!=cells.end();it++)
414 MEDCouplingAutoRefCountObjectPtr<DataArray> da(*it);
415 AppendMCFieldFrom(ParaMEDMEM::ON_CELLS,mesh,mfd,da,n2oPtr);
419 void AssignSingleGTMeshes(MEDFileData *mfd, const std::vector< MicroField >& ms)
422 throw MZCException("AssignSingleGTMeshes : internal error !");
423 MEDFileMesh *mm0(mfd->getMeshes()->getMeshAtPos(0));
424 MEDFileUMesh *mm(dynamic_cast<MEDFileUMesh *>(mm0));
426 throw MZCException("AssignSingleGTMeshes : internal error 2 !");
427 int meshDim(-std::numeric_limits<int>::max());
428 std::map<int, std::vector< MicroField > > ms2;
429 for(std::vector< MicroField >::const_iterator it=ms.begin();it!=ms.end();it++)
431 const MEDCouplingUMesh *elt((*it).getMesh());
434 int myMeshDim(elt->getMeshDimension());
435 meshDim=std::max(meshDim,myMeshDim);
436 ms2[myMeshDim].push_back(*it);
441 for(std::map<int, std::vector< MicroField > >::const_iterator it=ms2.begin();it!=ms2.end();it++)
443 const std::vector< MicroField >& vs((*it).second);
446 PutAtLevelDealOrder(mfd,(*it).first-meshDim,vs[0]);
450 MicroField merge(vs);
451 PutAtLevelDealOrder(mfd,(*it).first-meshDim,merge);
456 DataArrayDouble *BuildCoordsFrom(vtkPointSet *ds)
459 throw MZCException("BuildCoordsFrom : internal error !");
460 vtkPoints *pts(ds->GetPoints());
462 throw MZCException("BuildCoordsFrom : internal error 2 !");
463 vtkDataArray *data(pts->GetData());
465 throw MZCException("BuildCoordsFrom : internal error 3 !");
466 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(ConvertVTKArrayToMCArrayDouble(data));
467 return coords.retn();
470 void AddNodeFields(MEDFileData *mfd, vtkDataSetAttributes *dsa)
473 throw MZCException("AddNodeFields : internal error !");
474 MEDFileMesh *mm(mfd->getMeshes()->getMeshAtPos(0));
475 MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
477 throw MZCException("AddNodeFields : internal error 2 !");
478 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(mmu->getMeshAtLevel(0));
479 int nba(dsa->GetNumberOfArrays());
480 for(int i=0;i<nba;i++)
482 vtkDataArray *arr(dsa->GetArray(i));
483 const char *name(arr->GetName());
486 MEDCouplingAutoRefCountObjectPtr<DataArray> da(ConvertVTKArrayToMCArray(arr));
488 AppendMCFieldFrom(ParaMEDMEM::ON_NODES,mesh,mfd,da,0);
492 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > AddPartFields(const DataArrayInt *part, vtkDataSetAttributes *dsa)
494 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > ret;
497 int nba(dsa->GetNumberOfArrays());
498 for(int i=0;i<nba;i++)
500 vtkDataArray *arr(dsa->GetArray(i));
503 const char *name(arr->GetName());
504 int nbCompo(arr->GetNumberOfComponents());
505 vtkIdType nbTuples(arr->GetNumberOfTuples());
506 MEDCouplingAutoRefCountObjectPtr<DataArray> mcarr(ConvertVTKArrayToMCArray(arr));
508 mcarr=mcarr->selectByTupleId(part->begin(),part->end());
509 mcarr->setName(name);
510 ret.push_back(mcarr);
515 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > AddPartFields2(int bg, int end, vtkDataSetAttributes *dsa)
517 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > ret;
520 int nba(dsa->GetNumberOfArrays());
521 for(int i=0;i<nba;i++)
523 vtkDataArray *arr(dsa->GetArray(i));
526 const char *name(arr->GetName());
527 int nbCompo(arr->GetNumberOfComponents());
528 vtkIdType nbTuples(arr->GetNumberOfTuples());
529 MEDCouplingAutoRefCountObjectPtr<DataArray> mcarr(ConvertVTKArrayToMCArray(arr));
530 mcarr=mcarr->selectByTupleId2(bg,end,1);
531 mcarr->setName(name);
532 ret.push_back(mcarr);
537 void ConvertFromRectilinearGrid(MEDFileData *ret, vtkRectilinearGrid *ds, const std::vector<int>& context)
540 throw MZCException("ConvertFromRectilinearGrid : internal error !");
542 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> meshes(MEDFileMeshes::New());
543 ret->setMeshes(meshes);
544 MEDCouplingAutoRefCountObjectPtr<MEDFileFields> fields(MEDFileFields::New());
545 ret->setFields(fields);
547 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> cmesh(MEDFileCMesh::New());
548 meshes->pushMesh(cmesh);
549 MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cmeshmc(MEDCouplingCMesh::New());
550 vtkDataArray *cx(ds->GetXCoordinates()),*cy(ds->GetYCoordinates()),*cz(ds->GetZCoordinates());
553 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(ConvertVTKArrayToMCArrayDouble(cx));
554 cmeshmc->setCoordsAt(0,arr);
558 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(ConvertVTKArrayToMCArrayDouble(cy));
559 cmeshmc->setCoordsAt(1,arr);
563 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(ConvertVTKArrayToMCArrayDouble(cz));
564 cmeshmc->setCoordsAt(2,arr);
566 std::string meshName(GetMeshNameWithContext(context));
567 cmeshmc->setName(meshName);
568 cmesh->setMesh(cmeshmc);
569 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cellFs(AddPartFields(0,ds->GetCellData()));
570 for(std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> >::const_iterator it=cellFs.begin();it!=cellFs.end();it++)
572 MEDCouplingAutoRefCountObjectPtr<DataArray> da(*it);
573 AppendMCFieldFrom(ParaMEDMEM::ON_CELLS,cmeshmc,ret,da,0);
575 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > nodeFs(AddPartFields(0,ds->GetPointData()));
576 for(std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> >::const_iterator it=nodeFs.begin();it!=nodeFs.end();it++)
578 MEDCouplingAutoRefCountObjectPtr<DataArray> da(*it);
579 AppendMCFieldFrom(ParaMEDMEM::ON_NODES,cmeshmc,ret,da,0);
583 void ConvertFromPolyData(MEDFileData *ret, vtkPolyData *ds, const std::vector<int>& context)
586 throw MZCException("ConvertFromPolyData : internal error !");
588 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> meshes(MEDFileMeshes::New());
589 ret->setMeshes(meshes);
590 MEDCouplingAutoRefCountObjectPtr<MEDFileFields> fields(MEDFileFields::New());
591 ret->setFields(fields);
593 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> umesh(MEDFileUMesh::New());
594 meshes->pushMesh(umesh);
595 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(BuildCoordsFrom(ds));
596 umesh->setCoords(coords);
597 umesh->setName(GetMeshNameWithContext(context));
600 std::vector< MicroField > ms;
601 vtkCellArray *cd(ds->GetVerts());
604 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh(BuildMeshFromCellArray(cd,coords,0,INTERP_KERNEL::NORM_POINT1));
605 if((const MEDCouplingUMesh *)subMesh)
607 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cellFs(AddPartFields2(offset,offset+subMesh->getNumberOfCells(),ds->GetCellData()));
608 offset+=subMesh->getNumberOfCells();
609 ms.push_back(MicroField(subMesh,cellFs));
612 vtkCellArray *cc(ds->GetLines());
615 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh(BuildMeshFromCellArray(cc,coords,1,INTERP_KERNEL::NORM_SEG2));
616 if((const MEDCouplingUMesh *)subMesh)
618 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cellFs(AddPartFields2(offset,offset+subMesh->getNumberOfCells(),ds->GetCellData()));
619 offset+=subMesh->getNumberOfCells();
620 ms.push_back(MicroField(subMesh,cellFs));
623 vtkCellArray *cb(ds->GetPolys());
626 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh(BuildMeshFromCellArray(cb,coords,2,INTERP_KERNEL::NORM_POLYGON));
627 if((const MEDCouplingUMesh *)subMesh)
629 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cellFs(AddPartFields2(offset,offset+subMesh->getNumberOfCells(),ds->GetCellData()));
630 offset+=subMesh->getNumberOfCells();
631 ms.push_back(MicroField(subMesh,cellFs));
634 vtkCellArray *ca(ds->GetStrips());
637 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids;
638 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh(BuildMeshFromCellArrayTriangleStrip(ca,coords,ids));
639 if((const MEDCouplingUMesh *)subMesh)
641 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cellFs(AddPartFields(ids,ds->GetCellData()));
642 offset+=subMesh->getNumberOfCells();
643 ms.push_back(MicroField(subMesh,cellFs));
646 AssignSingleGTMeshes(ret,ms);
647 AddNodeFields(ret,ds->GetPointData());
650 void ConvertFromUnstructuredGrid(MEDFileData *ret, vtkUnstructuredGrid *ds, const std::vector<int>& context)
653 throw MZCException("ConvertFromUnstructuredGrid : internal error !");
655 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> meshes(MEDFileMeshes::New());
656 ret->setMeshes(meshes);
657 MEDCouplingAutoRefCountObjectPtr<MEDFileFields> fields(MEDFileFields::New());
658 ret->setFields(fields);
660 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> umesh(MEDFileUMesh::New());
661 meshes->pushMesh(umesh);
662 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(BuildCoordsFrom(ds));
663 umesh->setCoords(coords);
664 umesh->setName(GetMeshNameWithContext(context));
665 vtkIdType nbCells(ds->GetNumberOfCells());
666 vtkCellArray *ca(ds->GetCells());
669 vtkIdType nbEnt(ca->GetNumberOfConnectivityEntries());
670 vtkIdType *caPtr(ca->GetPointer());
671 vtkUnsignedCharArray *ct(ds->GetCellTypesArray());
673 throw MZCException("ConvertFromUnstructuredGrid : internal error");
674 vtkIdTypeArray *cla(ds->GetCellLocationsArray());
675 const vtkIdType *claPtr(cla->GetPointer(0));
677 throw MZCException("ConvertFromUnstructuredGrid : internal error 2");
678 const unsigned char *ctPtr(ct->GetPointer(0));
679 std::map<int,int> m(ComputeMapOfType());
680 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> lev(DataArrayInt::New()) ; lev->alloc(nbCells,1);
681 int *levPtr(lev->getPointer());
682 for(vtkIdType i=0;i<nbCells;i++)
684 std::map<int,int>::iterator it(m.find(ctPtr[i]));
687 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)(*it).second));
688 levPtr[i]=cm.getDimension();
692 std::ostringstream oss; oss << "ConvertFromUnstructuredGrid : at pos #" << i << " unrecognized VTK cell with type =" << ctPtr[i];
693 throw MZCException(oss.str());
697 int meshDim(lev->getMaxValue(dummy));
698 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> levs(lev->getDifferentValues());
699 std::vector< MicroField > ms;
700 vtkIdTypeArray *faces(ds->GetFaces()),*faceLoc(ds->GetFaceLocations());
701 for(const int *curLev=levs->begin();curLev!=levs->end();curLev++)
703 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(MEDCouplingUMesh::New("",*curLev));
704 m0->setCoords(coords); m0->allocateCells();
705 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsCurLev(lev->getIdsEqual(*curLev));
706 for(const int *cellId=cellIdsCurLev->begin();cellId!=cellIdsCurLev->end();cellId++)
708 std::map<int,int>::iterator it(m.find(ctPtr[*cellId]));
709 vtkIdType offset(claPtr[*cellId]);
710 vtkIdType sz(caPtr[offset]);
711 INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)(*it).second);
712 if(ct!=INTERP_KERNEL::NORM_POLYHED)
713 m0->insertNextCell(ct,sz,caPtr+offset+1);
716 if(!faces || !faceLoc)
717 throw MZCException("ConvertFromUnstructuredGrid : faces are expected when there are polyhedra !");
718 const vtkIdType *facPtr(faces->GetPointer(0)),*facLocPtr(faceLoc->GetPointer(0));
719 std::vector<int> conn;
720 int off0(facLocPtr[*cellId]);
721 int nbOfFaces(facPtr[off0++]);
722 for(int k=0;k<nbOfFaces;k++)
724 int nbOfNodesInFace(facPtr[off0++]);
725 std::copy(facPtr+off0,facPtr+off0+nbOfNodesInFace,std::back_inserter(conn));
726 off0+=nbOfNodesInFace;
730 m0->insertNextCell(ct,conn.size(),&conn[0]);
733 std::vector<MEDCouplingAutoRefCountObjectPtr<DataArray> > cellFs(AddPartFields(cellIdsCurLev,ds->GetCellData()));
734 ms.push_back(MicroField(m0,cellFs));
736 AssignSingleGTMeshes(ret,ms);
737 AddNodeFields(ret,ds->GetPointData());
742 vtkMEDWriter::vtkMEDWriter():WriteAllTimeSteps(0),FileName(0),IsTouched(false)
746 vtkMEDWriter::~vtkMEDWriter()
750 vtkInformationDataObjectMetaDataKey *GetMEDReaderMetaDataIfAny()
752 static const char ZE_KEY[]="vtkMEDReader::META_DATA";
753 ParaMEDMEM::GlobalDict *gd(ParaMEDMEM::GlobalDict::GetInstance());
754 if(!gd->hasKey(ZE_KEY))
756 std::string ptSt(gd->value(ZE_KEY));
758 std::istringstream iss(ptSt); iss >> pt;
759 return reinterpret_cast<vtkInformationDataObjectMetaDataKey *>(pt);
762 bool IsInformationOK(vtkInformation *info)
764 vtkInformationDataObjectMetaDataKey *key(GetMEDReaderMetaDataIfAny());
767 // Check the information contain meta data key
771 vtkMutableDirectedGraph *sil(vtkMutableDirectedGraph::SafeDownCast(info->Get(key)));
775 vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
776 vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
779 for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
781 vtkStdString &st(verticesNames2->GetValue(i));
782 if(st=="MeshesFamsGrps")
791 Grp(const std::string& name):_name(name) { }
792 void setFamilies(const std::vector<std::string>& fams) { _fams=fams; }
793 std::string getName() const { return _name; }
794 std::vector<std::string> getFamilies() const { return _fams; }
797 std::vector<std::string> _fams;
803 Fam(const std::string& name)
805 static const char ZE_SEP[]="@@][@@";
806 std::size_t pos(name.find(ZE_SEP));
807 std::string name0(name.substr(0,pos)),name1(name.substr(pos+strlen(ZE_SEP)));
808 std::istringstream iss(name1);
812 std::string getName() const { return _name; }
813 int getID() const { return _id; }
819 void LoadFamGrpMapInfo(vtkMutableDirectedGraph *sil, std::string& meshName, std::vector<Grp>& groups, std::vector<Fam>& fams)
822 throw MZCException("LoadFamGrpMapInfo : internal error !");
824 vtkAbstractArray *verticesNames(sil->GetVertexData()->GetAbstractArray("Names",idNames));
825 vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
828 for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
830 vtkStdString &st(verticesNames2->GetValue(i));
831 if(st=="MeshesFamsGrps")
838 throw INTERP_KERNEL::Exception("There is an internal error ! The tree on server side has not the expected look !");
839 vtkAdjacentVertexIterator *it0(vtkAdjacentVertexIterator::New());
840 sil->GetAdjacentVertices(id0,it0);
842 while(it0->HasNext())
844 vtkIdType id1(it0->Next());
845 std::string mName((const char *)verticesNames2->GetValue(id1));
847 vtkAdjacentVertexIterator *it1(vtkAdjacentVertexIterator::New());
848 sil->GetAdjacentVertices(id1,it1);
849 vtkIdType idZeGrps(it1->Next());//zeGroups
850 vtkAdjacentVertexIterator *itGrps(vtkAdjacentVertexIterator::New());
851 sil->GetAdjacentVertices(idZeGrps,itGrps);
852 while(itGrps->HasNext())
854 vtkIdType idg(itGrps->Next());
855 Grp grp((const char *)verticesNames2->GetValue(idg));
856 vtkAdjacentVertexIterator *itGrps2(vtkAdjacentVertexIterator::New());
857 sil->GetAdjacentVertices(idg,itGrps2);
858 std::vector<std::string> famsOnGroup;
859 while(itGrps2->HasNext())
861 vtkIdType idgf(itGrps2->Next());
862 famsOnGroup.push_back(std::string((const char *)verticesNames2->GetValue(idgf)));
864 grp.setFamilies(famsOnGroup);
866 groups.push_back(grp);
869 vtkIdType idZeFams(it1->Next());//zeFams
871 vtkAdjacentVertexIterator *itFams(vtkAdjacentVertexIterator::New());
872 sil->GetAdjacentVertices(idZeFams,itFams);
873 while(itFams->HasNext())
875 vtkIdType idf(itFams->Next());
876 Fam fam((const char *)verticesNames2->GetValue(idf));
884 int vtkMEDWriter::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
886 //std::cerr << "########################################## vtkMEDWriter::RequestInformation ########################################## " << (const char *) this->FileName << std::endl;
890 void WriteMEDFileFromVTKDataSet(MEDFileData *mfd, vtkDataSet *ds, const std::vector<int>& context)
893 throw MZCException("Internal error in WriteMEDFileFromVTKDataSet.");
894 vtkPolyData *ds2(vtkPolyData::SafeDownCast(ds));
895 vtkUnstructuredGrid *ds3(vtkUnstructuredGrid::SafeDownCast(ds));
896 vtkRectilinearGrid *ds4(vtkRectilinearGrid::SafeDownCast(ds));
899 ConvertFromPolyData(mfd,ds2,context);
903 ConvertFromUnstructuredGrid(mfd,ds3,context);
907 ConvertFromRectilinearGrid(mfd,ds4,context);
910 throw MZCException("Unrecognized vtkDataSet ! Sorry ! Try to convert it to UnstructuredGrid to be able to write it !");
913 void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, const std::vector<int>& context)
916 throw MZCException("Internal error in WriteMEDFileFromVTKMultiBlock.");
917 int nbBlocks(ds->GetNumberOfBlocks());
918 if(nbBlocks==1 && context.empty())
920 vtkDataObject *uniqueElt(ds->GetBlock(0));
922 throw MZCException("Unique elt in multiblock is NULL !");
923 vtkDataSet *uniqueEltc(vtkDataSet::SafeDownCast(uniqueElt));
926 WriteMEDFileFromVTKDataSet(mfd,uniqueEltc,context);
930 for(int i=0;i<nbBlocks;i++)
932 vtkDataObject *elt(ds->GetBlock(i));
933 std::vector<int> context2;
934 context2.push_back(i);
937 std::ostringstream oss; oss << "In context ";
938 std::copy(context.begin(),context.end(),std::ostream_iterator<int>(oss," "));
939 oss << " at pos #" << i << " elt is NULL !";
940 throw MZCException(oss.str());
942 vtkDataSet *elt1(vtkDataSet::SafeDownCast(elt));
945 WriteMEDFileFromVTKDataSet(mfd,elt1,context);
948 vtkMultiBlockDataSet *elt2(vtkMultiBlockDataSet::SafeDownCast(elt));
951 WriteMEDFileFromVTKMultiBlock(mfd,elt2,context);
954 std::ostringstream oss; oss << "In context ";
955 std::copy(context.begin(),context.end(),std::ostream_iterator<int>(oss," "));
956 oss << " at pos #" << i << " elt not recognized data type !";
957 throw MZCException(oss.str());
961 void WriteMEDFileFromVTKGDS(MEDFileData *mfd, vtkDataObject *input)
964 throw MZCException("WriteMEDFileFromVTKGDS : internal error !");
965 std::vector<int> context;
966 vtkDataSet *input1(vtkDataSet::SafeDownCast(input));
969 WriteMEDFileFromVTKDataSet(mfd,input1,context);
972 vtkMultiBlockDataSet *input2(vtkMultiBlockDataSet::SafeDownCast(input));
975 WriteMEDFileFromVTKMultiBlock(mfd,input2,context);
978 throw MZCException("WriteMEDFileFromVTKGDS : not recognized data type !");
981 void PutFamGrpInfoIfAny(MEDFileData *mfd, const std::string& meshName, const std::vector<Grp>& groups, const std::vector<Fam>& fams)
987 MEDFileMeshes *meshes(mfd->getMeshes());
990 if(meshes->getNumberOfMeshes()!=1)
992 MEDFileMesh *mm(meshes->getMeshAtPos(0));
995 mm->setName(meshName);
996 for(std::vector<Fam>::const_iterator it=fams.begin();it!=fams.end();it++)
997 mm->setFamilyId((*it).getName(),(*it).getID());
998 for(std::vector<Grp>::const_iterator it=groups.begin();it!=groups.end();it++)
999 mm->setFamiliesOnGroup((*it).getName(),(*it).getFamilies());
1000 MEDFileFields *fields(mfd->getFields());
1003 for(int i=0;i<fields->getNumberOfFields();i++)
1005 MEDFileAnyTypeFieldMultiTS *fmts(fields->getFieldAtPos(i));
1008 fmts->setMeshName(meshName);
1012 int vtkMEDWriter::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
1014 //std::cerr << "########################################## vtkMEDWriter::RequestData ########################################## " << (const char *) this->FileName << std::endl;
1017 vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0));
1018 std::string meshName;
1019 std::vector<Grp> groups; std::vector<Fam> fams;
1020 if(IsInformationOK(inputInfo))
1022 vtkMutableDirectedGraph *famGrpGraph(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(GetMEDReaderMetaDataIfAny())));
1023 LoadFamGrpMapInfo(famGrpGraph,meshName,groups,fams);
1025 vtkInformation *outInfo(outputVector->GetInformationObject(0));
1026 vtkDataObject *input(vtkDataObject::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
1028 throw MZCException("Not recognized data object in input of the MEDWriter ! Maybe not implemented yet !");
1029 MEDCouplingAutoRefCountObjectPtr<MEDFileData> mfd(MEDFileData::New());
1030 WriteMEDFileFromVTKGDS(mfd,input);
1031 PutFamGrpInfoIfAny(mfd,meshName,groups,fams);
1032 mfd->write(this->FileName,this->IsTouched?0:2); this->IsTouched=true;
1033 outInfo->Set(vtkDataObject::DATA_OBJECT(),input);
1035 catch(MZCException& e)
1037 std::ostringstream oss;
1038 oss << "Exception has been thrown in vtkMEDWriter::RequestData : During writing of \"" << (const char *) this->FileName << "\", the following exception has been thrown : "<< e.what() << std::endl;
1039 if(this->HasObserver("ErrorEvent") )
1040 this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
1042 vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
1043 vtkObject::BreakOnError();
1049 void vtkMEDWriter::PrintSelf(ostream& os, vtkIndent indent)
1051 this->Superclass::PrintSelf(os, indent);
1054 int vtkMEDWriter::Write()