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