Salome HOME
Fix for Bug IPAL8945
[modules/visu.git] / src / PIPELINE / VISU_FieldTransform.cxx
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : VISU_FieldTransform.cxx
6 //  Module : VISU
7
8 #include "VISU_FieldTransform.hxx"
9 #include "VTKViewer_Transform.h"
10
11 #include <vtkObjectFactory.h>
12 #include <vtkFloatArray.h>
13 #include <vtkPointData.h>
14 #include <vtkCellData.h>
15 #include <vtkDataSet.h>
16 #include <vtkMath.h>
17
18 static float Tolerance = 1.0 / VTK_LARGE_FLOAT;
19
20 using namespace std;
21
22 vtkStandardNewMacro(VISU_FieldTransform);
23
24 double
25 VISU_FieldTransform
26 ::Ident(double theArg)
27 {
28   return theArg;
29 }
30
31 double
32 VISU_FieldTransform
33 ::Log10(double theArg)
34 {
35   if(theArg <= 0.0) 
36     return -VTK_LARGE_FLOAT;
37
38   return log10(theArg);
39 }
40
41
42 VISU_FieldTransform
43 ::VISU_FieldTransform()
44 {
45   myFunction = &Ident;
46   myTransform = NULL;
47
48   myScalarRange[0] = VTK_LARGE_FLOAT;
49   myScalarRange[1] = -VTK_LARGE_FLOAT;
50 }
51
52 VISU_FieldTransform
53 ::~VISU_FieldTransform() 
54 {
55   SetSpaceTransform(NULL);
56 }
57
58
59 void
60 VISU_FieldTransform
61 ::Update()
62 {
63   vtkSource::Update();
64 }
65
66 unsigned long 
67 VISU_FieldTransform
68 ::GetMTime()
69 {
70   unsigned long aTime = Superclass::GetMTime();
71   if(myTransform)
72     aTime = max(aTime,myTransform->GetMTime());
73
74   return aTime;
75 }
76
77 void
78 VISU_FieldTransform
79 ::SetScalarTransform(TTransformFun theFunction) 
80 {
81   if(myFunction == theFunction)
82     return;
83
84   if(theFunction == NULL) 
85     theFunction = &Ident;
86
87   myFunction = theFunction;
88
89   Modified();
90 }
91
92 void VISU_FieldTransform::SetSpaceTransform(VTKViewer_Transform* theTransform){
93   if(myTransform == theTransform)
94     return;
95
96   if(myTransform != NULL) 
97     myTransform->UnRegister(this);
98
99   myTransform = theTransform;
100
101   if(theTransform != NULL) 
102     theTransform->Register(this);
103
104   Modified();
105 }
106
107
108 void
109 VISU_FieldTransform
110 ::SetScalarRange(float theScalarRange[2]) 
111 {
112   float aDelta = 
113     fabs(myScalarRange[0] - theScalarRange[0]) + 
114     fabs(myScalarRange[1] - theScalarRange[1]);
115   if(aDelta < Tolerance)
116     return;
117
118   myScalarRange[0] = theScalarRange[0];
119   myScalarRange[1] = theScalarRange[1];
120
121   Modified();
122 }
123
124 void
125 VISU_FieldTransform
126 ::SetScalarMin(float theValue)
127 {
128   float aScalarRange[2] = {theValue, GetScalarRange()[1]};
129   SetScalarRange(aScalarRange);
130 }
131
132 void
133 VISU_FieldTransform
134 ::SetScalarMax(float theValue)
135 {
136   float aScalarRange[2] = {GetScalarRange()[0], theValue};
137   SetScalarRange(aScalarRange);
138 }
139
140
141 template<typename TypeData> void
142 ExecVectors(VISU_FieldTransform::TTransformFun theFunction,
143             VTKViewer_Transform* theTransform,
144             float theScalarRange[2], 
145             int theNbOfTuples,
146             TypeData* theInputData, 
147             TypeData* theOutputData)
148 {
149   vtkDataArray *anInVectors = theInputData->GetVectors();
150   if ( !anInVectors || theNbOfTuples < 1 ) 
151     return;
152   vtkFloatArray *aNewVectors = vtkFloatArray::New();
153   aNewVectors->SetNumberOfComponents(3);
154   aNewVectors->SetNumberOfTuples(theNbOfTuples);
155   float aScalarRange[2] = {(*theFunction)(theScalarRange[0]),(*theFunction)(theScalarRange[1])};
156   float aDelta = aScalarRange[1] - aScalarRange[0];
157   float aScale[3] = {1.0, 1.0, 1.0};
158   static float EPS = 1.0 / VTK_LARGE_FLOAT;
159   if(theTransform){
160     aScale[0] = theTransform->GetScale()[0];
161     aScale[1] = theTransform->GetScale()[1];
162     aScale[2] = theTransform->GetScale()[2];
163   }
164   if(theFunction == &(VISU_FieldTransform::Ident)){
165     for (int aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
166       float anInVec[3];
167       anInVectors->GetTuple(aTupleId,anInVec);
168       float anNewVec[3];
169       anNewVec[0] = anInVec[0]*aScale[0];
170       anNewVec[1] = anInVec[1]*aScale[1];
171       anNewVec[2] = anInVec[2]*aScale[2];
172       aNewVectors->SetTuple(aTupleId,anNewVec);
173     }
174   }else{
175     for (int aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
176       float anInVec[3];
177       anInVectors->GetTuple(aTupleId,anInVec);
178       float aMagn = vtkMath::Norm(anInVec);
179       if(aMagn > EPS)
180         aMagn = ((*theFunction)(aMagn) - aScalarRange[0]) / aDelta * theScalarRange[1] / aMagn;
181       if(aMagn < 0.0) 
182         aMagn = 0.0;
183       float anNewVec[3];
184       anNewVec[0] = anInVec[0]*aMagn*aScale[0];
185       anNewVec[1] = anInVec[1]*aMagn*aScale[1];
186       anNewVec[2] = anInVec[2]*aMagn*aScale[2];
187       aNewVectors->SetTuple(aTupleId,anNewVec);
188     }
189   }
190   theOutputData->SetVectors(aNewVectors);
191   aNewVectors->Delete();
192 }
193
194 template<typename TypeData> void
195 ExecScalars(VISU_FieldTransform::TTransformFun theFunction, 
196             float theScalarRange[2],
197             int theNbOfTuples, 
198             TypeData* theInputData, 
199             TypeData* theOutputData)
200 {
201   vtkDataArray *anInScalars = theInputData->GetScalars();
202   if ( !anInScalars || theNbOfTuples < 1 )
203     return;
204   vtkFloatArray *aNewScalars = vtkFloatArray::New();
205   aNewScalars->SetNumberOfComponents(1);
206   aNewScalars->SetNumberOfTuples(theNbOfTuples);
207   float aScalarRange[2] = {(*theFunction)(theScalarRange[0]),(*theFunction)(theScalarRange[1])};
208   for (int aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
209     float aScalar = (*theFunction)(anInScalars->GetTuple1(aTupleId));
210     if(aScalar < aScalarRange[0]) 
211       aScalar = aScalarRange[0];
212     aNewScalars->SetTuple1(aTupleId,aScalar);
213   }
214   theOutputData->SetScalars(aNewScalars);
215   aNewScalars->Delete();
216 }
217
218 void
219 VISU_FieldTransform
220 ::Execute()
221 {
222   vtkDataSet *input = this->GetInput(), *output = this->GetOutput();
223   output->CopyStructure(input);
224   if(myFunction != &Ident || (myTransform && !myTransform->IsIdentity())){
225     output->GetPointData()->CopyAllOff();
226     output->GetCellData()->CopyAllOff();
227
228     ExecScalars(myFunction,myScalarRange,input->GetNumberOfPoints(),input->GetPointData(),output->GetPointData());
229     ExecVectors(myFunction,myTransform,myScalarRange,input->GetNumberOfPoints(),input->GetPointData(),output->GetPointData());
230
231     ExecScalars(myFunction,myScalarRange,input->GetNumberOfCells(),input->GetCellData(),output->GetCellData());
232     ExecVectors(myFunction,myTransform,myScalarRange,input->GetNumberOfCells(),input->GetCellData(),output->GetCellData());
233   }else{
234     output->GetPointData()->CopyAllOn();
235     output->GetCellData()->CopyAllOn();
236
237     output->GetPointData()->PassData(input->GetPointData());
238     output->GetCellData()->PassData(input->GetCellData());
239   }
240 }