Salome HOME
b2a5ec760e2a2349d3752d620f9a19dbd0fd98f4
[modules/visu.git] / src / PIPELINE / VISU_PipeLineUtils.cxx
1 // Copyright (C) 2007-2011  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:    VISU_PipeLine.hxx
25 // Author:  Alexey PETROV
26 // Module : VISU
27 //
28 #include "VISU_PipeLineUtils.hxx"
29
30 #include "VISU_OpenGLPointSpriteMapper.hxx"
31
32 #include <vtkCell.h>
33 #include <vtkDataSetMapper.h>
34 #include <vtkPolyDataMapper.h>
35
36 namespace VISU
37 {
38   //----------------------------------------------------------------------------
39   void
40   Mul(const vtkFloatingPointType A[3], 
41       vtkFloatingPointType b, 
42       vtkFloatingPointType C[3])
43   { // A*b;
44     for(int i = 0; i < 3; i++)  
45       C[i] = A[i]*b;
46   }
47
48
49   //----------------------------------------------------------------------------
50   void
51   Sub(const vtkFloatingPointType A[3], 
52             const vtkFloatingPointType B[3], 
53             vtkFloatingPointType C[3])
54   { //A-B
55     for(int i = 0; i < 3; i++)  
56       C[i] = A[i] - B[i];
57   }
58
59
60   //----------------------------------------------------------------------------
61   bool
62   CheckIsSameValue(vtkFloatingPointType theTarget,
63                    vtkFloatingPointType theSource)
64   {
65     static vtkFloatingPointType TOL = 10.0 / VTK_LARGE_FLOAT;
66     if(fabs(theTarget - theSource)  < TOL)
67       return true;
68     return false;
69   }
70   
71
72   //----------------------------------------------------------------------------
73   bool
74   CheckIsSameRange(vtkFloatingPointType* theTarget,
75                    vtkFloatingPointType* theSource)
76   {
77     return CheckIsSameValue(theTarget[0], theSource[0]) &&
78       CheckIsSameValue(theTarget[1], theSource[1]);
79   }
80   
81
82   //----------------------------------------------------------------------------
83   void
84   CopyMapper(vtkMapper* theTarget, 
85              vtkMapper* theSource,
86              bool theIsCopyInput)
87   {
88     // To customize vtkMapper::ShallowCopy ...
89     theTarget->SetLookupTable(theSource->GetLookupTable());
90     theTarget->SetScalarVisibility(theSource->GetScalarVisibility());
91     if(theIsCopyInput){
92       vtkFloatingPointType* aScalarRange = theSource->GetScalarRange();
93       if(!CheckIsSameRange(theTarget->GetScalarRange(), aScalarRange))
94         theTarget->SetScalarRange(aScalarRange);
95     }
96     theTarget->SetColorMode(theSource->GetColorMode());
97     theTarget->SetScalarMode(theSource->GetScalarMode());
98     theTarget->SetImmediateModeRendering(theSource->GetImmediateModeRendering());
99     theTarget->SetUseLookupTableScalarRange(theSource->GetUseLookupTableScalarRange());
100     theTarget->SetInterpolateScalarsBeforeMapping(theSource->GetInterpolateScalarsBeforeMapping());
101     if(theSource->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID)
102       theTarget->ColorByArrayComponent(theSource->GetArrayId(), theSource->GetArrayComponent());
103     else
104       theTarget->ColorByArrayComponent(theSource->GetArrayName(), theSource->GetArrayComponent());
105     
106     // To customize vtkAbstractMapper3D::ShallowCopy ...
107     theTarget->SetClippingPlanes(theSource->GetClippingPlanes());
108   }
109
110
111   //----------------------------------------------------------------------------
112   void
113   CopyDataSetMapper(vtkDataSetMapper* theTarget, 
114                     vtkDataSetMapper* theSource,
115                     bool theIsCopyInput)
116   {
117     // To customize vtkDataSetMapper::ShallowCopy ...
118     //theTarget->SetInput(theSource->GetInput());
119     CopyMapper(theTarget, theSource, theIsCopyInput);
120   }
121
122
123   //----------------------------------------------------------------------------
124   void
125   CopyPolyDataMapper(vtkPolyDataMapper* theTarget, 
126                      vtkPolyDataMapper* theSource,
127                      bool theIsCopyInput)
128   {
129     // To customize vtkPolyDataMapper::ShallowCopy ...
130     //theTarget->SetInput(theSource->GetInput());
131     theTarget->SetGhostLevel(theSource->GetGhostLevel());
132     theTarget->SetNumberOfPieces(theSource->GetNumberOfPieces());
133     theTarget->SetNumberOfSubPieces(theSource->GetNumberOfSubPieces());
134
135     CopyMapper(theTarget, theSource, theIsCopyInput);
136   }
137
138
139   //----------------------------------------------------------------------------
140   void
141   CopyPointSpriteDataMapper(VISU_OpenGLPointSpriteMapper* theTarget, 
142                             VISU_OpenGLPointSpriteMapper* theSource,
143                             bool theIsCopyInput)
144   {
145     // To customize VISU_OpenGLPointSpriteMapper::ShallowCopy ...
146     theTarget->SetPrimitiveType( theSource->GetPrimitiveType() );
147     
148     theTarget->SetPointSpriteMode( theSource->GetPointSpriteMode() );
149     
150     theTarget->SetPointSpriteClamp( theSource->GetPointSpriteClamp() );
151     theTarget->SetPointSpriteSize( theSource->GetPointSpriteSize() );
152     theTarget->SetPointSpriteMinSize( theSource->GetPointSpriteMinSize() );
153     theTarget->SetPointSpriteMaxSize( theSource->GetPointSpriteMaxSize() );
154     theTarget->SetPointSpriteMagnification( theSource->GetPointSpriteMagnification() );
155     
156     theTarget->SetImageData( theSource->GetImageData() );
157     theTarget->SetPointSpriteAlphaThreshold( theSource->GetPointSpriteAlphaThreshold() );
158
159     CopyPolyDataMapper(theTarget, theSource, theIsCopyInput);
160   }
161
162
163   //----------------------------------------------------------------------------
164   void
165   ComputeBoundsParam(vtkFloatingPointType theBounds[6],
166                      vtkFloatingPointType theDirection[3], 
167                      vtkFloatingPointType theMinPnt[3],
168                      vtkFloatingPointType& theMaxBoundPrj, 
169                      vtkFloatingPointType& theMinBoundPrj)
170   {
171     vtkFloatingPointType aBounds[6];
172     for(int i = 0; i < 6; i++) 
173       aBounds[i] = theBounds[i];
174     
175     //Enlarge bounds in order to avoid conflicts of precision
176     for(int i = 0; i < 6; i += 2){
177       static double EPS = 1.0E-3;
178       vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
179       aBounds[i] -= aDelta;
180       aBounds[i+1] += aDelta;
181     }
182     
183     vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
184                                                 {aBounds[1],aBounds[2],aBounds[4]},
185                                                 {aBounds[0],aBounds[3],aBounds[4]},
186                                                 {aBounds[1],aBounds[3],aBounds[4]},
187                                                 {aBounds[0],aBounds[2],aBounds[5]},
188                                                 {aBounds[1],aBounds[2],aBounds[5]},
189                                                 {aBounds[0],aBounds[3],aBounds[5]},
190                                                 {aBounds[1],aBounds[3],aBounds[5]}};
191     
192     int aMaxId = 0, aMinId = aMaxId;
193     theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
194     theMinBoundPrj = theMaxBoundPrj;
195     for(int i = 1; i < 8; i++){
196       vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
197       if(theMaxBoundPrj < aTmp){
198         theMaxBoundPrj = aTmp;
199         aMaxId = i;
200       }
201       if(theMinBoundPrj > aTmp){
202         theMinBoundPrj = aTmp;
203         aMinId = i;
204       }
205     }
206     vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
207     theMinPnt[0] = aMinPnt[0];
208     theMinPnt[1] = aMinPnt[1];
209     theMinPnt[2] = aMinPnt[2];
210   }
211
212
213   //----------------------------------------------------------------------------
214   void
215   DistanceToPosition(vtkFloatingPointType theBounds[6],
216                      vtkFloatingPointType theDirection[3], 
217                      vtkFloatingPointType theDist, 
218                      vtkFloatingPointType thePos[3])
219   {
220     vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
221     ComputeBoundsParam(theBounds,
222                        theDirection,
223                        aMinPnt,
224                        aMaxBoundPrj,
225                        aMinBoundPrj);
226     vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
227     thePos[0] = aMinPnt[0] - theDirection[0] * aLength;
228     thePos[1] = aMinPnt[1] - theDirection[1] * aLength;
229     thePos[2] = aMinPnt[2] - theDirection[2] * aLength;
230   }
231   
232
233   //----------------------------------------------------------------------------
234   void
235   PositionToDistance(vtkFloatingPointType theBounds[6],
236                      vtkFloatingPointType theDirection[3], 
237                      vtkFloatingPointType thePos[3], 
238                      vtkFloatingPointType& theDist)
239   {
240     vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
241     ComputeBoundsParam(theBounds,
242                        theDirection,
243                        aMinPnt,
244                        aMaxBoundPrj,
245                        aMinBoundPrj);
246     vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
247     theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
248   }
249   
250   //----------------------------------------------------------------------------
251   bool
252   IsQuadraticData(vtkDataSet* theDataSet)
253   {
254     for(int i = 0, n = theDataSet->GetNumberOfCells(); i < n; i++)
255       if(vtkCell* aCell = theDataSet->GetCell(i))
256         if(!aCell->IsLinear())
257           return true;
258     return false;
259   }
260
261   //----------------------------------------------------------------------------
262   //Compute bounds of the visible part of the dataset
263   void
264   ComputeVisibleBounds(vtkDataSet* theDataSet,  vtkFloatingPointType theBounds[6]) {
265     int nbCells, i, j, minIdx, maxIdx;
266     vtkFloatingPointType cellBounds[6];
267     
268     if( theDataSet && (nbCells = theDataSet->GetNumberOfCells()) ) {
269       theDataSet->GetCellBounds(0,theBounds);
270       for ( i = 1; i < nbCells;  i++ ) {
271         theDataSet->GetCellBounds(i, cellBounds);
272         for ( j = 0; j < 3; j++ ) {
273           minIdx = 2*j;
274           maxIdx = 2*j+1;
275           if ( cellBounds[minIdx] < theBounds[minIdx] ) {
276             theBounds[minIdx] = cellBounds[minIdx];
277           }     
278           if ( cellBounds[maxIdx] > theBounds[maxIdx] ) {
279             theBounds[maxIdx] = cellBounds[maxIdx];
280           }
281         }
282       } 
283     } else {
284       vtkMath::UninitializeBounds(theBounds);
285     }
286   }
287   
288   //----------------------------------------------------------------------------
289   //Compute center of the box, box defined as xmin, xmax, ymin, ymax, zmin, zmax
290   void
291   ComputeBoxCenter(vtkFloatingPointType theBounds[6], vtkFloatingPointType theCenter[3]) {
292     for (int i=0; i<3; i++) {
293       theCenter[i] = (theBounds[2*i+1] + theBounds[2*i]) / 2.0;
294     }
295   }
296   
297   //----------------------------------------------------------------------------
298   //Compute length of the box diagonal, box defined as xmin, xmax, ymin, ymax, zmin, zmax
299   double 
300   ComputeBoxDiagonal(vtkFloatingPointType theBounds[6]) {
301     double diff, len=0.0;
302     int i;
303     for (i=0; i<3; i++) {
304       diff = (double)(theBounds[2*i+1]) - (double)(theBounds[2*i]);
305       len += diff * diff;
306     }
307     diff = sqrt(len);
308     return diff;
309   }
310 }