Salome HOME
MPV: Merge V1_2d
[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 "SALOME_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 using namespace std;
19
20 #ifdef DEBUG
21 static int MYDEBUG = 0;
22 #else
23 static int MYDEBUG = 0;
24 #endif
25
26 vtkStandardNewMacro(VISU_FieldTransform);
27
28 double VISU_FieldTransform::Ident(double theArg){ 
29   return theArg;
30 }
31 double VISU_FieldTransform::Log10(double theArg){ 
32   if(theArg <= 0.0) return -VTK_LARGE_FLOAT;
33   return log10(theArg);
34 }
35
36
37 VISU_FieldTransform::VISU_FieldTransform(){
38   myFunction = &Ident;
39   myTransform = NULL;
40 }
41
42 VISU_FieldTransform::~VISU_FieldTransform() {
43   SetSpaceTransform(NULL);
44 }
45
46
47 void VISU_FieldTransform::Update(){
48   if(myTransform && myTransform->GetMTime() > vtkSource::GetMTime())
49     Modified();
50   vtkSource::Update();
51 }
52
53 unsigned long VISU_FieldTransform::GetMTime(){
54   if(myTransform && myTransform->GetMTime() > vtkSource::GetMTime())
55     return myTransform->GetMTime();
56   return vtkSource::GetMTime();
57 }
58
59 void VISU_FieldTransform::SetScalarTransform(TTransformFun theFunction) { 
60   myFunction = theFunction;
61   if(myFunction == NULL) myFunction = &Ident;
62   Modified();
63 }
64
65 void VISU_FieldTransform::SetSpaceTransform(SALOME_Transform* theTransform){
66   if(myTransform != theTransform){
67     if (myTransform != NULL) myTransform->UnRegister(this);
68     myTransform = theTransform;
69     if (myTransform != NULL) myTransform->Register(this);
70     this->Modified();
71   }
72 }
73
74
75 void VISU_FieldTransform::SetScalarRange(float theScalarRange[2]) { 
76   myScalarRange[0] = theScalarRange[0];
77   myScalarRange[1] = theScalarRange[1];
78   Modified();
79 }
80 void VISU_FieldTransform::SetScalarMin(float theValue){
81   float aScalarRange[2] = {theValue, GetScalarRange()[1]};
82   SetScalarRange(aScalarRange);
83 }
84 void VISU_FieldTransform::SetScalarMax(float theValue){
85   float aScalarRange[2] = {GetScalarRange()[0], theValue};
86   SetScalarRange(aScalarRange);
87 }
88
89
90 template<typename TypeData> void
91 ExecVectors(VISU_FieldTransform::TTransformFun theFunction, 
92             SALOME_Transform* theTransform,
93             float theScalarRange[2], int theNbComponent, 
94             TypeData* theInputData, TypeData* theOutputData)
95 {
96   vtkDataArray *inVectors = theInputData->GetVectors();
97   if ( !inVectors || theNbComponent < 1 ) return; 
98   vtkFloatArray *newVectors = vtkFloatArray::New();
99   newVectors->SetNumberOfComponents(3);
100   newVectors->SetNumberOfTuples(theNbComponent);
101   float aScalarRange[2] = {(*theFunction)(theScalarRange[0]),(*theFunction)(theScalarRange[1])};
102   float *V, v[3], vMag, aDelta = aScalarRange[1] - aScalarRange[0];
103   float aScale[3] = {1.0, 1.0, 1.0};
104   if(theTransform){
105     aScale[0] = theTransform->GetScale()[0];
106     aScale[1] = theTransform->GetScale()[1];
107     aScale[2] = theTransform->GetScale()[2];
108   }
109   if(theFunction == &(VISU_FieldTransform::Ident)){
110     for (int ptId = 0; ptId < theNbComponent; ptId++) {
111       V = inVectors->GetTuple3(ptId);
112       v[0] = V[0]*aScale[0];
113       v[1] = V[1]*aScale[1];
114       v[2] = V[2]*aScale[2];
115       newVectors->SetTuple3(ptId, v[0], v[1], v[2]);
116     }
117   }else{
118     for (int ptId = 0; ptId < theNbComponent; ptId++) {
119       V = inVectors->GetTuple3(ptId);
120       vMag = vtkMath::Norm(V);
121       vMag = ((*theFunction)(vMag) - aScalarRange[0]) / aDelta * theScalarRange[1] / vMag;
122       if(vMag <= 0.0) vMag = 0.0;
123       v[0] = V[0]*vMag*aScale[0];
124       v[1] = V[1]*vMag*aScale[1];
125       v[2] = V[2]*vMag*aScale[2];
126       newVectors->SetTuple3(ptId, v[0], v[1], v[2]);
127     }
128   }
129   theOutputData->SetVectors(newVectors);
130   newVectors->Delete();
131 }
132
133 template<typename TypeData> void
134 ExecScalars(VISU_FieldTransform::TTransformFun theFunction, float theScalarRange[2],
135             int theNbComponent, TypeData* theInputData, TypeData* theOutputData)
136 {
137   vtkDataArray *inScalars = theInputData->GetScalars();
138   if ( !inScalars || theNbComponent < 1 ) 
139     return; 
140   vtkFloatArray *newScalars = vtkFloatArray::New();
141   newScalars->SetNumberOfComponents(1);
142   newScalars->SetNumberOfTuples(theNbComponent);
143   float aScalarRange[2] = {(*theFunction)(theScalarRange[0]),(*theFunction)(theScalarRange[1])};
144   for (int ptId = 0; ptId < theNbComponent; ptId++) {
145     float s = (*theFunction)(inScalars->GetTuple1(ptId ));
146     if(s < aScalarRange[0]) s = aScalarRange[0];
147     newScalars->SetTuple1(ptId, s);
148   }
149   theOutputData->SetScalars(newScalars);
150   newScalars->Delete();
151 }
152
153 void VISU_FieldTransform::Execute(){
154   vtkDataSet *input = this->GetInput(), *output = this->GetOutput();
155   output->CopyStructure(input);
156   if(myFunction != &Ident || (myTransform && !myTransform->IsIdentity())){
157     output->GetPointData()->CopyAllOff();
158     output->GetCellData()->CopyAllOff();
159
160     ExecScalars(myFunction,myScalarRange,input->GetNumberOfPoints(),input->GetPointData(),output->GetPointData());
161     ExecVectors(myFunction,myTransform,myScalarRange,input->GetNumberOfPoints(),input->GetPointData(),output->GetPointData());
162
163     ExecScalars(myFunction,myScalarRange,input->GetNumberOfCells(),input->GetCellData(),output->GetCellData());
164     ExecVectors(myFunction,myTransform,myScalarRange,input->GetNumberOfCells(),input->GetCellData(),output->GetCellData());
165   }else{
166     output->GetPointData()->CopyAllOn();
167     output->GetCellData()->CopyAllOn();
168
169     output->GetPointData()->PassData(input->GetPointData());
170     output->GetCellData()->PassData(input->GetCellData());
171   }
172 }