From 6de6f121f84633e54af8c30b2be908349c9240ed Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Mon, 4 Sep 2017 11:03:36 +0200 Subject: [PATCH] Management of float32 in MEDReader + multi timestep is MEDWriter --- .../IO/MEDFileFieldRepresentationTree.cxx | 190 ++++++----- .../IO/MEDFileFieldRepresentationTree.hxx | 9 +- src/Plugins/MEDWriter/IO/vtkMEDWriter.cxx | 294 ++++++++++++------ src/Plugins/MEDWriter/IO/vtkMEDWriter.h | 6 +- 4 files changed, 311 insertions(+), 188 deletions(-) diff --git a/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx b/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx index d87827ac..983c753a 100644 --- a/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx +++ b/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx @@ -46,6 +46,7 @@ #include "vtkIdTypeArray.h" #include "vtkDoubleArray.h" #include "vtkIntArray.h" +#include "vtkFloatArray.h" #include "vtkCellArray.h" #include "vtkPointData.h" #include "vtkFieldData.h" @@ -77,7 +78,8 @@ const char MEDFileFieldRepresentationTree::ROOT_OF_FAM_IDS_IN_TREE[]="zeFamIds"; const char MEDFileFieldRepresentationTree::COMPO_STR_TO_LOCATE_MESH_DA[]="-@?|*_"; -vtkIdTypeArray *ELGACmp::findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds, bool& isNew, ExportedTinyInfo *internalInfo) const +template +vtkIdTypeArray *ELGACmp::findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDataArray *vtkd, vtkDataSet *ds, bool& isNew, ExportedTinyInfo *internalInfo) const { vtkIdTypeArray *try0(isExisting(locsReallyUsed,vtkd)); if(try0) @@ -88,11 +90,11 @@ vtkIdTypeArray *ELGACmp::findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal * else { isNew=true; - return createNew(globs,locsReallyUsed,vtkd,ds,internalInfo); + return createNew(globs,locsReallyUsed,vtkd,ds,internalInfo); } } -vtkIdTypeArray *ELGACmp::isExisting(const std::vector& locsReallyUsed, vtkDoubleArray *vtkd) const +vtkIdTypeArray *ELGACmp::isExisting(const std::vector& locsReallyUsed, vtkDataArray *vtkd) const { std::vector< std::vector >::iterator it(std::find(_loc_names.begin(),_loc_names.end(),locsReallyUsed)); if(it==_loc_names.end()) @@ -108,9 +110,10 @@ vtkIdTypeArray *ELGACmp::isExisting(const std::vector& locsReallyUs return ret; } -vtkIdTypeArray *ELGACmp::createNew(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds, ExportedTinyInfo *internalInfo) const +template +vtkIdTypeArray *ELGACmp::createNew(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDataArray *vtkd, vtkDataSet *ds, ExportedTinyInfo *internalInfo) const { - const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate::VTK_DATA_ARRAY_DELETE; + const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate::VTK_DATA_ARRAY_DELETE; std::vector< std::vector > locNames(_loc_names); std::vector elgas(_elgas); std::vector< std::pair< vtkQuadratureSchemeDefinition *, unsigned char > > defs; @@ -216,6 +219,14 @@ public: typedef MEDCoupling::DataArrayInt MCType; }; +template<> +class MEDFileVTKTraits +{ +public: + typedef vtkFloatArray VtkType; + typedef MEDCoupling::DataArrayFloat MCType; +}; + template<> class MEDFileVTKTraits { @@ -241,6 +252,84 @@ void AssignDataPointerOther(VTKT *vtkTab, MCT *mcTab, int nbElems) mcTab->accessToMemArray().setSpecificDeallocator(0); } +template +void AssignToFieldData(DataArray *vPtr, const MEDTimeReq *tr, vtkFieldData *att, const std::string& crudeName, bool noCpyNumNodes, + const std::vector& discs, const ELGACmp& elgaCmp, const MEDCoupling::MEDFileFieldGlobsReal *globs, + MEDFileAnyTypeField1TS *f1ts, vtkDataSet *ds, ExportedTinyInfo *internalInfo) +{ + const int VTK_DATA_ARRAY_DELETE=vtkDataArrayTemplate::VTK_DATA_ARRAY_DELETE; + typename MEDFileVTKTraits::MCType *vi(static_cast::MCType *>(vPtr)); + typename MEDFileVTKTraits::VtkType *vtkd(MEDFileVTKTraits::VtkType::New()); + vtkd->SetNumberOfComponents(vi->getNumberOfComponents()); + for(int i=0;igetNumberOfComponents();i++) + vtkd->SetComponentName(i,vi->getVarOnComponent(i).c_str()); + AssignDataPointerToVTK(vtkd,vi,noCpyNumNodes); + std::string name(tr->buildName(crudeName)); + vtkd->SetName(name.c_str()); + att->AddArray(vtkd); + vtkd->Delete(); + if(discs[0]==ON_GAUSS_PT) + { + bool tmp; + elgaCmp.findOrCreate(globs,f1ts->getLocsReallyUsed(),vtkd,ds,tmp,internalInfo); + } + if(discs[0]==ON_GAUSS_NE) + { + vtkIdTypeArray *elno(vtkIdTypeArray::New()); + elno->SetNumberOfComponents(1); + vtkIdType ncell(ds->GetNumberOfCells()); + int *pt(new int[ncell]),offset(0); + std::set cellTypes; + for(vtkIdType cellId=0;cellIdGetCell(cellId)); + int delta(cell->GetNumberOfPoints()); + cellTypes.insert(cell->GetCellType()); + pt[cellId]=offset; + offset+=delta; + } + elno->GetInformation()->Set(MEDUtilities::ELNO(),1); + elno->SetVoidArray(pt,ncell,0,VTK_DATA_ARRAY_DELETE); + std::string nameElno("ELNO"); nameElno+="@"; nameElno+=name; + elno->SetName(nameElno.c_str()); + ds->GetCellData()->AddArray(elno); + vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),elno->GetName()); + elno->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(),1); + // + vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY()); + for(std::set::const_iterator it=cellTypes.begin();it!=cellTypes.end();it++) + { + const unsigned char *pos(std::find(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH,*it)); + if(pos==MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH) + continue; + INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)std::distance(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,pos)); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(ct)); + int nbGaussPt(cm.getNumberOfNodes()),dim(cm.getDimension()); + vtkQuadratureSchemeDefinition *def(vtkQuadratureSchemeDefinition::New()); + double *shape(new double[nbGaussPt*nbGaussPt]); + std::size_t dummy; + const double *gsCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy));//GetLocsFromGeometricType + const double *refCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy)); + const double *weights(MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType(ct,dummy)); + std::vector gsCoords2(gsCoords,gsCoords+nbGaussPt*dim),refCoords2(refCoords,refCoords+nbGaussPt*dim); + INTERP_KERNEL::GaussInfo calculator(ct,gsCoords2,nbGaussPt,refCoords2,nbGaussPt); + calculator.initLocalInfo(); + for(int i=0;iInitialize(*it,nbGaussPt,nbGaussPt,shape,const_cast(weights)); + delete [] shape; + key->Set(elno->GetInformation(),def,*it); + key->Set(vtkd->GetInformation(),def,*it); + def->Delete(); + } + // + elno->Delete(); + } +} + //= MEDFileFieldRepresentationLeavesArrays::MEDFileFieldRepresentationLeavesArrays():_id(-1) @@ -330,13 +419,16 @@ void MEDFileFieldRepresentationLeavesArrays::appendFields(const MEDTimeReq *tr, MEDFileAnyTypeField1TS *f1tsPtr(f1ts); MEDFileField1TS *f1tsPtrDbl(dynamic_cast(f1tsPtr)); MEDFileIntField1TS *f1tsPtrInt(dynamic_cast(f1tsPtr)); + MEDFileFloatField1TS *f1tsPtrFloat(dynamic_cast(f1tsPtr)); DataArray *crudeArr(0),*postProcessedArr(0); if(f1tsPtrDbl) crudeArr=f1tsPtrDbl->getUndergroundDataArray(); else if(f1tsPtrInt) crudeArr=f1tsPtrInt->getUndergroundDataArray(); + else if(f1tsPtrFloat) + crudeArr=f1tsPtrFloat->getUndergroundDataArray(); else - throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64 and INT32 fields are dealt for the moment !"); + throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64, FLOAT32 and INT32 fields are dealt for the moment !"); MEDFileField1TSStructItem fsst(MEDFileField1TSStructItem::BuildItemFrom(f1ts,mst)); f1ts->loadArraysIfNecessary(); MCAuto v(mml->buildDataArray(fsst,globs,crudeArr)); @@ -373,89 +465,15 @@ void MEDFileFieldRepresentationLeavesArrays::appendFields(const MEDTimeReq *tr, } if(f1tsPtrDbl) { - DataArray *vPtr(v); DataArrayDouble *vd(static_cast(vPtr)); - vtkDoubleArray *vtkd(vtkDoubleArray::New()); - vtkd->SetNumberOfComponents(vd->getNumberOfComponents()); - for(int i=0;igetNumberOfComponents();i++) - vtkd->SetComponentName(i,vd->getInfoOnComponent(i).c_str()); - AssignDataPointerToVTK(vtkd,vd,postProcessedArr==crudeArr); - std::string name(tr->buildName(f1ts->getName())); - vtkd->SetName(name.c_str()); - att->AddArray(vtkd); - vtkd->Delete(); - if(discs[0]==ON_GAUSS_PT) - { - bool tmp; - _elga_cmp.findOrCreate(globs,f1ts->getLocsReallyUsed(),vtkd,ds,tmp,internalInfo); - } - if(discs[0]==ON_GAUSS_NE) - { - vtkIdTypeArray *elno(vtkIdTypeArray::New()); - elno->SetNumberOfComponents(1); - vtkIdType ncell(ds->GetNumberOfCells()); - int *pt(new int[ncell]),offset(0); - std::set cellTypes; - for(vtkIdType cellId=0;cellIdGetCell(cellId)); - int delta(cell->GetNumberOfPoints()); - cellTypes.insert(cell->GetCellType()); - pt[cellId]=offset; - offset+=delta; - } - elno->GetInformation()->Set(MEDUtilities::ELNO(),1); - elno->SetVoidArray(pt,ncell,0,VTK_DATA_ARRAY_DELETE); - std::string nameElno("ELNO"); nameElno+="@"; nameElno+=name; - elno->SetName(nameElno.c_str()); - ds->GetCellData()->AddArray(elno); - vtkd->GetInformation()->Set(vtkQuadratureSchemeDefinition::QUADRATURE_OFFSET_ARRAY_NAME(),elno->GetName()); - elno->GetInformation()->Set(vtkAbstractArray::GUI_HIDE(),1); - // - vtkInformationQuadratureSchemeDefinitionVectorKey *key(vtkQuadratureSchemeDefinition::DICTIONARY()); - for(std::set::const_iterator it=cellTypes.begin();it!=cellTypes.end();it++) - { - const unsigned char *pos(std::find(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH,*it)); - if(pos==MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE+MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH) - continue; - INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)std::distance(MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE,pos)); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(ct)); - int nbGaussPt(cm.getNumberOfNodes()),dim(cm.getDimension()); - vtkQuadratureSchemeDefinition *def(vtkQuadratureSchemeDefinition::New()); - double *shape(new double[nbGaussPt*nbGaussPt]); - std::size_t dummy; - const double *gsCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy));//GetLocsFromGeometricType - const double *refCoords(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(ct,dummy)); - const double *weights(MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType(ct,dummy)); - std::vector gsCoords2(gsCoords,gsCoords+nbGaussPt*dim),refCoords2(refCoords,refCoords+nbGaussPt*dim); - INTERP_KERNEL::GaussInfo calculator(ct,gsCoords2,nbGaussPt,refCoords2,nbGaussPt); - calculator.initLocalInfo(); - for(int i=0;iInitialize(*it,nbGaussPt,nbGaussPt,shape,const_cast(weights)); - delete [] shape; - key->Set(elno->GetInformation(),def,*it); - key->Set(vtkd->GetInformation(),def,*it); - def->Delete(); - } - // - elno->Delete(); - } + AssignToFieldData(v,tr,att,f1ts->getName(),postProcessedArr==crudeArr,discs,_elga_cmp,globs,f1ts,ds,internalInfo); } else if(f1tsPtrInt) { - DataArray *vPtr(v); DataArrayInt *vi(static_cast(vPtr)); - vtkIntArray *vtkd(vtkIntArray::New()); - vtkd->SetNumberOfComponents(vi->getNumberOfComponents()); - for(int i=0;igetNumberOfComponents();i++) - vtkd->SetComponentName(i,vi->getVarOnComponent(i).c_str()); - AssignDataPointerToVTK(vtkd,vi,postProcessedArr==crudeArr); - std::string name(tr->buildName(f1ts->getName())); - vtkd->SetName(name.c_str()); - att->AddArray(vtkd); - vtkd->Delete(); + AssignToFieldData(v,tr,att,f1ts->getName(),postProcessedArr==crudeArr,discs,_elga_cmp,globs,f1ts,ds,internalInfo); + } + else if(f1tsPtrFloat) + { + AssignToFieldData(v,tr,att,f1ts->getName(),postProcessedArr==crudeArr,discs,_elga_cmp,globs,f1ts,ds,internalInfo); } else throw INTERP_KERNEL::Exception("MEDFileFieldRepresentationLeavesArrays::appendFields : only FLOAT64 and INT32 fields are dealt for the moment ! Internal Error !"); diff --git a/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.hxx b/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.hxx index 47ba43ad..be6da385 100644 --- a/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.hxx +++ b/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.hxx @@ -38,6 +38,7 @@ class vtkStructuredGrid; class vtkVariantArray; class vtkIdTypeArray; class vtkDoubleArray; +class vtkDataArray; class vtkDataSet; class TimeKeeper; @@ -47,12 +48,14 @@ class ExportedTinyInfo; class ELGACmp { public: - vtkIdTypeArray *findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds, bool& isNew, ExportedTinyInfo *internalInfo) const; + template + vtkIdTypeArray *findOrCreate(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDataArray *vtkd, vtkDataSet *ds, bool& isNew, ExportedTinyInfo *internalInfo) const; void appendELGAIfAny(vtkDataSet *ds) const; ~ELGACmp(); private: - vtkIdTypeArray *isExisting(const std::vector& locsReallyUsed, vtkDoubleArray *vtkd) const; - vtkIdTypeArray *createNew(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDoubleArray *vtkd, vtkDataSet *ds, ExportedTinyInfo *internalInfo) const; + vtkIdTypeArray *isExisting(const std::vector& locsReallyUsed, vtkDataArray *vtkd) const; + template + vtkIdTypeArray *createNew(const MEDCoupling::MEDFileFieldGlobsReal *globs, const std::vector& locsReallyUsed, vtkDataArray *vtkd, vtkDataSet *ds, ExportedTinyInfo *internalInfo) const; private: //! size of _loc_names is equal to _elgas. mutable std::vector< std::vector > _loc_names; diff --git a/src/Plugins/MEDWriter/IO/vtkMEDWriter.cxx b/src/Plugins/MEDWriter/IO/vtkMEDWriter.cxx index 8b1b1230..eaf455e9 100644 --- a/src/Plugins/MEDWriter/IO/vtkMEDWriter.cxx +++ b/src/Plugins/MEDWriter/IO/vtkMEDWriter.cxx @@ -62,8 +62,10 @@ #include "MEDFileData.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldInt.hxx" +#include "MEDCouplingFieldFloat.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingRefCountObject.hxx" +#include "MEDLoaderTraits.hxx" #include #include @@ -83,13 +85,17 @@ using MEDCoupling::MEDFileFieldMultiTS; using MEDCoupling::MEDFileAnyTypeFieldMultiTS; using MEDCoupling::DataArray; using MEDCoupling::DataArrayInt; +using MEDCoupling::DataArrayFloat; using MEDCoupling::DataArrayDouble; using MEDCoupling::MEDCouplingMesh; using MEDCoupling::MEDCouplingUMesh; using MEDCoupling::MEDCouplingCMesh; using MEDCoupling::MEDCouplingFieldDouble; +using MEDCoupling::MEDCouplingFieldFloat; using MEDCoupling::MEDCouplingFieldInt; using MEDCoupling::MCAuto; +using MEDCoupling::Traits; +using MEDCoupling::MLFieldTraits; vtkStandardNewMacro(vtkMEDWriter); @@ -105,6 +111,38 @@ private: std::string _reason; }; +template +class MEDFileVTKTraits +{ +public: + typedef void VtkType; + typedef void MCType; +}; + +template<> +class MEDFileVTKTraits +{ +public: + typedef vtkIntArray VtkType; + typedef MEDCoupling::DataArrayInt MCType; +}; + +template<> +class MEDFileVTKTraits +{ +public: + typedef vtkFloatArray VtkType; + typedef MEDCoupling::DataArrayFloat MCType; +}; + +template<> +class MEDFileVTKTraits +{ +public: + typedef vtkDoubleArray VtkType; + typedef MEDCoupling::DataArrayDouble MCType; +}; + /////////////////// std::map ComputeMapOfType() @@ -172,49 +210,71 @@ DataArrayInt *ConvertVTKArrayToMCArrayInt(vtkDataArray *data) throw MZCException(oss.str()); } -DataArrayDouble *ConvertVTKArrayToMCArrayDouble(vtkDataArray *data) +template +typename Traits::ArrayType *ConvertVTKArrayToMCArrayDouble(vtkDataArray *data) { if(!data) throw MZCException("ConvertVTKArrayToMCArrayDouble : internal error !"); int nbTuples(data->GetNumberOfTuples()),nbComp(data->GetNumberOfComponents()); std::size_t nbElts(nbTuples*nbComp); - MCAuto ret(DataArrayDouble::New()); + MCAuto< typename Traits::ArrayType > ret(Traits::ArrayType::New()); ret->alloc(nbTuples,nbComp); for(int i=0;iGetComponentName(i)); if(comp) ret->setInfoOnComponent(i,comp); + else + { + if(nbComp>1 && nbComp<=3) + { + char tmp[2]; + tmp[0]='X'+i; tmp[1]='\0'; + ret->setInfoOnComponent(i,tmp); + } + } } - double *ptOut(ret->getPointer()); - vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data)); + T *ptOut(ret->getPointer()); + typename MEDFileVTKTraits::VtkType *d0(MEDFileVTKTraits::VtkType::SafeDownCast(data)); if(d0) { - const float *pt(d0->GetPointer(0)); + const T *pt(d0->GetPointer(0)); for(std::size_t i=0;iGetPointer(0)); - std::copy(pt,pt+nbElts,ptOut); + ptOut[i]=(T)pt[i]; return ret.retn(); } std::ostringstream oss; - oss << "ConvertVTKArrayToMCArrayDouble : unrecognized array \"" << typeid(*data).name() << "\" type !"; + oss << "ConvertVTKArrayToMCArrayDouble : unrecognized array \"" << data->GetClassName() << "\" type !"; throw MZCException(oss.str()); } +DataArrayDouble *ConvertVTKArrayToMCArrayDoubleForced(vtkDataArray *data) +{ + if(!data) + throw MZCException("ConvertVTKArrayToMCArrayDoubleForced : internal error 0 !"); + vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data)); + if(d0) + { + MCAuto ret(ConvertVTKArrayToMCArrayDouble(data)); + MCAuto ret2(ret->convertToDblArr()); + return ret2.retn(); + } + vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data)); + if(d1) + return ConvertVTKArrayToMCArrayDouble(data); + throw MZCException("ConvertVTKArrayToMCArrayDoubleForced : unrecognized type of data for double !"); +} + DataArray *ConvertVTKArrayToMCArray(vtkDataArray *data) { if(!data) throw MZCException("ConvertVTKArrayToMCArray : internal error !"); vtkFloatArray *d0(vtkFloatArray::SafeDownCast(data)); + if(d0) + return ConvertVTKArrayToMCArrayDouble(data); vtkDoubleArray *d1(vtkDoubleArray::SafeDownCast(data)); - if(d0 || d1) - return ConvertVTKArrayToMCArrayDouble(data); + if(d1) + return ConvertVTKArrayToMCArrayDouble(data); vtkIntArray *d2(vtkIntArray::SafeDownCast(data)); vtkLongArray *d3(vtkLongArray::SafeDownCast(data)); vtkUnsignedCharArray *d4(vtkUnsignedCharArray::SafeDownCast(data)); @@ -322,7 +382,29 @@ MicroField::MicroField(const std::vector< MicroField >& vs) _m=MEDCouplingUMesh::MergeUMeshesOnSameCoords(vs2); } -void AppendMCFieldFrom(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, MEDFileData *mfd, MCAuto da, const DataArrayInt *n2oPtr) +template +void AppendToFields(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, const DataArrayInt *n2oPtr, typename MEDFileVTKTraits::MCType *dadPtr, MEDFileFields *fs, double timeStep, int tsId) +{ + std::string fieldName(dadPtr->getName()); + MCAuto< typename Traits::FieldType > f(Traits::FieldType::New(tf)); + f->setTime(timeStep,tsId,0); + f->setName(fieldName); + if(!n2oPtr) + f->setArray(dadPtr); + else + { + MCAuto< typename Traits::ArrayType > dad2(dadPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); + f->setArray(dad2); + } + f->setMesh(mesh); + MCAuto< typename MLFieldTraits::FMTSType > fmts(MLFieldTraits::FMTSType::New()); + MCAuto< typename MLFieldTraits::F1TSType > f1ts(MLFieldTraits::F1TSType::New()); + f1ts->setFieldNoProfileSBT(f); + fmts->pushBackTimeStep(f1ts); + fs->pushField(fmts); +} + +void AppendMCFieldFrom(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, MEDFileData *mfd, MCAuto da, const DataArrayInt *n2oPtr, double timeStep, int tsId) { static const char FAMFIELD_FOR_CELLS[]="FamilyIdCell"; static const char FAMFIELD_FOR_NODES[]="FamilyIdNode"; @@ -333,53 +415,24 @@ void AppendMCFieldFrom(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, MEDFi if(!fs || !ms) throw MZCException("AppendMCFieldFrom : internal error 2 !"); MCAuto dad(MEDCoupling::DynamicCast(da)); - DataArrayDouble *dadPtr(dad); - std::string fieldName; - if(dadPtr) + if(dad.isNotNull()) { - fieldName=dadPtr->getName(); - MCAuto f(MEDCouplingFieldDouble::New(tf)); - f->setName(fieldName); - if(!n2oPtr) - f->setArray(dadPtr); - else - { - MCAuto dad2(dadPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); - f->setArray(dad2); - } - f->setMesh(mesh); - MCAuto fmts(MEDFileFieldMultiTS::New()); - MCAuto f1ts(MEDFileField1TS::New()); - f1ts->setFieldNoProfileSBT(f); - fmts->pushBackTimeStep(f1ts); - fs->pushField(fmts); + AppendToFields(tf,mesh,n2oPtr,dad,fs,timeStep,tsId); + return ; + } + MCAuto daf(MEDCoupling::DynamicCast(da)); + if(daf.isNotNull()) + { + AppendToFields(tf,mesh,n2oPtr,daf,fs,timeStep,tsId); return ; } MCAuto dai(MEDCoupling::DynamicCast(da)); - DataArrayInt *daiPtr(dai); - if(daiPtr) + if(dai.isNotNull()) { - fieldName=daiPtr->getName(); + std::string fieldName(dai->getName()); if((fieldName!=FAMFIELD_FOR_CELLS || tf!=MEDCoupling::ON_CELLS) && (fieldName!=FAMFIELD_FOR_NODES || tf!=MEDCoupling::ON_NODES)) { - MCAuto f(MEDCouplingFieldInt::New(tf)); - f->setName(fieldName); - f->setMesh(mesh); - MCAuto fmts(MEDFileIntFieldMultiTS::New()); - MCAuto f1ts(MEDFileIntField1TS::New()); - if(!n2oPtr) - { - f->setArray(dai); - f1ts->setFieldNoProfileSBT(f); - } - else - { - MCAuto dai2(daiPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); - f->setArray(dai2); - f1ts->setFieldNoProfileSBT(f); - } - fmts->pushBackTimeStep(f1ts); - fs->pushField(fmts); + AppendToFields(tf,mesh,n2oPtr,dai,fs,timeStep,tsId); return ; } else if(fieldName==FAMFIELD_FOR_CELLS && tf==MEDCoupling::ON_CELLS) @@ -388,10 +441,10 @@ void AppendMCFieldFrom(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, MEDFi if(!mm) throw MZCException("AppendMCFieldFrom : internal error 3 !"); if(!n2oPtr) - mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),daiPtr); + mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),dai); else { - MCAuto dai2(daiPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); + MCAuto dai2(dai->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); mm->setFamilyFieldArr(mesh->getMeshDimension()-mm->getMeshDimension(),dai2); } } @@ -401,17 +454,17 @@ void AppendMCFieldFrom(MEDCoupling::TypeOfField tf, MEDCouplingMesh *mesh, MEDFi if(!mm) throw MZCException("AppendMCFieldFrom : internal error 4 !"); if(!n2oPtr) - mm->setFamilyFieldArr(1,daiPtr); + mm->setFamilyFieldArr(1,dai); else { - MCAuto dai2(daiPtr->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); + MCAuto dai2(dai->selectByTupleId(n2oPtr->begin(),n2oPtr->end())); mm->setFamilyFieldArr(1,dai2); } } } } -void PutAtLevelDealOrder(MEDFileData *mfd, int meshDimRel, const MicroField& mf) +void PutAtLevelDealOrder(MEDFileData *mfd, int meshDimRel, const MicroField& mf, double timeStep, int tsId) { if(!mfd) throw MZCException("PutAtLevelDealOrder : internal error !"); @@ -440,11 +493,11 @@ void PutAtLevelDealOrder(MEDFileData *mfd, int meshDimRel, const MicroField& mf) for(std::vector >::const_iterator it=cells.begin();it!=cells.end();it++) { MCAuto da(*it); - AppendMCFieldFrom(MEDCoupling::ON_CELLS,mesh,mfd,da,n2oPtr); + AppendMCFieldFrom(MEDCoupling::ON_CELLS,mesh,mfd,da,n2oPtr,timeStep,tsId); } } -void AssignSingleGTMeshes(MEDFileData *mfd, const std::vector< MicroField >& ms) +void AssignSingleGTMeshes(MEDFileData *mfd, const std::vector< MicroField >& ms, double timeStep, int tsId) { if(!mfd) throw MZCException("AssignSingleGTMeshes : internal error !"); @@ -471,12 +524,12 @@ void AssignSingleGTMeshes(MEDFileData *mfd, const std::vector< MicroField >& ms) const std::vector< MicroField >& vs((*it).second); if(vs.size()==1) { - PutAtLevelDealOrder(mfd,(*it).first-meshDim,vs[0]); + PutAtLevelDealOrder(mfd,(*it).first-meshDim,vs[0],timeStep,tsId); } else { MicroField merge(vs); - PutAtLevelDealOrder(mfd,(*it).first-meshDim,merge); + PutAtLevelDealOrder(mfd,(*it).first-meshDim,merge,timeStep,tsId); } } } @@ -491,11 +544,10 @@ DataArrayDouble *BuildCoordsFrom(vtkPointSet *ds) vtkDataArray *data(pts->GetData()); if(!data) throw MZCException("BuildCoordsFrom : internal error 3 !"); - MCAuto coords(ConvertVTKArrayToMCArrayDouble(data)); - return coords.retn(); + return ConvertVTKArrayToMCArrayDoubleForced(data); } -void AddNodeFields(MEDFileData *mfd, vtkDataSetAttributes *dsa) +void AddNodeFields(MEDFileData *mfd, vtkDataSetAttributes *dsa, double timeStep, int tsId) { if(!mfd || !dsa) throw MZCException("AddNodeFields : internal error !"); @@ -520,7 +572,7 @@ void AddNodeFields(MEDFileData *mfd, vtkDataSetAttributes *dsa) continue; MCAuto da(ConvertVTKArrayToMCArray(arr)); da->setName(name); - AppendMCFieldFrom(MEDCoupling::ON_NODES,mesh,mfd,da,0); + AppendMCFieldFrom(MEDCoupling::ON_NODES,mesh,mfd,da,NULL,timeStep,tsId); } } @@ -569,7 +621,7 @@ std::vector > AddPartFields2(int bg, int end, vtkDataSetAttrib return ret; } -void ConvertFromRectilinearGrid(MEDFileData *ret, vtkRectilinearGrid *ds, const std::vector& context) +void ConvertFromRectilinearGrid(MEDFileData *ret, vtkRectilinearGrid *ds, const std::vector& context, double timeStep, int tsId) { if(!ds || !ret) throw MZCException("ConvertFromRectilinearGrid : internal error !"); @@ -585,17 +637,17 @@ void ConvertFromRectilinearGrid(MEDFileData *ret, vtkRectilinearGrid *ds, const vtkDataArray *cx(ds->GetXCoordinates()),*cy(ds->GetYCoordinates()),*cz(ds->GetZCoordinates()); if(cx) { - MCAuto arr(ConvertVTKArrayToMCArrayDouble(cx)); + MCAuto arr(ConvertVTKArrayToMCArrayDoubleForced(cx)); cmeshmc->setCoordsAt(0,arr); } if(cy) { - MCAuto arr(ConvertVTKArrayToMCArrayDouble(cy)); + MCAuto arr(ConvertVTKArrayToMCArrayDoubleForced(cy)); cmeshmc->setCoordsAt(1,arr); } if(cz) { - MCAuto arr(ConvertVTKArrayToMCArrayDouble(cz)); + MCAuto arr(ConvertVTKArrayToMCArrayDoubleForced(cz)); cmeshmc->setCoordsAt(2,arr); } std::string meshName(GetMeshNameWithContext(context)); @@ -605,17 +657,17 @@ void ConvertFromRectilinearGrid(MEDFileData *ret, vtkRectilinearGrid *ds, const for(std::vector >::const_iterator it=cellFs.begin();it!=cellFs.end();it++) { MCAuto da(*it); - AppendMCFieldFrom(MEDCoupling::ON_CELLS,cmeshmc,ret,da,0); + AppendMCFieldFrom(MEDCoupling::ON_CELLS,cmeshmc,ret,da,NULL,timeStep,tsId); } std::vector > nodeFs(AddPartFields(0,ds->GetPointData())); for(std::vector >::const_iterator it=nodeFs.begin();it!=nodeFs.end();it++) { MCAuto da(*it); - AppendMCFieldFrom(MEDCoupling::ON_NODES,cmeshmc,ret,da,0); + AppendMCFieldFrom(MEDCoupling::ON_NODES,cmeshmc,ret,da,NULL,timeStep,tsId); } } -void ConvertFromPolyData(MEDFileData *ret, vtkPolyData *ds, const std::vector& context) +void ConvertFromPolyData(MEDFileData *ret, vtkPolyData *ds, const std::vector& context, double timeStep, int tsId) { if(!ds || !ret) throw MZCException("ConvertFromPolyData : internal error !"); @@ -678,11 +730,11 @@ void ConvertFromPolyData(MEDFileData *ret, vtkPolyData *ds, const std::vectorGetPointData()); + AssignSingleGTMeshes(ret,ms,timeStep,tsId); + AddNodeFields(ret,ds->GetPointData(),timeStep,tsId); } -void ConvertFromUnstructuredGrid(MEDFileData *ret, vtkUnstructuredGrid *ds, const std::vector& context) +void ConvertFromUnstructuredGrid(MEDFileData *ret, vtkUnstructuredGrid *ds, const std::vector& context, double timeStep, int tsId) { if(!ds || !ret) throw MZCException("ConvertFromUnstructuredGrid : internal error !"); @@ -772,13 +824,13 @@ void ConvertFromUnstructuredGrid(MEDFileData *ret, vtkUnstructuredGrid *ds, cons std::vector > cellFs(AddPartFields(cellIdsCurLev,ds->GetCellData())); ms.push_back(MicroField(m0,cellFs)); } - AssignSingleGTMeshes(ret,ms); - AddNodeFields(ret,ds->GetPointData()); + AssignSingleGTMeshes(ret,ms,timeStep,tsId); + AddNodeFields(ret,ds->GetPointData(),timeStep,tsId); } /////////////////// -vtkMEDWriter::vtkMEDWriter():WriteAllTimeSteps(0),FileName(0),IsTouched(false) +vtkMEDWriter::vtkMEDWriter():WriteAllTimeSteps(0),NumberOfTimeSteps(0),CurrentTimeIndex(0),FileName(0) { } @@ -923,10 +975,26 @@ void LoadFamGrpMapInfo(vtkMutableDirectedGraph *sil, std::string& meshName, std: int vtkMEDWriter::RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { //std::cerr << "########################################## vtkMEDWriter::RequestInformation ########################################## " << (const char *) this->FileName << std::endl; + vtkInformation *inInfo(inputVector[0]->GetInformationObject(0)); + if(inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS())) + this->NumberOfTimeSteps=inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); + else + this->NumberOfTimeSteps=0; + return 1; +} + +int vtkMEDWriter::RequestUpdateExtent(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* vtkNotUsed(outputVector)) +{ + double *inTimes(inputVector[0]->GetInformationObject(0)->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS())); + if(inTimes && this->WriteAllTimeSteps) + { + double timeReq(inTimes[this->CurrentTimeIndex]); + inputVector[0]->GetInformationObject(0)->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(),timeReq); + } return 1; } -void WriteMEDFileFromVTKDataSet(MEDFileData *mfd, vtkDataSet *ds, const std::vector& context) +void WriteMEDFileFromVTKDataSet(MEDFileData *mfd, vtkDataSet *ds, const std::vector& context, double timeStep, int tsId) { if(!ds || !mfd) throw MZCException("Internal error in WriteMEDFileFromVTKDataSet."); @@ -935,21 +1003,21 @@ void WriteMEDFileFromVTKDataSet(MEDFileData *mfd, vtkDataSet *ds, const std::vec vtkRectilinearGrid *ds4(vtkRectilinearGrid::SafeDownCast(ds)); if(ds2) { - ConvertFromPolyData(mfd,ds2,context); + ConvertFromPolyData(mfd,ds2,context,timeStep,tsId); } else if(ds3) { - ConvertFromUnstructuredGrid(mfd,ds3,context); + ConvertFromUnstructuredGrid(mfd,ds3,context,timeStep,tsId); } else if(ds4) { - ConvertFromRectilinearGrid(mfd,ds4,context); + ConvertFromRectilinearGrid(mfd,ds4,context,timeStep,tsId); } else throw MZCException("Unrecognized vtkDataSet ! Sorry ! Try to convert it to UnstructuredGrid to be able to write it !"); } -void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, const std::vector& context) +void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, const std::vector& context, double timeStep, int tsId) { if(!ds || !mfd) throw MZCException("Internal error in WriteMEDFileFromVTKMultiBlock."); @@ -962,7 +1030,7 @@ void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, c vtkDataSet *uniqueEltc(vtkDataSet::SafeDownCast(uniqueElt)); if(uniqueEltc) { - WriteMEDFileFromVTKDataSet(mfd,uniqueEltc,context); + WriteMEDFileFromVTKDataSet(mfd,uniqueEltc,context,timeStep,tsId); return ; } } @@ -981,13 +1049,13 @@ void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, c vtkDataSet *elt1(vtkDataSet::SafeDownCast(elt)); if(elt1) { - WriteMEDFileFromVTKDataSet(mfd,elt1,context); + WriteMEDFileFromVTKDataSet(mfd,elt1,context,timeStep,tsId); continue; } vtkMultiBlockDataSet *elt2(vtkMultiBlockDataSet::SafeDownCast(elt)); if(elt2) { - WriteMEDFileFromVTKMultiBlock(mfd,elt2,context); + WriteMEDFileFromVTKMultiBlock(mfd,elt2,context,timeStep,tsId); continue; } std::ostringstream oss; oss << "In context "; @@ -997,7 +1065,7 @@ void WriteMEDFileFromVTKMultiBlock(MEDFileData *mfd, vtkMultiBlockDataSet *ds, c } } -void WriteMEDFileFromVTKGDS(MEDFileData *mfd, vtkDataObject *input) +void WriteMEDFileFromVTKGDS(MEDFileData *mfd, vtkDataObject *input, double timeStep, int tsId) { if(!input || !mfd) throw MZCException("WriteMEDFileFromVTKGDS : internal error !"); @@ -1005,13 +1073,13 @@ void WriteMEDFileFromVTKGDS(MEDFileData *mfd, vtkDataObject *input) vtkDataSet *input1(vtkDataSet::SafeDownCast(input)); if(input1) { - WriteMEDFileFromVTKDataSet(mfd,input1,context); + WriteMEDFileFromVTKDataSet(mfd,input1,context,timeStep,tsId); return ; } vtkMultiBlockDataSet *input2(vtkMultiBlockDataSet::SafeDownCast(input)); if(input2) { - WriteMEDFileFromVTKMultiBlock(mfd,input2,context); + WriteMEDFileFromVTKMultiBlock(mfd,input2,context,timeStep,tsId); return ; } throw MZCException("WriteMEDFileFromVTKGDS : not recognized data type !"); @@ -1053,6 +1121,18 @@ int vtkMEDWriter::RequestData(vtkInformation *request, vtkInformationVector **in //std::cerr << "########################################## vtkMEDWriter::RequestData ########################################## " << (const char *) this->FileName << std::endl; try { + bool writeAll((this->WriteAllTimeSteps!=0 && this->NumberOfTimeSteps>0)); + if(writeAll) + { + if(this->CurrentTimeIndex==0) + request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(),1); + } + else + { + request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING()); + this->CurrentTimeIndex=0; + } + ////////////// vtkInformation *inputInfo(inputVector[0]->GetInformationObject(0)); std::string meshName; std::vector groups; std::vector fams; @@ -1065,11 +1145,33 @@ int vtkMEDWriter::RequestData(vtkInformation *request, vtkInformationVector **in vtkDataObject *input(vtkDataObject::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT()))); if(!input) throw MZCException("Not recognized data object in input of the MEDWriter ! Maybe not implemented yet !"); + double timeStep; + { + vtkInformation *inInfo(inputVector[0]->GetInformationObject(0)); + vtkDataObject* input(vtkDataObject::GetData(inInfo)); + timeStep=input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP()); + } + //////////// MCAuto mfd(MEDFileData::New()); - WriteMEDFileFromVTKGDS(mfd,input); + WriteMEDFileFromVTKGDS(mfd,input,timeStep,this->CurrentTimeIndex); PutFamGrpInfoIfAny(mfd,meshName,groups,fams); - mfd->write(this->FileName,this->IsTouched?0:2); this->IsTouched=true; + if(this->WriteAllTimeSteps==0 || (this->WriteAllTimeSteps!=0 && this->CurrentTimeIndex==0)) + mfd->write(this->FileName,2); + else + { + mfd->getFields()->write(this->FileName,0); + } outInfo->Set(vtkDataObject::DATA_OBJECT(),input); + /////////// + if(writeAll) + { + this->CurrentTimeIndex++; + if(this->CurrentTimeIndex>=this->NumberOfTimeSteps) + { + request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING()); + this->CurrentTimeIndex=0; + } + } } catch(MZCException& e) { diff --git a/src/Plugins/MEDWriter/IO/vtkMEDWriter.h b/src/Plugins/MEDWriter/IO/vtkMEDWriter.h index f35de695..9f9432d4 100644 --- a/src/Plugins/MEDWriter/IO/vtkMEDWriter.h +++ b/src/Plugins/MEDWriter/IO/vtkMEDWriter.h @@ -44,16 +44,16 @@ protected: ~vtkMEDWriter(); int RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector); - int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector); - + int RequestUpdateExtent(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector); private: vtkMEDWriter(const vtkMEDWriter&); void operator=(const vtkMEDWriter&); // Not implemented. private: int WriteAllTimeSteps; + int NumberOfTimeSteps; + int CurrentTimeIndex; char *FileName; - bool IsTouched; //BTX //ETX }; -- 2.39.2