Salome HOME
Restore support of med-2.1 in MEDWrapper
[modules/visu.git] / src / PIPELINE / VISU_PipeLineUtils.cxx
index 404baf1e69934dc638e5a0f1a9300f49682ab01e..0219054d2aa7a5ef856d31835981cf24f991e84a 100644 (file)
-//  VISU OBJECT : interactive object for VISU entities implementation
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  This library is free software; you can redistribute it and/or 
-//  modify it under the terms of the GNU Lesser General Public 
-//  License as published by the Free Software Foundation; either 
-//  version 2.1 of the License. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
+//  VISU OBJECT : interactive object for VISU entities implementation
 // File:    VISU_PipeLine.hxx
 // Author:  Alexey PETROV
 // Module : VISU
-
+//
 #include "VISU_PipeLineUtils.hxx"
 
-void
-VISU::Mul(const vtkFloatingPointType A[3], 
-         vtkFloatingPointType b, 
-         vtkFloatingPointType C[3])
-{ // A*b;
-  for(int i = 0; i < 3; i++)  C[i] = A[i]*b;
-}
+#include "VISU_OpenGLPointSpriteMapper.hxx"
 
-void
-VISU::Sub(const vtkFloatingPointType A[3], 
-         const vtkFloatingPointType B[3], 
-         vtkFloatingPointType C[3])
-{ //A-B
-  for(int i = 0; i < 3; i++)  C[i] = A[i] - B[i];
-}
+#include <vtkCell.h>
+#include <vtkDataSetMapper.h>
+#include <vtkPolyDataMapper.h>
+
+namespace VISU
+{
+  //----------------------------------------------------------------------------
+  void
+  Mul(const vtkFloatingPointType A[3], 
+      vtkFloatingPointType b, 
+      vtkFloatingPointType C[3])
+  { // A*b;
+    for(int i = 0; i < 3; i++)  
+      C[i] = A[i]*b;
+  }
+
+
+  //----------------------------------------------------------------------------
+  void
+  Sub(const vtkFloatingPointType A[3], 
+            const vtkFloatingPointType B[3], 
+            vtkFloatingPointType C[3])
+  { //A-B
+    for(int i = 0; i < 3; i++)  
+      C[i] = A[i] - B[i];
+  }
+
+
+  //----------------------------------------------------------------------------
+  bool
+  CheckIsSameValue(vtkFloatingPointType theTarget,
+                   vtkFloatingPointType theSource)
+  {
+    static vtkFloatingPointType TOL = 10.0 / VTK_LARGE_FLOAT;
+    if(fabs(theTarget - theSource)  < TOL)
+      return true;
+    return false;
+  }
+  
+
+  //----------------------------------------------------------------------------
+  bool
+  CheckIsSameRange(vtkFloatingPointType* theTarget,
+                   vtkFloatingPointType* theSource)
+  {
+    return CheckIsSameValue(theTarget[0], theSource[0]) &&
+      CheckIsSameValue(theTarget[1], theSource[1]);
+  }
+  
 
+  //----------------------------------------------------------------------------
+  void
+  CopyMapper(vtkMapper* theTarget, 
+             vtkMapper* theSource,
+             bool theIsCopyInput)
+  {
+    // To customize vtkMapper::ShallowCopy ...
+    theTarget->SetLookupTable(theSource->GetLookupTable());
+    theTarget->SetScalarVisibility(theSource->GetScalarVisibility());
+    if(theIsCopyInput){
+      vtkFloatingPointType* aScalarRange = theSource->GetScalarRange();
+      if(!CheckIsSameRange(theTarget->GetScalarRange(), aScalarRange))
+        theTarget->SetScalarRange(aScalarRange);
+    }
+    theTarget->SetColorMode(theSource->GetColorMode());
+    theTarget->SetScalarMode(theSource->GetScalarMode());
+    theTarget->SetImmediateModeRendering(theSource->GetImmediateModeRendering());
+    theTarget->SetUseLookupTableScalarRange(theSource->GetUseLookupTableScalarRange());
+    theTarget->SetInterpolateScalarsBeforeMapping(theSource->GetInterpolateScalarsBeforeMapping());
+    if(theSource->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID)
+      theTarget->ColorByArrayComponent(theSource->GetArrayId(), theSource->GetArrayComponent());
+    else
+      theTarget->ColorByArrayComponent(theSource->GetArrayName(), theSource->GetArrayComponent());
+    
+    // To customize vtkAbstractMapper3D::ShallowCopy ...
+    theTarget->SetClippingPlanes(theSource->GetClippingPlanes());
+  }
+
+
+  //----------------------------------------------------------------------------
+  void
+  CopyDataSetMapper(vtkDataSetMapper* theTarget, 
+                    vtkDataSetMapper* theSource,
+                    bool theIsCopyInput)
+  {
+    // To customize vtkDataSetMapper::ShallowCopy ...
+    //theTarget->SetInput(theSource->GetInput());
+    CopyMapper(theTarget, theSource, theIsCopyInput);
+  }
+
+
+  //----------------------------------------------------------------------------
+  void
+  CopyPolyDataMapper(vtkPolyDataMapper* theTarget, 
+                     vtkPolyDataMapper* theSource,
+                     bool theIsCopyInput)
+  {
+    // To customize vtkPolyDataMapper::ShallowCopy ...
+    //theTarget->SetInput(theSource->GetInput());
+    theTarget->SetGhostLevel(theSource->GetGhostLevel());
+    theTarget->SetNumberOfPieces(theSource->GetNumberOfPieces());
+    theTarget->SetNumberOfSubPieces(theSource->GetNumberOfSubPieces());
+
+    CopyMapper(theTarget, theSource, theIsCopyInput);
+  }
+
+
+  //----------------------------------------------------------------------------
+  void
+  CopyPointSpriteDataMapper(VISU_OpenGLPointSpriteMapper* theTarget, 
+                            VISU_OpenGLPointSpriteMapper* theSource,
+                            bool theIsCopyInput)
+  {
+    // To customize VISU_OpenGLPointSpriteMapper::ShallowCopy ...
+    theTarget->SetPrimitiveType( theSource->GetPrimitiveType() );
+    
+    theTarget->SetPointSpriteMode( theSource->GetPointSpriteMode() );
+    
+    theTarget->SetPointSpriteClamp( theSource->GetPointSpriteClamp() );
+    theTarget->SetPointSpriteSize( theSource->GetPointSpriteSize() );
+    theTarget->SetPointSpriteMinSize( theSource->GetPointSpriteMinSize() );
+    theTarget->SetPointSpriteMaxSize( theSource->GetPointSpriteMaxSize() );
+    theTarget->SetPointSpriteMagnification( theSource->GetPointSpriteMagnification() );
+    
+    theTarget->SetImageData( theSource->GetImageData() );
+    theTarget->SetPointSpriteAlphaThreshold( theSource->GetPointSpriteAlphaThreshold() );
+
+    CopyPolyDataMapper(theTarget, theSource, theIsCopyInput);
+  }
+
+
+  //----------------------------------------------------------------------------
+  void
+  ComputeBoundsParam(vtkFloatingPointType theBounds[6],
+                     vtkFloatingPointType theDirection[3], 
+                     vtkFloatingPointType theMinPnt[3],
+                     vtkFloatingPointType& theMaxBoundPrj, 
+                     vtkFloatingPointType& theMinBoundPrj)
+  {
+    vtkFloatingPointType aBounds[6];
+    for(int i = 0; i < 6; i++) 
+      aBounds[i] = theBounds[i];
+    
+    //Enlarge bounds in order to avoid conflicts of precision
+    for(int i = 0; i < 6; i += 2){
+      static double EPS = 1.0E-3;
+      vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
+      aBounds[i] -= aDelta;
+      aBounds[i+1] += aDelta;
+    }
+    
+    vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
+                                                {aBounds[1],aBounds[2],aBounds[4]},
+                                                {aBounds[0],aBounds[3],aBounds[4]},
+                                                {aBounds[1],aBounds[3],aBounds[4]},
+                                                {aBounds[0],aBounds[2],aBounds[5]},
+                                                {aBounds[1],aBounds[2],aBounds[5]},
+                                                {aBounds[0],aBounds[3],aBounds[5]},
+                                                {aBounds[1],aBounds[3],aBounds[5]}};
+    
+    int aMaxId = 0, aMinId = aMaxId;
+    theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
+    theMinBoundPrj = theMaxBoundPrj;
+    for(int i = 1; i < 8; i++){
+      vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
+      if(theMaxBoundPrj < aTmp){
+        theMaxBoundPrj = aTmp;
+        aMaxId = i;
+      }
+      if(theMinBoundPrj > aTmp){
+        theMinBoundPrj = aTmp;
+        aMinId = i;
+      }
+    }
+    vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
+    theMinPnt[0] = aMinPnt[0];
+    theMinPnt[1] = aMinPnt[1];
+    theMinPnt[2] = aMinPnt[2];
+  }
+
+
+  //----------------------------------------------------------------------------
+  void
+  DistanceToPosition(vtkFloatingPointType theBounds[6],
+                     vtkFloatingPointType theDirection[3], 
+                     vtkFloatingPointType theDist, 
+                     vtkFloatingPointType thePos[3])
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,
+                       theDirection,
+                       aMinPnt,
+                       aMaxBoundPrj,
+                       aMinBoundPrj);
+    vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
+    thePos[0] = aMinPnt[0] - theDirection[0] * aLength;
+    thePos[1] = aMinPnt[1] - theDirection[1] * aLength;
+    thePos[2] = aMinPnt[2] - theDirection[2] * aLength;
+  }
+  
+
+  //----------------------------------------------------------------------------
+  void
+  PositionToDistance(vtkFloatingPointType theBounds[6],
+                     vtkFloatingPointType theDirection[3], 
+                     vtkFloatingPointType thePos[3], 
+                     vtkFloatingPointType& theDist)
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,
+                       theDirection,
+                       aMinPnt,
+                       aMaxBoundPrj,
+                       aMinBoundPrj);
+    vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
+    theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
+  }
+  
+  //----------------------------------------------------------------------------
+  bool
+  IsQuadraticData(vtkDataSet* theDataSet)
+  {
+    for(int i = 0, n = theDataSet->GetNumberOfCells(); i < n; i++)
+      if(vtkCell* aCell = theDataSet->GetCell(i))
+        if(!aCell->IsLinear())
+          return true;
+    return false;
+  }
+
+  //----------------------------------------------------------------------------
+  //Compute bounds of the visible part of the dataset
+  void
+  ComputeVisibleBounds(vtkDataSet* theDataSet,  vtkFloatingPointType theBounds[6]) {
+    int nbCells, i, j, minIdx, maxIdx;
+    vtkFloatingPointType cellBounds[6];
+    
+    if( theDataSet && (nbCells = theDataSet->GetNumberOfCells()) ) {
+      theDataSet->GetCellBounds(0,theBounds);
+      for ( i = 1; i < nbCells;  i++ ) {
+       theDataSet->GetCellBounds(i, cellBounds);
+       for ( j = 0; j < 3; j++ ) {
+         minIdx = 2*j;
+         maxIdx = 2*j+1;
+         if ( cellBounds[minIdx] < theBounds[minIdx] ) {
+           theBounds[minIdx] = cellBounds[minIdx];
+         }     
+         if ( cellBounds[maxIdx] > theBounds[maxIdx] ) {
+           theBounds[maxIdx] = cellBounds[maxIdx];
+         }
+       }
+      } 
+    } else {
+      vtkMath::UninitializeBounds(theBounds);
+    }
+  }
+  
+  //----------------------------------------------------------------------------
+  //Compute center of the box, box defined as xmin, xmax, ymin, ymax, zmin, zmax
+  void
+  ComputeBoxCenter(vtkFloatingPointType theBounds[6], vtkFloatingPointType theCenter[3]) {
+    for (int i=0; i<3; i++) {
+      theCenter[i] = (theBounds[2*i+1] + theBounds[2*i]) / 2.0;
+    }
+  }
+  
+  //----------------------------------------------------------------------------
+  //Compute length of the box diagonal, box defined as xmin, xmax, ymin, ymax, zmin, zmax
+  double 
+  ComputeBoxDiagonal(vtkFloatingPointType theBounds[6]) {
+    double diff, len=0.0;
+    int i;
+    for (i=0; i<3; i++) {
+      diff = (double)(theBounds[2*i+1]) - (double)(theBounds[2*i]);
+      len += diff * diff;
+    }
+    diff = sqrt(len);
+    return diff;
+  }
+}