1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // VISU OBJECT : interactive object for VISU entities implementation
27 #include "VISU_MeshValue.hxx"
28 #include "VISU_ElnoMeshValue.hxx"
29 #include "VISU_Structures_impl.hxx"
30 #include "VISU_ConvertorUtils.hxx"
32 #include "VISU_PointCoords.hxx"
33 #include "VISU_VTKTypeList.hxx"
35 #include <vtkUnstructuredGrid.h>
36 #include <vtkPolyData.h>
38 #include <vtkPointData.h>
39 #include <vtkCellData.h>
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>
56 static int MYDEBUG = 0;
58 static int MYDEBUG = 0;
63 //---------------------------------------------------------------
65 GenerateFieldName(const PFieldImpl& theField,
66 const PValForTimeImpl& theValForTime)
68 const VISU::TTime& aTime = theValForTime->myTime;
69 std::string aFieldName = theField->myMeshName + ", " + theField->myName + ": " +
70 VISU_Convertor::GenerateName(aTime);
75 //---------------------------------------------------------------
78 ::Init(vtkIdType theNbElem,
83 myNbGauss = theNbGauss;
85 myStep = theNbComp*theNbGauss;
113 return myNbElem * myStep;
117 //----------------------------------------------------------------------------
118 template<int EDataType>
120 InitTimeStampOnProfile(const PUnstructuredGrid& theSource,
121 const PFieldImpl& theField,
122 const PValForTimeImpl& theValForTime,
123 const VISU::TEntity& theEntity);
126 //----------------------------------------------------------------------------
128 GetTimeStampOnProfile(const PUnstructuredGrid& theSource,
129 const PFieldImpl& theField,
130 const PValForTimeImpl& theValForTime,
131 const VISU::TEntity& theEntity)
133 vtkIdType aDataType = theField->GetDataType();
136 InitTimeStampOnProfile<VTK_DOUBLE>(theSource, theField, theValForTime, theEntity);
139 InitTimeStampOnProfile<VTK_FLOAT>(theSource, theField, theValForTime, theEntity);
142 InitTimeStampOnProfile<VTK_INT>(theSource, theField, theValForTime, theEntity);
145 InitTimeStampOnProfile<VTK_LONG>(theSource, theField, theValForTime, theEntity);
148 EXCEPTION(std::runtime_error,
149 "GetTimeStampOnProfile - handling unsupported data type - "<<aDataType);
154 //----------------------------------------------------------------------------
155 template<int EDataType>
156 struct TDataArrayHolder
158 typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
159 typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
160 TVTKDataArray* myDataArray;
162 TDataArrayHolder(TVTKDataArray* theDataArray):
163 myDataArray(theDataArray)
167 WritePointer(TVTKDataArray* theDataArray,
168 vtkIdType theTupleId,
169 TVTKBasicType* thePointer)
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++;
180 SetTuple(vtkIdType theTupleId,
181 TVTKBasicType* thePointer)
183 this->WritePointer(myDataArray, theTupleId, thePointer);
188 //----------------------------------------------------------------------------
189 template<int EDataType>
190 struct TDataArrayHolder2: TDataArrayHolder<EDataType>
192 typedef TDataArrayHolder<EDataType> TSuperClass;
193 typedef typename TSuperClass::TVTKDataArray TVTKDataArray;
194 typedef typename TSuperClass::TVTKBasicType TVTKBasicType;
195 TVTKDataArray* myDataArray2;
197 TDataArrayHolder2(TVTKDataArray* theDataArray,
198 TVTKDataArray* theDataArray2):
199 TSuperClass(theDataArray),
200 myDataArray2(theDataArray2)
205 SetTuple(vtkIdType theTupleId,
206 TVTKBasicType* thePointer)
208 this->WritePointer(this->myDataArray, theTupleId, thePointer);
209 this->WritePointer(this->myDataArray2, theTupleId, thePointer);
214 //----------------------------------------------------------------------------
215 template<int EDataType>
216 struct TTimeStampOnProfileInitArray
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;
223 typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
224 typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
225 PDataArrayHolder myDataArrayHolder;
227 TTimeStampOnProfileInitArray(const PDataArrayHolder& theDataArrayHolder):
228 myDataArrayHolder(theDataArrayHolder)
232 Execute(const PFieldImpl& theField,
233 const PValForTimeImpl& theValForTime)
235 vtkIdType aNbComp = theField->myNbComp;
236 vtkIdType aSize = std::max(vtkIdType(3), aNbComp);
237 TVector<TVTKBasicType> aDataValues(aSize);
239 const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
240 TGeom2MeshValue::const_iterator anIter = aGeom2MeshValue.begin();
241 for(int aTupleId = 0; anIter != aGeom2MeshValue.end(); anIter++){
242 EGeometry aEGeom = anIter->first;
243 const TMeshValuePtr aMeshValue = anIter->second;
245 vtkIdType aNbElem = aMeshValue->GetNbElem();
246 vtkIdType aNbGauss = aMeshValue->GetNbGauss();
249 "- aEGeom = "<<aEGeom<<
250 "; aNbElem = "<<aNbElem<<
251 "; aNbGauss = "<<aNbGauss<<
254 for(vtkIdType iElem = 0; iElem < aNbElem; iElem++, aTupleId++){
255 typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetCompValueSliceArr(iElem);
256 for(vtkIdType iComp = 0; iComp < aNbComp; iComp++){
257 const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iComp];
258 aDataValues[iComp] = TVTKBasicType();
259 for(vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++){
260 aDataValues[iComp] += aValueSlice[iGauss];
262 aDataValues[iComp] /= aNbGauss;
264 this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
271 //----------------------------------------------------------------------------
272 template<int EDataType>
274 InitTimeStampOnProfile(const PUnstructuredGrid& theSource,
275 const PFieldImpl& theField,
276 const PValForTimeImpl& theValForTime,
277 const VISU::TEntity& theEntity)
279 vtkIdType aNbTuples = theField->myDataSize / theField->myNbComp;
280 std::string aFieldName = VISU::GenerateFieldName(theField, theValForTime);
282 vtkDataSetAttributes* aDataSetAttributes;
283 switch ( theEntity ) {
284 case VISU::NODE_ENTITY :
285 aDataSetAttributes = theSource->GetPointData();
288 aDataSetAttributes = theSource->GetCellData();
291 typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
292 TVTKDataArray *aSelectedDataArray = TVTKDataArray::New();
293 vtkIdType aNbComp = theField->myNbComp;
297 aSelectedDataArray->SetNumberOfComponents( 1 );
298 aDataSetAttributes->SetScalars( aSelectedDataArray );
301 aSelectedDataArray->SetNumberOfComponents( 3 );
302 aDataSetAttributes->SetVectors( aSelectedDataArray );
304 aSelectedDataArray->SetNumberOfTuples( aNbTuples );
305 aSelectedDataArray->SetName( aFieldName.c_str() );
307 TVTKDataArray *aFullDataArray = TVTKDataArray::New();
308 aFullDataArray->SetNumberOfComponents( aNbComp );
309 aFullDataArray->SetNumberOfTuples( aNbTuples );
310 aFullDataArray->SetName( "VISU_FIELD" );
311 aDataSetAttributes->AddArray( aFullDataArray );
313 INITMSG(MYDEBUG,"InitTimeStampOnProfile "<<
314 "- theEntity = "<<theEntity<<
315 "; aNbTuples = "<<aNbTuples<<
316 "; aNbComp = "<<aNbComp<<
319 TTimerLog aTimerLog(MYDEBUG,"InitTimeStampOnProfile");
321 const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
322 typedef typename TL::TEnum2VTKBasicType< EDataType >::TResult TVTKBasicType;
323 typedef TTMeshValue< TVTKBasicType > TMeshValue;
324 typedef MED::SharedPtr< TMeshValue > TMeshValuePtr;
326 typedef TDataArrayHolder< EDataType > TTDataArrayHolder;
327 typedef MED::SharedPtr< TTDataArrayHolder > PDataArrayHolder;
329 TMeshValuePtr aMeshValue = theValForTime->GetFirstMeshValue();
330 if ( aGeom2MeshValue.size() == 1 && aMeshValue->GetNbGauss() == 1 ) {
331 aFullDataArray->SetVoidArray(aMeshValue->GetPointer(),
334 INITMSG(MYDEBUG,"InitTimeStampOnProfile - aFullDataArray->SetVoidArray()"<<std::endl);
335 if ( aNbComp == 1 ) {
336 aSelectedDataArray->SetVoidArray( aMeshValue->GetPointer(),
339 INITMSG(MYDEBUG,"InitTimeStampOnProfile - aSelectedDataArray->SetVoidArray()"<<std::endl);
341 PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder(aSelectedDataArray));
342 TTimeStampOnProfileInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
345 typedef TDataArrayHolder2<EDataType> TTDataArrayHolder2;
346 PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder2(aSelectedDataArray, aFullDataArray));
347 TTimeStampOnProfileInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
350 aSelectedDataArray->Delete();
351 aFullDataArray->Delete();
353 // Process the case for ELNO data
354 //-------------------------------
355 if ( theField->myIsELNO ) {
356 // To calculate effective number of components for the VTK compatibel ELNO data representation
357 vtkIdType aEffectNbTuples = 0;
358 TGeom2MeshValue::const_iterator anIter = aGeom2MeshValue.begin();
359 for ( ; anIter != aGeom2MeshValue.end(); anIter++ ) {
360 const PMeshValue& aMeshValue = anIter->second;
361 aEffectNbTuples += aMeshValue->GetNbElem() * aMeshValue->GetNbGauss();
364 vtkIdType anEffectNbComp = ( aEffectNbTuples * aNbComp ) / aNbTuples + 1;
366 // To create corresponding VTK representation for the ELNO data
367 TSetElnoNodeData< EDataType > aSetElnoNodeData( anEffectNbComp,
371 "ELNO_COMPONENT_MAPPER" );
373 std::vector< TVTKBasicType > aDataValues( aNbComp ); // To reserve a temproary value holder
375 // To initilize these VTK representation for the ELNO data from the MED
376 anIter = aGeom2MeshValue.begin();
377 for ( ; anIter != aGeom2MeshValue.end(); anIter++ ) {
378 EGeometry aEGeom = anIter->first;
379 const TMeshValuePtr aMeshValue = anIter->second;
381 vtkIdType aNbElem = aMeshValue->GetNbElem();
382 vtkIdType aNbGauss = aMeshValue->GetNbGauss();
385 "- aEGeom = "<<aEGeom<<
386 "; aNbElem = "<<aNbElem<<
387 "; aNbGauss = "<<aNbGauss<<
389 std::vector<int> med2visu(aNbGauss);
390 InitMed2VisuArray(med2visu,aEGeom);
391 for ( vtkIdType iElem = 0; iElem < aNbElem; iElem++ ) {
392 const typename TMeshValue::TValueSliceArr& aValueSliceArr = aMeshValue->GetGaussValueSliceArr( iElem );
394 for( vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++ ) {
395 const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[ med2visu[iGauss] ];
397 for( vtkIdType iComp = 0; iComp < aNbComp; iComp++ ) {
398 aDataValues[ iComp ] = aValueSlice[ iComp ];
401 aSetElnoNodeData.AddNextPointData( &aDataValues[ 0 ] );
404 aSetElnoNodeData.InsertNextCellData();
408 // Assign the ELNO data on the corresponding VTK data set attribute
409 aSetElnoNodeData.AddData( aDataSetAttributes );
411 //-------------------------------
415 //----------------------------------------------------------------------------
416 template<int EDataType>
418 InitTimeStampOnGaussMesh(const PPolyData& theSource,
419 const PFieldImpl& theField,
420 const PValForTimeImpl& theValForTime);
423 GetTimeStampOnGaussMesh(const PPolyData& theSource,
424 const PFieldImpl& theField,
425 const PValForTimeImpl& theValForTime)
427 vtkIdType aDataType = theField->GetDataType();
430 InitTimeStampOnGaussMesh<VTK_DOUBLE>(theSource, theField, theValForTime);
433 InitTimeStampOnGaussMesh<VTK_FLOAT>(theSource, theField, theValForTime);
436 InitTimeStampOnGaussMesh<VTK_INT>(theSource, theField, theValForTime);
439 InitTimeStampOnGaussMesh<VTK_LONG>(theSource, theField, theValForTime);
442 EXCEPTION(std::runtime_error,
443 "GetTimeStampOnGaussMesh - handling unsupported data type - "<<aDataType);
447 //----------------------------------------------------------------------------
448 template<int EDataType>
449 struct TTimeStampOnGaussMeshInitArray
451 typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
452 typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
453 typedef TTMeshValue<TVTKBasicType> TMeshValue;
454 typedef MED::SharedPtr<TMeshValue> TMeshValuePtr;
456 typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
457 typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
458 PDataArrayHolder myDataArrayHolder;
460 TTimeStampOnGaussMeshInitArray(const PDataArrayHolder& theDataArrayHolder):
461 myDataArrayHolder(theDataArrayHolder)
465 Execute(const PFieldImpl& theField,
466 const PValForTimeImpl& theValForTime)
468 vtkIdType aNbComp = theField->myNbComp;
469 vtkIdType aSize = std::max(vtkIdType(3), aNbComp);
470 TVector<TVTKBasicType> aDataValues(aSize);
472 const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
474 PGaussMeshImpl aGaussMesh = theValForTime->myGaussMesh;
475 const TGeom2GaussSubMesh& aGeom2GaussSubMesh = aGaussMesh->myGeom2GaussSubMesh;
476 TGeom2GaussSubMesh::const_iterator anIter = aGeom2GaussSubMesh.begin();
477 for(int aTupleId = 0; anIter != aGeom2GaussSubMesh.end(); anIter++){
478 EGeometry aEGeom = anIter->first;
480 PGaussSubMeshImpl aGaussSubMesh = anIter->second;
481 if(!aGaussSubMesh->myIsDone)
484 TGeom2MeshValue::const_iterator anIter2 = aGeom2MeshValue.find(aEGeom);
485 if(anIter2 == aGeom2MeshValue.end()){
486 EXCEPTION(std::runtime_error,
487 "TTimeStampOnGaussMeshInitArray >> Can't find values for corresponding Gauss Points SubMesh");
489 TMeshValuePtr aMeshValue = anIter2->second;
490 vtkIdType aNbGauss = aMeshValue->GetNbGauss();
491 vtkIdType aNbElem = aMeshValue->GetNbElem();
496 const TPointCoords& aCoords = aGaussSubMesh->myPointCoords;
499 "- aEGeom = "<<aEGeom<<
500 "; aNbElem = "<<aNbElem<<
501 "; aNbGauss = "<<aNbGauss<<
502 "; aCoords.GetNbPoints() = "<<aCoords.GetNbPoints()<<
505 if(aCoords.GetNbPoints() == aNbElem*aNbGauss){
506 for(int iElem = 0; iElem < aNbElem; iElem++){
507 typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetGaussValueSliceArr(iElem);
508 for(int iGauss = 0; iGauss < aNbGauss; iGauss++, aTupleId++){
509 const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iGauss];
510 for(int iComp = 0; iComp < aNbComp; iComp++){
511 aDataValues[iComp] = aValueSlice[iComp];
513 this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
517 for(int iElem = 0; iElem < aNbElem; iElem++, aTupleId++){
518 typename TMeshValue::TCValueSliceArr aValueSliceArr = aMeshValue->GetCompValueSliceArr(iElem);
519 for(int iComp = 0; iComp < aNbComp; iComp++){
520 const typename TMeshValue::TCValueSlice& aValueSlice = aValueSliceArr[iComp];
521 aDataValues[iComp] = TVTKBasicType();
522 for(int iGauss = 0; iGauss < aNbGauss; iGauss++){
523 aDataValues[iComp] += aValueSlice[iGauss];
525 aDataValues[iComp] /= aNbGauss;
527 this->myDataArrayHolder->SetTuple(aTupleId, &aDataValues[0]);
535 template<int EDataType>
537 InitTimeStampOnGaussMesh(const PPolyData& theSource,
538 const PFieldImpl& theField,
539 const PValForTimeImpl& theValForTime)
541 vtkIdType aNbTuples = theSource->GetNumberOfPoints();
542 std::string aFieldName = VISU::GenerateFieldName(theField, theValForTime);
544 vtkDataSetAttributes* aDataSetAttributes = theSource->GetPointData();
546 typedef typename TL::TEnum2VTKArrayType<EDataType>::TResult TVTKDataArray;
547 TVTKDataArray *aSelectedDataArray = TVTKDataArray::New();
548 vtkIdType aNbComp = theField->myNbComp;
551 aSelectedDataArray->SetNumberOfComponents(1);
552 aDataSetAttributes->SetScalars(aSelectedDataArray);
555 aSelectedDataArray->SetNumberOfComponents(3);
556 aDataSetAttributes->SetVectors(aSelectedDataArray);
558 aSelectedDataArray->SetNumberOfTuples(aNbTuples);
559 aSelectedDataArray->SetName(aFieldName.c_str());
561 TVTKDataArray *aFullDataArray = TVTKDataArray::New();
562 aFullDataArray->SetNumberOfComponents(aNbComp);
563 aFullDataArray->SetNumberOfTuples(aNbTuples);
564 aFullDataArray->SetName("VISU_FIELD");
565 aDataSetAttributes->AddArray(aFullDataArray);
567 INITMSG(MYDEBUG,"InitTimeStampOnGaussMesh "<<
568 "- aNbTuples = "<<aNbTuples<<
569 "; aNbComp = "<<aNbComp<<
571 TTimerLog aTimerLog(MYDEBUG,"InitTimeStampOnGaussMesh");
573 const TGeom2MeshValue& aGeom2MeshValue = theValForTime->GetGeom2MeshValue();
574 typedef typename TL::TEnum2VTKBasicType<EDataType>::TResult TVTKBasicType;
575 typedef TTMeshValue<TVTKBasicType> TMeshValue;
576 typedef MED::SharedPtr<TMeshValue> TMeshValuePtr;
578 typedef TDataArrayHolder<EDataType> TTDataArrayHolder;
579 typedef MED::SharedPtr<TTDataArrayHolder> PDataArrayHolder;
581 TMeshValuePtr aMeshValue = theValForTime->GetFirstMeshValue();
582 if(aGeom2MeshValue.size() == 1){
583 aFullDataArray->SetVoidArray(aMeshValue->GetPointer(),
586 INITMSG(MYDEBUG,"InitTimeStampOnGaussMesh - aFullDataArray->SetVoidArray()"<<std::endl);
587 if(aNbComp == 1 || aNbComp == 3){
588 aSelectedDataArray->SetVoidArray(aMeshValue->GetPointer(),
591 INITMSG(MYDEBUG,"InitTimeStampOnGaussMesh - aSelectedDataArray->SetVoidArray()"<<std::endl);
593 PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder(aSelectedDataArray));
594 TTimeStampOnGaussMeshInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
597 typedef TDataArrayHolder2<EDataType> TTDataArrayHolder2;
598 PDataArrayHolder aDataArrayHolder(new TTDataArrayHolder2(aSelectedDataArray, aFullDataArray));
599 TTimeStampOnGaussMeshInitArray<EDataType>(aDataArrayHolder).Execute(theField, theValForTime);
602 aSelectedDataArray->Delete();
603 aFullDataArray->Delete();
607 //----------------------------------------------------------------------------
609 void InitMed2VisuArray(std::vector<int>& anArray, EGeometry aEGeom){
611 #if !(defined(VTK_QUADRATIC_EDGE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
619 #if !(defined(VTK_QUADRATIC_TRIANGLE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
631 #if !(defined(VTK_QUADRATIC_QUAD) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
657 #if (defined(VTK_QUADRATIC_TETRA) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
674 #if (defined(VTK_QUADRATIC_PYRAMID) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
694 for(int i=0;i<anArray.size();i++){