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