Salome HOME
7816f8efed11371c8e0f525a566acad4120c6f7f
[modules/visu.git] / src / PIPELINE / VISU_FieldTransform.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
4 //  This library is free software; you can redistribute it and/or 
5 //  modify it under the terms of the GNU Lesser General Public 
6 //  License as published by the Free Software Foundation; either 
7 //  version 2.1 of the License. 
8 // 
9 //  This library is distributed in the hope that it will be useful, 
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 //  Lesser General Public License for more details. 
13 // 
14 //  You should have received a copy of the GNU Lesser General Public 
15 //  License along with this library; if not, write to the Free Software 
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 // 
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : VISU_FieldTransform.cxx
21 //  Module : VISU
22
23 #include "VISU_FieldTransform.hxx"
24 #include "VTKViewer_Transform.h"
25 #include "VISU_PipeLineUtils.hxx"
26
27 #include <vtkObjectFactory.h>
28 #include <vtkPointData.h>
29 #include <vtkCellData.h>
30 #include <vtkDataSet.h>
31 #include <vtkMath.h>
32 #include <vtkInformation.h>
33 #include <vtkInformationVector.h>
34
35 static vtkFloatingPointType Tolerance = 1.0 / VTK_LARGE_FLOAT;
36
37 //----------------------------------------------------------------------------
38 vtkStandardNewMacro(VISU_FieldTransform);
39
40 //----------------------------------------------------------------------------
41 double
42 VISU_FieldTransform
43 ::Ident(double theArg)
44 {
45   return theArg;
46 }
47
48 //----------------------------------------------------------------------------
49 double
50 VISU_FieldTransform
51 ::Log10(double theArg)
52 {
53   if(theArg <= 0.0) 
54     return -VTK_LARGE_FLOAT;
55
56   return log10(theArg);
57 }
58
59
60 //----------------------------------------------------------------------------
61 VISU_FieldTransform
62 ::VISU_FieldTransform()
63 {
64   myFunction = &Ident;
65   myTransform = NULL;
66
67   myScalarRange[0] = VTK_LARGE_FLOAT;
68   myScalarRange[1] = -VTK_LARGE_FLOAT;
69 }
70
71 //----------------------------------------------------------------------------
72 VISU_FieldTransform
73 ::~VISU_FieldTransform() 
74 {
75   SetSpaceTransform(NULL);
76 }
77
78
79 unsigned long 
80 VISU_FieldTransform
81 ::GetMTime()
82 {
83   unsigned long aTime = Superclass::GetMTime();
84   if(myTransform)
85     aTime = std::max(aTime, myTransform->GetMTime());
86
87   return aTime;
88 }
89
90 //----------------------------------------------------------------------------
91 void
92 VISU_FieldTransform
93 ::SetScalarTransform(TTransformFun theFunction) 
94 {
95   if(myFunction == theFunction)
96     return;
97
98   if(theFunction == NULL) 
99     theFunction = &Ident;
100
101   myFunction = theFunction;
102
103   Modified();
104 }
105
106 //----------------------------------------------------------------------------
107 void 
108 VISU_FieldTransform
109 ::SetSpaceTransform(VTKViewer_Transform* theTransform)
110 {
111   if(myTransform == theTransform)
112     return;
113
114   if(myTransform != NULL) 
115     myTransform->UnRegister(this);
116
117   myTransform = theTransform;
118
119   if(theTransform != NULL) 
120     theTransform->Register(this);
121
122   Modified();
123 }
124
125
126 //----------------------------------------------------------------------------
127 void
128 VISU_FieldTransform
129 ::SetScalarRange(vtkFloatingPointType theScalarRange[2]) 
130 {
131   if(VISU::CheckIsSameRange(theScalarRange, myScalarRange))
132     return;
133
134   myScalarRange[0] = theScalarRange[0];
135   myScalarRange[1] = theScalarRange[1];
136
137   Modified();
138 }
139
140 //----------------------------------------------------------------------------
141 void
142 VISU_FieldTransform
143 ::SetScalarMin(vtkFloatingPointType theValue)
144 {
145   vtkFloatingPointType aScalarRange[2] = {theValue, GetScalarRange()[1]};
146   SetScalarRange(aScalarRange);
147 }
148
149 //----------------------------------------------------------------------------
150 void
151 VISU_FieldTransform
152 ::SetScalarMax(vtkFloatingPointType theValue)
153 {
154   vtkFloatingPointType aScalarRange[2] = {GetScalarRange()[0], theValue};
155   SetScalarRange(aScalarRange);
156 }
157
158 //----------------------------------------------------------------------------
159 template<typename TValueType> 
160 void
161 LinearTransformVectors(TValueType* theInputPtr,
162                        TValueType* theOutputPtr,
163                        vtkIdType theNbOfTuples,
164                        vtkFloatingPointType theScale[3])
165 {
166   for(vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++){
167     for(vtkIdType aComponentId = 0; aComponentId < 3; aComponentId++){
168       *theOutputPtr = TValueType(*theInputPtr * theScale[aComponentId]);
169       theOutputPtr++;
170       theInputPtr++;
171     }
172   }
173 }
174
175
176 //----------------------------------------------------------------------------
177 template<typename TValueType> 
178 void
179 NonLinearTransformVectors(vtkDataArray *theInputVectors,
180                           TValueType* theInputPtr,
181                           TValueType* theOutputPtr,
182                           vtkIdType theNbOfTuples,
183                           vtkFloatingPointType theScale[3],
184                           VISU_FieldTransform::TTransformFun theFunction,
185                           vtkFloatingPointType theModifiedScalarMin,
186                           vtkFloatingPointType theModifiedScalarDelta,
187                           vtkFloatingPointType theSourceScalarMax)
188 {
189   for(vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++){
190     vtkFloatingPointType anInputVector[3];
191     theInputVectors->GetTuple(aTupleId, anInputVector);
192     vtkFloatingPointType aMagnification = vtkMath::Norm(anInputVector);
193     if(aMagnification > Tolerance)
194       aMagnification = 
195         ((*theFunction)(aMagnification) - theModifiedScalarMin) / 
196         theModifiedScalarDelta * theSourceScalarMax / 
197         aMagnification;
198     if(aMagnification < 0.0) 
199       aMagnification = 0.0;
200     for(vtkIdType aComponentId = 0; aComponentId < 3; aComponentId++){
201       *theOutputPtr = TValueType(*theInputPtr * aMagnification * theScale[aComponentId]);
202       theOutputPtr++;
203       theInputPtr++;
204     }
205   }
206 }
207
208
209 //----------------------------------------------------------------------------
210 template<typename TDataSetAttributesType> 
211 void
212 ExecuteVectors(VISU_FieldTransform::TTransformFun theFunction,
213                VTKViewer_Transform* theTransform,
214                vtkFloatingPointType theScalarRange[2], 
215                vtkIdType theNbOfTuples,
216                TDataSetAttributesType* theInputData, 
217                TDataSetAttributesType* theOutputData)
218 {
219   vtkDataArray *anInputVectors = theInputData->GetVectors();
220   if(!anInputVectors || theNbOfTuples < 1) 
221     return;
222
223   vtkFloatingPointType aScalarRange[2];
224   aScalarRange[0] = (*theFunction)(theScalarRange[0]);
225   aScalarRange[1] = (*theFunction)(theScalarRange[1]);
226
227   vtkFloatingPointType aScalarDelta = aScalarRange[1] - aScalarRange[0];
228   vtkFloatingPointType aScale[3] = {1.0, 1.0, 1.0};
229
230   if(theTransform){
231     aScale[0] = theTransform->GetScale()[0];
232     aScale[1] = theTransform->GetScale()[1];
233     aScale[2] = theTransform->GetScale()[2];
234   }
235
236   vtkIdType anInputDataType = anInputVectors->GetDataType();
237   vtkDataArray *anOutputVectors = vtkDataArray::CreateDataArray(anInputDataType);
238   anOutputVectors->SetNumberOfComponents(3);
239   anOutputVectors->SetNumberOfTuples(theNbOfTuples);
240
241   void *anInputPtr = anInputVectors->GetVoidPointer(0);
242   void *anOutputPtr = anOutputVectors->GetVoidPointer(0);
243
244   if(theFunction == &(VISU_FieldTransform::Ident)){
245     switch(anInputDataType){
246       vtkTemplateMacro4(LinearTransformVectors,
247                         (VTK_TT *)(anInputPtr), 
248                         (VTK_TT *)(anOutputPtr), 
249                         theNbOfTuples,
250                         aScale);
251     default:
252       break;
253     }  
254   }else{
255     switch(anInputDataType){
256       vtkTemplateMacro9(NonLinearTransformVectors,
257                         anInputVectors,
258                         (VTK_TT *)(anInputPtr), 
259                         (VTK_TT *)(anOutputPtr), 
260                         theNbOfTuples,
261                         aScale,
262                         theFunction,
263                         aScalarRange[0],
264                         aScalarDelta,
265                         theScalarRange[1]);
266     default:
267       break;
268     }  
269   }
270
271   theOutputData->SetVectors(anOutputVectors);
272   anOutputVectors->Delete();
273 }
274
275
276 //----------------------------------------------------------------------------
277 template<typename TValueType> 
278 void
279 NonLinearTransformScalars(vtkDataArray *theInputScalars,
280                           TValueType* theInputPtr,
281                           TValueType* theOutputPtr,
282                           vtkIdType theNbOfTuples,
283                           VISU_FieldTransform::TTransformFun theFunction,
284                           vtkFloatingPointType theModifiedScalarMin)
285 {
286   for(vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++){
287     vtkFloatingPointType aScalar = (*theFunction)(vtkFloatingPointType(*theInputPtr));
288     if(aScalar < theModifiedScalarMin) 
289       aScalar = theModifiedScalarMin;
290     *theOutputPtr = TValueType(aScalar);
291     theOutputPtr++;
292     theInputPtr++;
293   }
294 }
295
296
297 //----------------------------------------------------------------------------
298 template<typename TDataSetAttributesType> 
299 void
300 ExecuteScalars(VISU_FieldTransform::TTransformFun theFunction, 
301                vtkFloatingPointType theScalarRange[2],
302                vtkIdType theNbOfTuples, 
303                TDataSetAttributesType* theInputData, 
304                TDataSetAttributesType* theOutputData)
305 {
306   vtkDataArray *anInputScalars = theInputData->GetScalars();
307   if(!anInputScalars || theNbOfTuples < 1)
308     return;
309
310   vtkFloatingPointType aScalarRange[2];
311   aScalarRange[0] = (*theFunction)(theScalarRange[0]);
312   aScalarRange[1] = (*theFunction)(theScalarRange[1]);
313
314   vtkIdType anInputDataType = anInputScalars->GetDataType();
315   vtkDataArray *anOutputScalars = vtkDataArray::CreateDataArray(anInputDataType);
316   anOutputScalars->SetNumberOfComponents(1);
317   anOutputScalars->SetNumberOfTuples(theNbOfTuples);
318
319   void *anInputPtr = anInputScalars->GetVoidPointer(0);
320   void *anOutputPtr = anOutputScalars->GetVoidPointer(0);
321
322   switch(anInputDataType){
323     vtkTemplateMacro6(NonLinearTransformScalars,
324                       anInputScalars,
325                       (VTK_TT *)(anInputPtr), 
326                       (VTK_TT *)(anOutputPtr), 
327                       theNbOfTuples,
328                       theFunction,
329                       aScalarRange[0]);
330   default:
331     break;
332   }  
333   
334   theOutputData->SetScalars(anOutputScalars);
335   anOutputScalars->Delete();
336 }
337
338
339 //----------------------------------------------------------------------------
340 int
341 VISU_FieldTransform
342 ::RequestData(vtkInformation *vtkNotUsed(request),
343               vtkInformationVector **inputVector,
344               vtkInformationVector *outputVector)
345 {
346   // get the info objects
347   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
348   vtkInformation *outInfo = outputVector->GetInformationObject(0);
349
350   // get the input and ouptut
351   vtkDataSet *input = vtkDataSet::SafeDownCast(
352     inInfo->Get(vtkDataObject::DATA_OBJECT()));
353   vtkDataSet *output = vtkDataSet::SafeDownCast(
354     outInfo->Get(vtkDataObject::DATA_OBJECT()));
355
356   output->CopyStructure(input);
357   if(myFunction != &Ident || (myTransform && !myTransform->IsIdentity())){
358     output->GetPointData()->CopyScalarsOff();
359     output->GetPointData()->CopyVectorsOff();
360
361     output->GetCellData()->CopyScalarsOff();
362     output->GetCellData()->CopyVectorsOff();
363
364     ExecuteScalars(myFunction,
365                    myScalarRange,
366                    input->GetNumberOfPoints(),
367                    input->GetPointData(),
368                    output->GetPointData());
369
370     ExecuteVectors(myFunction,
371                    myTransform,
372                    myScalarRange,
373                    input->GetNumberOfPoints(),
374                    input->GetPointData(),
375                    output->GetPointData());
376
377     ExecuteScalars(myFunction,
378                    myScalarRange,
379                    input->GetNumberOfCells(),
380                    input->GetCellData(),
381                    output->GetCellData());
382
383     ExecuteVectors(myFunction,
384                    myTransform,
385                    myScalarRange,
386                    input->GetNumberOfCells(),
387                    input->GetCellData(),
388                    output->GetCellData());
389   }else{
390     output->GetPointData()->CopyAllOn();
391     output->GetCellData()->CopyAllOn();
392
393     output->GetPointData()->PassData(input->GetPointData());
394     output->GetCellData()->PassData(input->GetCellData());
395   }
396
397   output->GetPointData()->PassData(input->GetPointData());
398   output->GetCellData()->PassData(input->GetCellData());
399   return 1;
400 }
401
402
403 //----------------------------------------------------------------------------