1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File : VISU_Extractor.cxx
27 #include "VISU_Extractor.hxx"
28 #include "VISU_PipeLineUtils.hxx"
29 #include "VISU_ConvertorUtils.hxx"
30 #include "VISU_MeshValue.hxx"
32 #include <SUIT_Session.h>
33 #include <SUIT_ResourceMgr.h>
36 #include <cmath> // to use std::abs( int )
38 #include <vtkObjectFactory.h>
39 #include <vtkUnstructuredGrid.h>
40 #include <vtkPointData.h>
41 #include <vtkCellData.h>
43 #include <vtkInformation.h>
44 #include <vtkInformationVector.h>
46 // Algorithm to cut values (see CutValue())
47 // Use sprintf function
49 // Use new algorithm (works only when USE_SPRINTF is disabled)
50 #define USE_NEW_ALGORITHM
52 //----------------------------------------------------------------------------
53 vtkStandardNewMacro(VISU_Extractor);
55 //----------------------------------------------------------------------------
59 myGaussMetric(VISU::AVERAGE_METRIC)
64 //----------------------------------------------------------------------------
70 //----------------------------------------------------------------------------
73 ::SetScalarMode(int theScalarMode)
75 if(myScalarMode != theScalarMode){
76 myScalarMode = theScalarMode;
81 //----------------------------------------------------------------------------
90 //----------------------------------------------------------------------------
93 ::SetGaussMetric(VISU::TGaussMetric theGaussMetric)
95 if(myGaussMetric != theGaussMetric){
96 myGaussMetric = theGaussMetric;
101 //----------------------------------------------------------------------------
106 return myGaussMetric;
109 //----------------------------------------------------------------------------
110 vtkFloatingPointType CutValue (vtkFloatingPointType theValue, int theDecimals)
112 vtkFloatingPointType v = theValue;
114 #if defined(USE_SPRINTF)
116 sprintf(aFormat, "%%.%dg", theDecimals);
118 sprintf(aStr, aFormat, theValue);
120 #elif defined(USE_NEW_ALGORITHM)
122 // VSR 19/10/2009: new algorithm does not use long long type
125 // calculate order of the integral part
130 // calculate length of the fractional part
131 long n2 = theDecimals - n1;
134 while ( n2-- > 0 ) v = v * 10.;
136 while ( n2++ < 0 ) v = v / 10.;
137 v = floor( (double) v );
138 n2 = theDecimals - n1;
140 while ( n2-- > 0 ) v = v / 10.;
142 while ( n2++ < 0 ) v = v * 10.;
145 // VSR 19/10/2009: old algorithm uses long long type -
146 // causes incompatibility with some platforms (Windows?)
148 vtkFloatingPointType aDegree = 0.0;
149 if (abs((long long)v) > 1)
150 aDegree = (long long)log10((double)abs((long long)v)) + 1;
151 aDegree = theDecimals - aDegree;
152 //printf("$$$ 1 v = %.20g , aDegree = %lld \n", v, (long long)aDegree);
154 aDegree = pow(10, aDegree);
155 v = ((vtkFloatingPointType)((long long)(v * aDegree))) / aDegree;
156 //printf("$$$ 2 v = %.20g , aDegree = %lld \n", v, (long long)aDegree);
162 //----------------------------------------------------------------------------
163 template<typename TValueType>
165 Module2Scalars(vtkDataArray *theInputDataArray,
166 TValueType* theOutputPtr,
167 vtkIdType theNbOfTuples)
169 vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
170 std::vector<vtkFloatingPointType> anArray(aNbComp < 3? 3: aNbComp);
171 for(vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++){
172 theInputDataArray->GetTuple(aTupleId, &anArray[0]);
173 vtkFloatingPointType aVector[3] = {anArray[0], anArray[1], anArray[2]};
174 vtkFloatingPointType aScalar = sqrt(aVector[0]*aVector[0] +
175 aVector[1]*aVector[1] +
176 aVector[2]*aVector[2]);
177 *theOutputPtr = TValueType(aScalar);
182 template<typename TValueType>
184 Module2ScalarsMOD(vtkDataArray *theInputDataArray,
185 TValueType* theOutputPtr,
186 vtkIdType theNbOfTuples,
187 VISU::TGaussMetric theGaussMetric)
189 vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
190 if (aNbComp != 3) // Min, Max, Avg
192 std::vector<vtkFloatingPointType> anArray (3);
193 for (vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
194 theInputDataArray->GetTuple(aTupleId, &anArray[0]);
195 switch (theGaussMetric) {
196 case VISU::MINIMUM_METRIC: *theOutputPtr = TValueType(anArray[0]); break;
197 case VISU::MAXIMUM_METRIC: *theOutputPtr = TValueType(anArray[1]); break;
198 case VISU::AVERAGE_METRIC: *theOutputPtr = TValueType(anArray[2]); break;
205 //----------------------------------------------------------------------------
206 template<typename TValueType>
208 Component2Scalars(vtkDataArray *theInputDataArray,
209 TValueType* theInputPtr,
210 TValueType* theOutputPtr,
211 vtkIdType theNbOfTuples,
212 vtkIdType theComponentId)
214 vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
215 for (vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
216 *theOutputPtr = *(theInputPtr + theComponentId);
217 theInputPtr += aNbComp;
222 //----------------------------------------------------------------------------
223 template<typename TValueType>
225 CutScalarsTempl(TValueType* theDataPtr,
226 vtkIdType theNbOfTuples,
229 for (vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
230 *theDataPtr = TValueType(CutValue(*theDataPtr, theDecimals));
235 //----------------------------------------------------------------------------
236 template<typename TDataSetAttributesType> void
237 ExecuteScalars(vtkIdType theNbOfTuples,
238 vtkIdType theScalarMode,
239 VISU::TGaussMetric theGaussMetric,
240 TDataSetAttributesType* theInputData,
241 TDataSetAttributesType* theOutputData)
243 if (theNbOfTuples < 1)
246 vtkDataArray* aFieldArray = NULL;
247 switch (theGaussMetric) {
248 case VISU::AVERAGE_METRIC: aFieldArray = theInputData->GetArray("VISU_FIELD"); break;
249 case VISU::MINIMUM_METRIC: aFieldArray = theInputData->GetArray("VISU_FIELD_GAUSS_MIN"); break;
250 case VISU::MAXIMUM_METRIC: aFieldArray = theInputData->GetArray("VISU_FIELD_GAUSS_MAX"); break;
255 vtkIdType anInputDataType = aFieldArray->GetDataType();
256 vtkDataArray *anOutputScalars = vtkDataArray::CreateDataArray(anInputDataType);
257 anOutputScalars->SetNumberOfComponents(1);
258 anOutputScalars->SetNumberOfTuples(theNbOfTuples);
260 void *anInputPtr = aFieldArray->GetVoidPointer(0);
261 void *anOutputPtr = anOutputScalars->GetVoidPointer(0);
263 if (theScalarMode == 0) {
264 vtkDataArray* aFieldArrayMOD = theInputData->GetArray("VISU_FIELD_GAUSS_MOD");
265 if (aFieldArrayMOD) {
266 switch (anInputDataType) {
267 vtkTemplateMacro4(Module2ScalarsMOD,
269 (VTK_TT *)(anOutputPtr),
277 switch (anInputDataType) {
278 vtkTemplateMacro3(Module2Scalars,
280 (VTK_TT *)(anOutputPtr),
287 switch (anInputDataType) {
288 vtkTemplateMacro5(Component2Scalars,
290 (VTK_TT *)(anInputPtr),
291 (VTK_TT *)(anOutputPtr),
299 theOutputData->SetScalars(anOutputScalars);
300 anOutputScalars->Delete();
303 //---------------------------------------------------------------
304 template<typename TDataSetAttributesType> void
305 CutScalars(vtkIdType theNbOfTuples,
306 TDataSetAttributesType* theData)
308 if (theNbOfTuples < 1)
311 vtkDataArray *aScalars = theData->GetScalars();
315 vtkIdType aDataType = aScalars->GetDataType();
316 void *aPtr = aScalars->GetVoidPointer(0);
318 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
319 // san: precision can be negative - this is used by double spin boxes
320 int aDecimals = std::abs( aResourceMgr->integerValue("VISU", "visual_data_precision", 6) );
323 vtkTemplateMacro3(CutScalarsTempl,
332 //---------------------------------------------------------------
335 ::RequestData(vtkInformation *theRequest,
336 vtkInformationVector **theInputVector,
337 vtkInformationVector *theOutputVector)
339 vtkDataSet *anInput = VISU::GetInput( theInputVector, 0 );
340 vtkDataSet *anOutput = VISU::GetOutput( theOutputVector );
342 anOutput->CopyStructure( anInput );
344 vtkPointData *anInputPointData = anInput->GetPointData();
345 vtkPointData *anOutputPointData = anOutput->GetPointData();
346 anOutputPointData->PassData( anInputPointData );
347 if ( VISU::IsDataOnPoints( anInput ) ) {
348 int aNbElems = anInput->GetNumberOfPoints();
349 if ( anInputPointData->GetAttribute( vtkDataSetAttributes::VECTORS ) )
350 ExecuteScalars( aNbElems, myScalarMode, myGaussMetric, anInputPointData, anOutputPointData );
351 CutScalars( aNbElems, anOutputPointData );
354 vtkCellData *anInputCellData = anInput->GetCellData();
355 vtkCellData *anOutputCellData = anOutput->GetCellData();
356 anOutputCellData->PassData( anInputCellData );
357 if ( VISU::IsDataOnCells( anInput ) ) {
358 int aNbElems = anInput->GetNumberOfCells();
359 if ( anInputCellData->GetAttribute( vtkDataSetAttributes::VECTORS ) )
360 ExecuteScalars( aNbElems, myScalarMode, myGaussMetric, anInputCellData, anOutputCellData );
361 CutScalars( aNbElems, anOutputCellData );