Salome HOME
Merge from V5_1_main 14/05/2010
[modules/visu.git] / src / CONVERTOR / VISU_MeshValue.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  VISU OBJECT : interactive object for VISU entities implementation
24 //  File:
25 //  Author:
26 //  Module : VISU
27 //
28 #include "VISU_MeshValue.hxx"
29 #include "VISU_ElnoMeshValue.hxx"
30 #include "VISU_Structures_impl.hxx"
31 #include "VISU_ConvertorUtils.hxx"
32
33 #include "VISU_PointCoords.hxx"
34 #include "VISU_VTKTypeList.hxx"
35
36 #include <vtkUnstructuredGrid.h>
37 #include <vtkPolyData.h>
38
39 #include <vtkPointData.h>
40 #include <vtkCellData.h>
41
42 #include <vtkCharArray.h>
43 #include <vtkUnsignedCharArray.h>
44 #include <vtkShortArray.h>
45 #include <vtkUnsignedShortArray.h>
46 #include <vtkIntArray.h>
47 #include <vtkUnsignedIntArray.h>
48 #include <vtkLongArray.h>
49 #include <vtkUnsignedLongArray.h>
50 #include <vtkFloatArray.h>
51 #include <vtkDoubleArray.h>
52
53 #include <string>
54 #include <algorithm>
55
56 #ifdef _DEBUG_
57 static int MYDEBUG = 0;
58 #else
59 static int MYDEBUG = 0;
60 #endif
61
62 namespace VISU
63 {
64   //---------------------------------------------------------------
65   std::string
66   GenerateFieldName(const PFieldImpl& theField,
67                     const PValForTimeImpl& theValForTime)
68   {
69     const VISU::TTime& aTime = theValForTime->myTime;
70     std::string aFieldName = theField->myMeshName + ", " + theField->myName + ": " +
71       VISU_Convertor::GenerateName(aTime);
72     return aFieldName;
73   }
74
75
76   //---------------------------------------------------------------
77   void
78   TMeshValueBase
79   ::Init(vtkIdType theNbElem,
80          vtkIdType theNbGauss,
81          vtkIdType theNbComp)
82   {
83     myNbElem = theNbElem;
84     myNbGauss = theNbGauss;
85     myNbComp = theNbComp;
86     myStep = theNbComp*theNbGauss;
87   }
88
89   vtkIdType
90   TMeshValueBase
91   ::GetNbElem() const
92   {
93     return myNbElem;
94   }
95
96   vtkIdType
97   TMeshValueBase
98   ::GetNbComp() const
99   {
100     return myNbComp;
101   }
102
103   vtkIdType
104   TMeshValueBase
105   ::GetNbGauss() const
106   {
107     return myNbGauss;
108   }
109
110   size_t
111   TMeshValueBase
112   ::size() const
113   {
114     return myNbElem * myStep;
115   }
116
117
118   //----------------------------------------------------------------------------
119   template<int EDataType>
120   void
121   InitTimeStampOnProfile(const PUnstructuredGrid& theSource,
122                          const PFieldImpl& theField,
123                          const PValForTimeImpl& theValForTime,
124                          const VISU::TEntity& theEntity);
125
126
127   //----------------------------------------------------------------------------
128   void
129   GetTimeStampOnProfile(const PUnstructuredGrid& theSource,
130                         const PFieldImpl& theField,
131                         const PValForTimeImpl& theValForTime,
132                         const VISU::TEntity& theEntity)
133   {
134     vtkIdType aDataType = theField->GetDataType();
135     switch(aDataType){
136     case VTK_DOUBLE:
137       InitTimeStampOnProfile<VTK_DOUBLE>(theSource, theField, theValForTime, theEntity);
138       break;
139     case VTK_FLOAT:
140       InitTimeStampOnProfile<VTK_FLOAT>(theSource, theField, theValForTime, theEntity);
141       break;
142     case VTK_INT:
143       InitTimeStampOnProfile<VTK_INT>(theSource, theField, theValForTime, theEntity);
144       break;
145     case VTK_LONG:
146       InitTimeStampOnProfile<VTK_LONG>(theSource, theField, theValForTime, theEntity);
147       break;
148     default:
149       EXCEPTION(std::runtime_error,
150                 "GetTimeStampOnProfile - handling unsupported data type - "<<aDataType);
151     }
152   }
153
154
155   //----------------------------------------------------------------------------
156   template<int EDataType>
157   struct TDataArrayHolder
158   {
159     typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
160     typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
161     TVTKDataArray* myDataArray;
162
163     TDataArrayHolder(TVTKDataArray* theDataArray):
164       myDataArray(theDataArray)
165     {}
166
167     void
168     WritePointer(TVTKDataArray* theDataArray,
169                  vtkIdType theTupleId,
170                  TVTKBasicType* thePointer)
171     {
172       vtkIdType aNumberOfComponents = theDataArray->GetNumberOfComponents();
173       vtkIdType aPosition = theTupleId * aNumberOfComponents;
174       TVTKBasicType *aPtr = theDataArray->WritePointer(aPosition, aNumberOfComponents);
175       for(vtkIdType anId = 0; anId < aNumberOfComponents; anId++)
176         *aPtr++ = *thePointer++;
177     }
178
179     virtual
180     void
181     SetTuple(vtkIdType theTupleId,
182              TVTKBasicType* thePointer)
183     {
184       this->WritePointer(myDataArray, theTupleId, thePointer);
185     }
186   };
187
188
189   //----------------------------------------------------------------------------
190   template<int EDataType>
191   struct TDataArrayHolder2: TDataArrayHolder<EDataType>
192   {
193     typedef TDataArrayHolder<EDataType> TSuperClass;
194     typedef typename TSuperClass::TVTKDataArray TVTKDataArray;
195     typedef typename TSuperClass::TVTKBasicType TVTKBasicType;
196     TVTKDataArray* myDataArray2;
197
198     TDataArrayHolder2(TVTKDataArray* theDataArray,
199                       TVTKDataArray* theDataArray2):
200       TSuperClass(theDataArray),
201       myDataArray2(theDataArray2)
202     {}
203
204     virtual
205     void
206     SetTuple(vtkIdType theTupleId,
207              TVTKBasicType* thePointer)
208     {
209       this->WritePointer(this->myDataArray, theTupleId, thePointer);
210       this->WritePointer(this->myDataArray2, theTupleId, thePointer);
211     }
212   };
213
214
215   //----------------------------------------------------------------------------
216   template<int EDataType>
217   struct TTimeStampOnProfileInitArray
218   {
219     typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
220     typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
221     typedef TTMeshValue<TVTKBasicType> TMeshValue;
222     typedef MED::SharedPtr<TMeshValue> TMeshValuePtr;
223
224     typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
225     typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
226     PDataArrayHolder myDataArrayHolder;
227
228     TTimeStampOnProfileInitArray(const PDataArrayHolder& theDataArrayHolder):
229       myDataArrayHolder(theDataArrayHolder)
230     {}
231
232     void
233     Execute(const PFieldImpl& theField,
234             const PValForTimeImpl& theValForTime,
235             const TGaussMetric theGaussMetric = VISU::AVERAGE_METRIC)
236     {
237       vtkIdType aNbComp = theField->myNbComp;
238       vtkIdType aSize = std::max(vtkIdType(3), aNbComp);
239       TVector<TVTKBasicType> aDataValues (aSize);
240
241       const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
242       TGeom2MeshValue::const_iterator anIter = aGeom2MeshValue.begin();
243       for (int aTupleId = 0; anIter != aGeom2MeshValue.end(); anIter++) {
244         EGeometry aEGeom = anIter->first;
245         const TMeshValuePtr aMeshValue = anIter->second;
246
247         vtkIdType aNbElem = aMeshValue->GetNbElem();
248         vtkIdType aNbGauss = aMeshValue->GetNbGauss();
249
250         INITMSG(MYDEBUG,
251                 "- aEGeom = "<<aEGeom<<
252                 "; aNbElem = "<<aNbElem<<
253                 "; aNbGauss = "<<aNbGauss<<
254                 std::endl);
255
256         for (vtkIdType iElem = 0; iElem < aNbElem; iElem++, aTupleId++) {
257           typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetCompValueSliceArr(iElem);
258
259           for (vtkIdType iComp = 0; iComp < aNbComp; iComp++) {
260             const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iComp];
261             //jfa//aDataValues[iComp] = TVTKBasicType();
262             for (vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++) {
263               TVTKBasicType aValue = aValueSlice[iGauss];
264               //jfa//if (iGauss == 0 && theGaussMetric != VISU::AVERAGE_METRIC) {
265               if (iGauss == 0) {
266                 aDataValues[iComp] = aValue; // init
267               }
268               else {
269                 switch (theGaussMetric) {
270                   case VISU::AVERAGE_METRIC:
271                     aDataValues[iComp] += aValue; break;
272                   case VISU::MINIMUM_METRIC:
273                     aDataValues[iComp] = std::min( aValue, aDataValues[iComp] ); break;
274                   case VISU::MAXIMUM_METRIC:
275                     aDataValues[iComp] = std::max( aValue, aDataValues[iComp] ); break;
276                 }
277               }
278             }
279             if (theGaussMetric == VISU::AVERAGE_METRIC)
280               aDataValues[iComp] /= aNbGauss;
281           }
282
283           this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
284         }
285       }
286     }
287   };
288
289   template<int EDataType>
290   struct TTimeStampOnProfileInitModulus
291   {
292     typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
293     typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
294     typedef TTMeshValue<TVTKBasicType> TMeshValue;
295     typedef MED::SharedPtr<TMeshValue> TMeshValuePtr;
296
297     typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
298     typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
299     PDataArrayHolder myDataArrayHolder;
300
301     TTimeStampOnProfileInitModulus(const PDataArrayHolder& theDataArrayHolder):
302       myDataArrayHolder(theDataArrayHolder)
303     {}
304
305     void
306     Execute(const PFieldImpl& theField, const PValForTimeImpl& theValForTime)
307     {
308       vtkIdType aNbComp = theField->myNbComp;
309       vtkIdType aSize = vtkIdType(3); // Minimum, Maximum and Average modulus
310       TVector<TVTKBasicType> aDataValues (aSize);
311
312       const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
313       TGeom2MeshValue::const_iterator anIter = aGeom2MeshValue.begin();
314       for (int aTupleId = 0; anIter != aGeom2MeshValue.end(); anIter++) {
315         EGeometry aEGeom = anIter->first;
316         const TMeshValuePtr aMeshValue = anIter->second;
317
318         vtkIdType aNbElem = aMeshValue->GetNbElem();
319         vtkIdType aNbGauss = aMeshValue->GetNbGauss();
320
321         INITMSG(MYDEBUG,
322                 "- aEGeom = "<<aEGeom<<
323                 "; aNbElem = "<<aNbElem<<
324                 "; aNbGauss = "<<aNbGauss<<
325                 std::endl);
326
327         for (vtkIdType iElem = 0; iElem < aNbElem; iElem++, aTupleId++) {
328           typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetCompValueSliceArr(iElem);
329
330           // modules of all gauss points
331           TVector<TVTKBasicType> aModules (aNbGauss);
332
333           for (vtkIdType iComp = 0; iComp < aNbComp; iComp++) {
334             const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iComp];
335             for (vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++) {
336               TVTKBasicType aValue = aValueSlice[iGauss];
337
338               // modules of all gauss points
339               if (iComp == 0)
340                 aModules[iGauss] = aValue * aValue; // init
341               else
342                 aModules[iGauss] += aValue * aValue;
343             }
344           }
345
346           TVTKBasicType aModule = (TVTKBasicType)sqrt((double)aModules[0]);
347           aDataValues[0] = aModule; // init Min
348           aDataValues[1] = aModule; // init Max
349           aDataValues[2] = aModule; // init Average
350
351           for (vtkIdType ig = 0; ig < aNbGauss; ig++) {
352             aModule = (TVTKBasicType)sqrt((double)aModules[ig]);
353
354             aDataValues[0] = std::min(TVTKBasicType(aModule), aDataValues[0]); // Min
355             aDataValues[1] = std::max(TVTKBasicType(aModule), aDataValues[1]); // Max
356             aDataValues[2] += aModule;                                         // Average
357           }
358           aDataValues[2] /= aNbGauss; // Average
359
360           this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
361         }
362       }
363     }
364   };
365
366
367   //----------------------------------------------------------------------------
368   template<int EDataType>
369   void
370   InitTimeStampOnProfile(const PUnstructuredGrid& theSource,
371                          const PFieldImpl& theField,
372                          const PValForTimeImpl& theValForTime,
373                          const VISU::TEntity& theEntity)
374   {
375     vtkIdType aNbTuples = theField->myDataSize / theField->myNbComp;
376     std::string aFieldName = VISU::GenerateFieldName(theField, theValForTime);
377
378     vtkDataSetAttributes* aDataSetAttributes;
379     switch ( theEntity ) {
380     case VISU::NODE_ENTITY :
381       aDataSetAttributes = theSource->GetPointData();
382       break;
383     default:
384       aDataSetAttributes = theSource->GetCellData();
385     }
386
387     typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
388     TVTKDataArray *aSelectedDataArray = TVTKDataArray::New();
389     vtkIdType aNbComp = theField->myNbComp;
390
391     switch ( aNbComp ) {
392     case 1:
393       aSelectedDataArray->SetNumberOfComponents( 1 );
394       aDataSetAttributes->SetScalars( aSelectedDataArray );
395       break;
396     default:
397       aSelectedDataArray->SetNumberOfComponents( 3 );
398       aDataSetAttributes->SetVectors( aSelectedDataArray );
399     }
400     aSelectedDataArray->SetNumberOfTuples( aNbTuples );
401     aSelectedDataArray->SetName( aFieldName.c_str() );
402
403     TVTKDataArray *aFullDataArray = TVTKDataArray::New();
404     aFullDataArray->SetNumberOfComponents( aNbComp );
405     aFullDataArray->SetNumberOfTuples( aNbTuples );
406     aFullDataArray->SetName( "VISU_FIELD" );
407     aDataSetAttributes->AddArray( aFullDataArray );
408
409     INITMSG(MYDEBUG,"InitTimeStampOnProfile "<<
410             "- theEntity = "<<theEntity<<
411             "; aNbTuples = "<<aNbTuples<<
412             "; aNbComp = "<<aNbComp<<
413             std::endl);
414
415     TTimerLog aTimerLog(MYDEBUG,"InitTimeStampOnProfile");
416
417     const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
418     typedef typename TL::TEnum2VTKBasicType< EDataType >::TResult TVTKBasicType;
419     typedef TTMeshValue< TVTKBasicType > TMeshValue;
420     typedef MED::SharedPtr< TMeshValue > TMeshValuePtr;
421
422     typedef TDataArrayHolder< EDataType > TTDataArrayHolder;
423     typedef MED::SharedPtr< TTDataArrayHolder > PDataArrayHolder;
424
425     TMeshValuePtr aMeshValue = theValForTime->GetFirstMeshValue();
426     if ( aGeom2MeshValue.size() == 1 && aMeshValue->GetNbGauss() == 1 ) {
427       aFullDataArray->SetVoidArray(aMeshValue->GetPointer(),
428                                    aMeshValue->size(),
429                                    true);
430       INITMSG(MYDEBUG,"InitTimeStampOnProfile - aFullDataArray->SetVoidArray()"<<std::endl);
431       if ( aNbComp == 1 ) {
432         aSelectedDataArray->SetVoidArray( aMeshValue->GetPointer(),
433                                           aMeshValue->size(),
434                                           true );
435         INITMSG(MYDEBUG,"InitTimeStampOnProfile - aSelectedDataArray->SetVoidArray()"<<std::endl);
436       }else{
437         PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder(aSelectedDataArray));
438         TTimeStampOnProfileInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
439       }
440     }
441     else {
442       typedef TDataArrayHolder2<EDataType> TTDataArrayHolder2;
443       PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder2(aSelectedDataArray, aFullDataArray));
444       TTimeStampOnProfileInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
445
446       if ( theValForTime->GetMaxNbGauss() > 1 ) { // at least one of geometry contains multiple gauss points
447         TVTKDataArray *aGaussMinDataArray = TVTKDataArray::New();
448         aGaussMinDataArray->SetNumberOfComponents( aNbComp );
449         aGaussMinDataArray->SetNumberOfTuples( aNbTuples );
450         aGaussMinDataArray->SetName( "VISU_FIELD_GAUSS_MIN" );
451         aDataSetAttributes->AddArray( aGaussMinDataArray );
452
453         PDataArrayHolder aGaussMinDataArrayHolder(new TTDataArrayHolder(aGaussMinDataArray));
454         TTimeStampOnProfileInitArray<EDataType>(aGaussMinDataArrayHolder).Execute
455           (theField, theValForTime, VISU::MINIMUM_METRIC);
456         aGaussMinDataArray->Delete();
457
458         TVTKDataArray *aGaussMaxDataArray = TVTKDataArray::New();
459         aGaussMaxDataArray->SetNumberOfComponents( aNbComp );
460         aGaussMaxDataArray->SetNumberOfTuples( aNbTuples );
461         aGaussMaxDataArray->SetName( "VISU_FIELD_GAUSS_MAX" );
462         aDataSetAttributes->AddArray( aGaussMaxDataArray );
463
464         PDataArrayHolder aGaussMaxDataArrayHolder(new TTDataArrayHolder(aGaussMaxDataArray));
465         TTimeStampOnProfileInitArray<EDataType>(aGaussMaxDataArrayHolder).Execute
466           (theField, theValForTime, VISU::MAXIMUM_METRIC);
467         aGaussMaxDataArray->Delete();
468
469         TVTKDataArray *aGaussModulusDataArray = TVTKDataArray::New();
470         aGaussModulusDataArray->SetNumberOfComponents( 3 ); // Min, Max and Average
471         aGaussModulusDataArray->SetNumberOfTuples( aNbTuples );
472         aGaussModulusDataArray->SetName( "VISU_FIELD_GAUSS_MOD" );
473         aDataSetAttributes->AddArray( aGaussModulusDataArray );
474
475         PDataArrayHolder aGaussModulusDataArrayHolder(new TTDataArrayHolder(aGaussModulusDataArray));
476         TTimeStampOnProfileInitModulus<EDataType>(aGaussModulusDataArrayHolder).Execute
477           (theField, theValForTime);
478         aGaussModulusDataArray->Delete();
479       }
480     }
481
482     aSelectedDataArray->Delete();
483     aFullDataArray->Delete();
484
485     // Process the case for ELNO data
486     //-------------------------------
487     if ( theField->myIsELNO ) {
488       // To calculate effective number of components for the VTK compatibel ELNO data representation
489       vtkIdType aEffectNbTuples = 0;
490       TGeom2MeshValue::const_iterator anIter = aGeom2MeshValue.begin();
491       for ( ; anIter != aGeom2MeshValue.end(); anIter++ ) {
492         const PMeshValue& aMeshValue = anIter->second;
493         aEffectNbTuples += aMeshValue->GetNbElem() * aMeshValue->GetNbGauss();
494       }
495
496       vtkIdType anEffectNbComp = ( aEffectNbTuples * aNbComp ) / aNbTuples + 1;
497
498       // To create corresponding VTK representation for the ELNO data
499       TSetElnoNodeData< EDataType > aSetElnoNodeData( anEffectNbComp,
500                                                       aNbComp,
501                                                       aNbTuples,
502                                                       "ELNO_FIELD",
503                                                       "ELNO_COMPONENT_MAPPER" );
504
505       std::vector< TVTKBasicType > aDataValues( aNbComp ); // To reserve a temproary value holder
506
507       // To initilize these VTK representation for the ELNO data from the MED
508       anIter = aGeom2MeshValue.begin();
509       for ( ; anIter != aGeom2MeshValue.end(); anIter++ ) {
510         EGeometry aEGeom = anIter->first;
511         const TMeshValuePtr aMeshValue = anIter->second;
512
513         vtkIdType aNbElem = aMeshValue->GetNbElem();
514         vtkIdType aNbGauss = aMeshValue->GetNbGauss();
515
516         INITMSG(MYDEBUG,
517                 "- aEGeom = "<<aEGeom<<
518                 "; aNbElem = "<<aNbElem<<
519                 "; aNbGauss = "<<aNbGauss<<
520                 std::endl);
521         std::vector<int> med2visu(aNbGauss);
522         InitMed2VisuArray(med2visu,aEGeom);
523         for ( vtkIdType iElem = 0; iElem < aNbElem; iElem++ ) {
524           const typename TMeshValue::TValueSliceArr& aValueSliceArr =
525             aMeshValue->GetGaussValueSliceArr( iElem );
526
527           for( vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++ ) {
528             const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[ med2visu[iGauss] ];
529
530             for( vtkIdType iComp = 0; iComp < aNbComp; iComp++ ) {
531               aDataValues[ iComp ] = aValueSlice[ iComp ];
532             }
533
534             aSetElnoNodeData.AddNextPointData( &aDataValues[ 0 ] );
535           }
536
537           aSetElnoNodeData.InsertNextCellData();
538         }
539       }
540
541       // Assign the ELNO data on the corresponding VTK data set attribute
542       aSetElnoNodeData.AddData( aDataSetAttributes );
543     }
544     //-------------------------------
545   }
546
547
548   //----------------------------------------------------------------------------
549   template<int EDataType>
550   void
551   InitTimeStampOnGaussMesh(const PPolyData& theSource,
552                            const PFieldImpl& theField,
553                            const PValForTimeImpl& theValForTime);
554
555   void
556   GetTimeStampOnGaussMesh(const PPolyData& theSource,
557                           const PFieldImpl& theField,
558                           const PValForTimeImpl& theValForTime)
559   {
560     vtkIdType aDataType = theField->GetDataType();
561     switch(aDataType){
562     case VTK_DOUBLE:
563       InitTimeStampOnGaussMesh<VTK_DOUBLE>(theSource, theField, theValForTime);
564       break;
565     case VTK_FLOAT:
566       InitTimeStampOnGaussMesh<VTK_FLOAT>(theSource, theField, theValForTime);
567       break;
568     case VTK_INT:
569       InitTimeStampOnGaussMesh<VTK_INT>(theSource, theField, theValForTime);
570       break;
571     case VTK_LONG:
572       InitTimeStampOnGaussMesh<VTK_LONG>(theSource, theField, theValForTime);
573       break;
574     default:
575       EXCEPTION(std::runtime_error,
576                 "GetTimeStampOnGaussMesh - handling unsupported data type - "<<aDataType);
577     }
578   }
579
580   //----------------------------------------------------------------------------
581   template<int EDataType>
582   struct TTimeStampOnGaussMeshInitArray
583   {
584     typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
585     typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
586     typedef TTMeshValue<TVTKBasicType> TMeshValue;
587     typedef MED::SharedPtr<TMeshValue> TMeshValuePtr;
588
589     typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
590     typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
591     PDataArrayHolder myDataArrayHolder;
592
593     TTimeStampOnGaussMeshInitArray(const PDataArrayHolder& theDataArrayHolder):
594       myDataArrayHolder(theDataArrayHolder)
595     {}
596
597     void
598     Execute(const PFieldImpl& theField,
599             const PValForTimeImpl& theValForTime)
600     {
601       vtkIdType aNbComp = theField->myNbComp;
602       vtkIdType aSize = std::max(vtkIdType(3), aNbComp);
603       TVector<TVTKBasicType> aDataValues(aSize);
604
605       const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
606
607       PGaussMeshImpl aGaussMesh = theValForTime->myGaussMesh;
608       const TGeom2GaussSubMesh& aGeom2GaussSubMesh = aGaussMesh->myGeom2GaussSubMesh;
609       TGeom2GaussSubMesh::const_iterator anIter = aGeom2GaussSubMesh.begin();
610       for(int aTupleId = 0; anIter != aGeom2GaussSubMesh.end(); anIter++){
611         EGeometry aEGeom = anIter->first;
612
613         PGaussSubMeshImpl aGaussSubMesh = anIter->second;
614         if(!aGaussSubMesh->myIsDone)
615           continue;
616
617         TGeom2MeshValue::const_iterator anIter2 = aGeom2MeshValue.find(aEGeom);
618         if(anIter2 == aGeom2MeshValue.end()){
619           EXCEPTION(std::runtime_error,
620                     "TTimeStampOnGaussMeshInitArray >> Can't find values for corresponding Gauss Points SubMesh");
621         }
622         TMeshValuePtr aMeshValue = anIter2->second;
623         vtkIdType aNbGauss = aMeshValue->GetNbGauss();
624         vtkIdType aNbElem = aMeshValue->GetNbElem();
625
626         if(aNbGauss < 1)
627           continue;
628
629         const TPointCoords& aCoords = aGaussSubMesh->myPointCoords;
630
631         INITMSG(MYDEBUG,
632                 "- aEGeom = "<<aEGeom<<
633                 "; aNbElem = "<<aNbElem<<
634                 "; aNbGauss = "<<aNbGauss<<
635                 "; aCoords.GetNbPoints() = "<<aCoords.GetNbPoints()<<
636                 std::endl);
637
638         if(aCoords.GetNbPoints() == aNbElem*aNbGauss){
639           for(int iElem = 0; iElem < aNbElem; iElem++){
640             typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetGaussValueSliceArr(iElem);
641             for(int iGauss = 0; iGauss < aNbGauss; iGauss++, aTupleId++){
642               const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iGauss];
643               for(int iComp = 0; iComp < aNbComp; iComp++){
644                 aDataValues[iComp] = aValueSlice[iComp];
645               }
646               this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
647             }
648           }
649         }else{
650           for(int iElem = 0; iElem < aNbElem; iElem++, aTupleId++){
651             typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetCompValueSliceArr(iElem);
652             for(int iComp = 0; iComp < aNbComp; iComp++){
653               const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iComp];
654               aDataValues[iComp] = TVTKBasicType();
655               for(int iGauss = 0; iGauss < aNbGauss; iGauss++){
656                 aDataValues[iComp] += aValueSlice[iGauss];
657               }
658               aDataValues[iComp] /= aNbGauss;
659             }
660             this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
661           }
662         }
663       }
664     }
665   };
666
667
668   template<int EDataType>
669   void
670   InitTimeStampOnGaussMesh(const PPolyData& theSource,
671                            const PFieldImpl& theField,
672                            const PValForTimeImpl& theValForTime)
673   {
674     vtkIdType aNbTuples = theSource->GetNumberOfPoints();
675     std::string aFieldName = VISU::GenerateFieldName(theField, theValForTime);
676
677     vtkDataSetAttributes* aDataSetAttributes = theSource->GetPointData();
678
679     typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
680     TVTKDataArray *aSelectedDataArray = TVTKDataArray::New();
681     vtkIdType aNbComp = theField->myNbComp;
682     switch(aNbComp){
683     case 1:
684       aSelectedDataArray->SetNumberOfComponents(1);
685       aDataSetAttributes->SetScalars(aSelectedDataArray);
686       break;
687     default:
688       aSelectedDataArray->SetNumberOfComponents(3);
689       aDataSetAttributes->SetVectors(aSelectedDataArray);
690     }
691     aSelectedDataArray->SetNumberOfTuples(aNbTuples);
692     aSelectedDataArray->SetName(aFieldName.c_str());
693
694     TVTKDataArray *aFullDataArray = TVTKDataArray::New();
695     aFullDataArray->SetNumberOfComponents(aNbComp);
696     aFullDataArray->SetNumberOfTuples(aNbTuples);
697     aFullDataArray->SetName("VISU_FIELD");
698     aDataSetAttributes->AddArray(aFullDataArray);
699
700     INITMSG(MYDEBUG,"InitTimeStampOnGaussMesh "<<
701             "- aNbTuples = "<<aNbTuples<<
702             "; aNbComp = "<<aNbComp<<
703             std::endl);
704     TTimerLog aTimerLog(MYDEBUG,"InitTimeStampOnGaussMesh");
705
706     const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
707     typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
708     typedef TTMeshValue<TVTKBasicType> TMeshValue;
709     typedef MED::SharedPtr<TMeshValue> TMeshValuePtr;
710
711     typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
712     typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
713
714     TMeshValuePtr aMeshValue = theValForTime->GetFirstMeshValue();
715     if(aGeom2MeshValue.size() == 1){
716       aFullDataArray->SetVoidArray(aMeshValue->GetPointer(),
717                                    aMeshValue->size(),
718                                    true);
719       INITMSG(MYDEBUG,"InitTimeStampOnGaussMesh - aFullDataArray->SetVoidArray()"<<std::endl);
720       if(aNbComp == 1 || aNbComp == 3){
721         aSelectedDataArray->SetVoidArray(aMeshValue->GetPointer(),
722                                          aMeshValue->size(),
723                                          true);
724         INITMSG(MYDEBUG,"InitTimeStampOnGaussMesh - aSelectedDataArray->SetVoidArray()"<<std::endl);
725       }else{
726         PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder(aSelectedDataArray));
727         TTimeStampOnGaussMeshInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
728       }
729     }else{
730       typedef TDataArrayHolder2<EDataType> TTDataArrayHolder2;
731       PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder2(aSelectedDataArray, aFullDataArray));
732       TTimeStampOnGaussMeshInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
733     }
734
735     aSelectedDataArray->Delete();
736     aFullDataArray->Delete();
737   }
738
739
740   //----------------------------------------------------------------------------
741
742   void InitMed2VisuArray(std::vector<int>& anArray, EGeometry aEGeom){
743     switch(aEGeom){
744 #if !(defined(VTK_QUADRATIC_EDGE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
745     case eSEG3:
746       anArray[0] = 0;
747       anArray[2] = 1;
748       anArray[1] = 2;
749       break;
750 #endif
751
752 #if !(defined(VTK_QUADRATIC_TRIANGLE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
753     case eTRIA6:
754       anArray[0] = 0;
755       anArray[2] = 1;
756       anArray[4] = 2;
757
758       anArray[1] = 3;
759       anArray[3] = 4;
760       anArray[5] = 5;
761       break;
762 #endif
763
764 #if !(defined(VTK_QUADRATIC_QUAD) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
765     case eQUAD8:
766       anArray[0] = 0;
767       anArray[2] = 1;
768       anArray[4] = 2;
769       anArray[6] = 3;
770
771       anArray[1] = 4;
772       anArray[3] = 5;
773       anArray[5] = 6;
774       anArray[7] = 7;
775       break;
776 #endif
777     case eTETRA4:
778       anArray[0] = 0;
779       anArray[1] = 2;
780       anArray[2] = 1;
781       anArray[3] = 3;
782       break;
783     case ePYRA5:
784       anArray[0] = 0;
785       anArray[1] = 3;
786       anArray[2] = 2;
787       anArray[3] = 1;
788       anArray[4] = 4;
789       break;
790 #if (defined(VTK_QUADRATIC_TETRA) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
791     case eTETRA10:
792       anArray[0] = 0;
793       anArray[1] = 2;
794       anArray[2] = 1;
795       anArray[3] = 3;
796
797       anArray[4] = 6;
798       anArray[5] = 5;
799       anArray[6] = 4;
800
801       anArray[7] = 7;
802       anArray[8] = 9;
803       anArray[9] = 8;
804       break;
805 #endif
806
807 #if (defined(VTK_QUADRATIC_PYRAMID) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
808     case ePYRA13:
809       anArray[0] = 0;
810       anArray[1] = 3;
811       anArray[2] = 2;
812       anArray[3] = 1;
813       anArray[4] = 4;
814
815       anArray[5] = 8;
816       anArray[6] = 7;
817       anArray[7] = 6;
818       anArray[8] = 5;
819
820       anArray[9] = 9;
821       anArray[10] = 12;
822       anArray[11] = 11;
823       anArray[12] = 10;
824       break;
825 #endif
826     default:
827       for(int i=0;i<anArray.size();i++){
828         anArray[i] = i;
829       }
830       break;
831     }
832   }
833 }