1 // Copyright (C) 2010-2013 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.
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
20 // To access to vtkUnstructuredGrid::Faces and FaceLocations
21 #define protected public
23 #include "VTKMEDCouplingMultiFieldsClient.hxx"
24 #include "VTKMEDCouplingMeshClient.hxx"
25 #include "VTKMEDCouplingFieldClient.hxx"
27 #include "vtkUnstructuredGrid.h"
28 #include "vtkRectilinearGrid.h"
29 #include "vtkDoubleArray.h"
30 #include "vtkErrorCode.h"
31 #include "vtkCellData.h"
32 #include "vtkIdTypeArray.h"
33 #include "vtkPointData.h"
40 const double ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::EPS_TIME=1e-7;
42 ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::MEDCouplingMultiFieldsFetcher(int bufferingPolicy,
43 SALOME_MED::MEDCouplingMultiFieldsCorbaInterface_ptr mfieldsPtr):_effective_pol(bufferingPolicy),_mfields_ptr_released(false)
45 _mfields_ptr=SALOME_MED::MEDCouplingMultiFieldsCorbaInterface::_duplicate(mfieldsPtr);
46 _mfields_ptr->Register();
49 ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::~MEDCouplingMultiFieldsFetcher()
51 for(std::vector<vtkDataSet *>::iterator it=_meshes.begin();it!=_meshes.end();it++)
56 for(std::vector<vtkDoubleArray *>::iterator it2=_arrays.begin();it2!=_arrays.end();it2++)
61 if(!_mfields_ptr_released)
62 _mfields_ptr->UnRegister();
65 std::vector<double> ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::getTimeStepsForPV()
67 retrievesMainTinyInfo();
68 int nbOfFields=_mesh_id_per_field.size();
70 _time_label_per_field.resize(nbOfFields);
71 SALOME_MED::MEDCouplingFieldOverTimeCorbaInterface_var fotPtr=SALOME_MED::MEDCouplingFieldOverTimeCorbaInterface::_narrow(_mfields_ptr);
72 if(CORBA::is_nil(fotPtr))
74 for(CORBA::Long i=0;i<nbOfFields;i++)
75 _time_label_per_field[i]=(double)i;
80 for(CORBA::Long i=0;i<nbOfFields;i++)
82 if(!_time_def_per_field[i].empty())
83 _time_label_per_field[i]=_time_def_per_field[i].front();
85 _time_label_per_field[i]=tmp++;
88 return _time_label_per_field;
91 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::fetchRegardingPolicy()
93 if(_effective_pol>=10)
98 if(_effective_pol>=1 && _effective_pol<=9)
105 vtkDataSet *ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::buildDataSetOnTime(double time)
107 int fieldId=getPosGivenTimeLabel(time);
110 fetchDataIfNeeded(fieldId);
111 int meshId=_mesh_id_per_field[fieldId];
112 vtkDataSet *ret0=_meshes[meshId];
113 std::string clsName=ret0->GetClassName();
114 if(clsName=="vtkUnstructuredGrid")
116 vtkUnstructuredGrid *ret1=vtkUnstructuredGrid::New();
117 ret1->DeepCopy(ret0);
118 if(_is_meshes_polyhedron[meshId])//bug VTK polyhedron
119 {//bug VTK polyhedron part
120 ret1->Faces->UnRegister(ret1);
121 ret1->Faces=vtkIdTypeArray::New();
122 ret1->Faces->DeepCopy(((vtkUnstructuredGrid *)ret0)->GetFaces());
123 ret1->Faces->Register(ret1);
124 ret1->Faces->Delete();
125 ret1->FaceLocations->UnRegister(ret1);
126 ret1->FaceLocations=vtkIdTypeArray::New();
127 ret1->FaceLocations->DeepCopy(((vtkUnstructuredGrid *)ret0)->GetFaceLocations());
128 ret1->FaceLocations->Register(ret1);
129 ret1->FaceLocations->Delete();
130 }//end bug VTK polyhedron part
131 appendFieldValueOnAlreadyFetchedData(ret1,fieldId);
132 applyBufferingPolicy();
135 if(clsName=="vtkRectilinearGrid")
137 vtkRectilinearGrid *ret1=vtkRectilinearGrid::New();
138 ret1->DeepCopy(ret0);
139 appendFieldValueOnAlreadyFetchedData(ret1,fieldId);
140 applyBufferingPolicy();
146 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::retrievesMainTinyInfo()
148 SALOME_TYPES::ListOfLong *tinyL=0;
149 SALOME_TYPES::ListOfDouble *tinyD=0;
150 SALOME_TYPES::ListOfString *tinyS=0;
152 CORBA::Long nbOfArrays;
153 CORBA::Long nbOfFields;
154 CORBA::Long nbOfMeshes=_mfields_ptr->getMainTinyInfo(tinyL,tinyD,nbOfArrays,nbOfFields);
155 int sz=(*tinyL)[0];//nbOfFields
156 //int sz2=(*tinyL)[1];//sigma(nbOfArraysPerField)
157 _time_discr_per_field.resize(sz);//4 : NO_TIME 5:ONE_TIME 6:LINEAR_TIME 7:CONST_ON_TIME_INTERVAL
158 _mesh_id_per_field.resize(sz);
159 _array_ids_per_field.resize(sz);
160 _time_def_per_field.resize(sz);
163 for(int i=0;i<sz;i++)
165 _mesh_id_per_field[i]=(*tinyL)[3+i];
166 int nbOfArrayForCurField=(*tinyL)[sz+3+i];
167 _array_ids_per_field[i].resize(nbOfArrayForCurField);
168 for(int k=0;k<nbOfArrayForCurField;k++)
169 _array_ids_per_field[i][k]=(*tinyL)[5*sz+3+offsetArrays+k];
170 _time_discr_per_field[i]=(*tinyL)[2*sz+3+i];
171 int nbOfTimeSpot=(*tinyL)[3*sz+3+i]-1;//-1 because time precision is not useful here.
172 _time_def_per_field[i].resize(nbOfTimeSpot);
173 for(int j=0;j<nbOfTimeSpot;j++)
174 _time_def_per_field[i][j]=(*tinyD)[offsetTime+1+j];
175 offsetTime+=nbOfTimeSpot+1;
176 offsetArrays+=nbOfArrayForCurField;
181 _meshes.resize(nbOfMeshes+1);
182 _is_meshes_polyhedron.resize(nbOfMeshes+1);
183 _arrays.resize(nbOfArrays+1);
185 _info_per_field.resize(nbOfFields);
186 for(int i=0;i<nbOfFields;i++)
188 _mfields_ptr->getTinyInfo(i,tinyL,tinyD,tinyS);
189 _info_per_field[i]._type=(*tinyL)[0];
190 _info_per_field[i]._name=(*tinyS)[0];
197 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::fetchAll()
200 int nbOfArrays=_arrays.size();
201 for(int i=0;i<nbOfArrays;i++)
203 SALOME_MED::DataArrayDoubleCorbaInterface_var daPtr=_mfields_ptr->getArray(i);
205 _arrays[i]->Delete();
206 _arrays[i]=ParaMEDMEM2VTK::BuildFromMEDCouplingFieldDoubleArr(daPtr);
209 unregisterRemoteServantIfAllFetched();
213 * Fetches meshes without regarding if already fetched
215 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::fetchMeshes()
217 int nbOfMeshes=_meshes.size();
218 for(int i=0;i<nbOfMeshes;i++)
220 SALOME_MED::MEDCouplingMeshCorbaInterface_var mPtr=_mfields_ptr->getMeshWithId(i);
222 _meshes[i]->Delete();
223 bool polyh=false;//bug VTK
224 _meshes[i]=ParaMEDMEM2VTK::BuildFromMEDCouplingMeshInstance(mPtr,polyh);//bug VTK
225 _is_meshes_polyhedron[i]=polyh;//bug VTK
228 unregisterRemoteServantIfAllFetched();
232 * For a field with id 'fieldId' this method CORBA fetch, if needed, basic data.
233 * 'fieldId' should be correct no check of that is done !
235 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::fetchDataIfNeeded(int fieldId)
237 std::vector<int> arrayIds=_array_ids_per_field[fieldId];
238 int meshId=_mesh_id_per_field[fieldId];
241 SALOME_MED::MEDCouplingMeshCorbaInterface_var mPtr=_mfields_ptr->getMeshWithId(meshId);
242 bool polyh=false;//bug VTK
243 _meshes[meshId]=ParaMEDMEM2VTK::BuildFromMEDCouplingMeshInstance(mPtr,polyh);//bug VTK
244 _is_meshes_polyhedron[meshId]=polyh;//bug VTK
247 for(std::vector<int>::const_iterator it=arrayIds.begin();it!=arrayIds.end();it++)
251 SALOME_MED::DataArrayDoubleCorbaInterface_var daPtr=_mfields_ptr->getArray(*it);
252 _arrays[*it]=ParaMEDMEM2VTK::BuildFromMEDCouplingFieldDoubleArr(daPtr);
256 unregisterRemoteServantIfAllFetched();
259 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::unregisterRemoteServantIfAllFetched()
261 for(std::vector<vtkDataSet *>::iterator it=_meshes.begin();it!=_meshes.end();it++)
266 for(std::vector<vtkDoubleArray *>::iterator it2=_arrays.begin();it2!=_arrays.end();it2++)
271 if(!_mfields_ptr_released)
273 _mfields_ptr_released=true;
274 _mfields_ptr->UnRegister();
278 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::applyBufferingPolicy()
280 if(_effective_pol==0)
282 for(std::vector<vtkDataSet *>::iterator it=_meshes.begin();it!=_meshes.end();it++)
290 for(std::vector<vtkDoubleArray *>::iterator it2=_arrays.begin();it2!=_arrays.end();it2++)
299 //else nothing to do let the plugin bufferize
302 void ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::appendFieldValueOnAlreadyFetchedData(vtkDataSet *ds, int fieldId)
304 const TinyInfoOnField& info=_info_per_field[fieldId];
305 vtkDoubleArray *arr=_arrays[_array_ids_per_field[fieldId].front()];
306 arr->SetName(info._name.c_str());
307 if(info._type==0)//ON_CELLS
309 ds->GetCellData()->AddArray(arr);
312 if(info._type==1)//ON_NODES
314 ds->GetPointData()->AddArray(arr);
319 int ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher::getPosGivenTimeLabel(double t)
321 int nbOfFields=_time_label_per_field.size();
322 for(int i=0;i<nbOfFields;i++)
323 if(fabs(_time_label_per_field[i]-t)<EPS_TIME)
326 std::vector<double>::iterator it=std::find_if(_time_label_per_field.begin(),_time_label_per_field.end(),
327 std::bind2nd(std::greater<double>(),t));
328 if(it!=_time_label_per_field.end() && it!=_time_label_per_field.end())
329 return std::distance(_time_label_per_field.begin(),it);
331 std::ostringstream oss;
332 oss << "Unexisting time : " << t << " Not in ";
333 std::copy(_time_label_per_field.begin(),_time_label_per_field.end(),std::ostream_iterator<double>(oss," "));
335 vtkOutputWindowDisplayErrorText(oss.str().c_str());