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