-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
//
-// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// VISU OBJECT : interactive object for VISU entities implementation
// File : VISU_Extractor.cxx
// Module : VISU
#include "VISU_ConvertorUtils.hxx"
#include "VISU_MeshValue.hxx"
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+
#include <sstream>
+#include <cmath> // to use std::abs( int )
#include <vtkObjectFactory.h>
#include <vtkUnstructuredGrid.h>
#include <vtkInformation.h>
#include <vtkInformationVector.h>
-
+// Algorithm to cut values (see CutValue())
+// Use sprintf function
+#define USE_SPRINTF
+// Use new algorithm (works only when USE_SPRINTF is disabled)
+#define USE_NEW_ALGORITHM
//----------------------------------------------------------------------------
vtkStandardNewMacro(VISU_Extractor);
return myGaussMetric;
}
+//----------------------------------------------------------------------------
+vtkFloatingPointType CutValue (vtkFloatingPointType theValue, int theDecimals)
+{
+ vtkFloatingPointType v = theValue;
+
+#if defined(USE_SPRINTF)
+ char aFormat[16];
+ sprintf(aFormat, "%%.%dg", theDecimals);
+ char aStr [256];
+ sprintf(aStr, aFormat, theValue);
+ v = atof(aStr);
+#elif defined(USE_NEW_ALGORITHM)
+ //
+ // VSR 19/10/2009: new algorithm does not use long long type
+ //
+ long n1 = 0;
+ // calculate order of the integral part
+ while ( v > 1. ) {
+ v = v / 10.;
+ n1++;
+ }
+ // calculate length of the fractional part
+ long n2 = theDecimals - n1;
+ v = theValue;
+ if ( n2 > 0 )
+ while ( n2-- > 0 ) v = v * 10.;
+ else
+ while ( n2++ < 0 ) v = v / 10.;
+ v = floor( (double) v );
+ n2 = theDecimals - n1;
+ if ( n2 > 0 )
+ while ( n2-- > 0 ) v = v / 10.;
+ else
+ while ( n2++ < 0 ) v = v * 10.;
+#else
+ //
+ // VSR 19/10/2009: old algorithm uses long long type -
+ // causes incompatibility with some platforms (Windows?)
+ //
+ vtkFloatingPointType aDegree = 0.0;
+ if (abs((long long)v) > 1)
+ aDegree = (long long)log10((double)abs((long long)v)) + 1;
+ aDegree = theDecimals - aDegree;
+ //printf("$$$ 1 v = %.20g , aDegree = %lld \n", v, (long long)aDegree);
+
+ aDegree = pow(10, aDegree);
+ v = ((vtkFloatingPointType)((long long)(v * aDegree))) / aDegree;
+ //printf("$$$ 2 v = %.20g , aDegree = %lld \n", v, (long long)aDegree);
+#endif
+
+ return v;
+}
//----------------------------------------------------------------------------
-template<typename TValueType>
+template<typename TValueType>
void
Module2Scalars(vtkDataArray *theInputDataArray,
- TValueType* theOutputPtr,
- vtkIdType theNbOfTuples)
+ TValueType* theOutputPtr,
+ vtkIdType theNbOfTuples)
{
vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
std::vector<vtkFloatingPointType> anArray(aNbComp < 3? 3: aNbComp);
for(vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++){
theInputDataArray->GetTuple(aTupleId, &anArray[0]);
vtkFloatingPointType aVector[3] = {anArray[0], anArray[1], anArray[2]};
- vtkFloatingPointType aScalar = sqrt(aVector[0]*aVector[0] +
- aVector[1]*aVector[1] +
- aVector[2]*aVector[2]);
+ vtkFloatingPointType aScalar = sqrt(aVector[0]*aVector[0] +
+ aVector[1]*aVector[1] +
+ aVector[2]*aVector[2]);
*theOutputPtr = TValueType(aScalar);
theOutputPtr++;
}
}
+template<typename TValueType>
+void
+Module2ScalarsMOD(vtkDataArray *theInputDataArray,
+ TValueType* theOutputPtr,
+ vtkIdType theNbOfTuples,
+ VISU::TGaussMetric theGaussMetric)
+{
+ vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
+ if (aNbComp != 3) // Min, Max, Avg
+ return;
+ std::vector<vtkFloatingPointType> anArray (3);
+ for (vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
+ theInputDataArray->GetTuple(aTupleId, &anArray[0]);
+ switch (theGaussMetric) {
+ case VISU::MINIMUM_METRIC: *theOutputPtr = TValueType(anArray[0]); break;
+ case VISU::MAXIMUM_METRIC: *theOutputPtr = TValueType(anArray[1]); break;
+ case VISU::AVERAGE_METRIC: *theOutputPtr = TValueType(anArray[2]); break;
+ }
+ theOutputPtr++;
+ }
+}
+
//----------------------------------------------------------------------------
-template<typename TValueType>
+template<typename TValueType>
void
Component2Scalars(vtkDataArray *theInputDataArray,
- TValueType* theInputPtr,
- TValueType* theOutputPtr,
- vtkIdType theNbOfTuples,
- vtkIdType theComponentId)
+ TValueType* theInputPtr,
+ TValueType* theOutputPtr,
+ vtkIdType theNbOfTuples,
+ vtkIdType theComponentId)
{
vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
- for(vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++){
+ for (vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
*theOutputPtr = *(theInputPtr + theComponentId);
theInputPtr += aNbComp;
theOutputPtr++;
}
}
+//----------------------------------------------------------------------------
+template<typename TValueType>
+void
+CutScalarsTempl(TValueType* theDataPtr,
+ vtkIdType theNbOfTuples,
+ int theDecimals)
+{
+ for (vtkIdType aTupleId = 0; aTupleId < theNbOfTuples; aTupleId++) {
+ *theDataPtr = TValueType(CutValue(*theDataPtr, theDecimals));
+ theDataPtr++;
+ }
+}
//----------------------------------------------------------------------------
template<typename TDataSetAttributesType> void
-ExecuteScalars(vtkIdType theNbOfTuples,
- vtkIdType theScalarMode,
- VISU::TGaussMetric theGaussMetric,
- TDataSetAttributesType* theInputData,
- TDataSetAttributesType* theOutputData)
+ExecuteScalars(vtkIdType theNbOfTuples,
+ vtkIdType theScalarMode,
+ VISU::TGaussMetric theGaussMetric,
+ TDataSetAttributesType* theInputData,
+ TDataSetAttributesType* theOutputData)
{
- if(theNbOfTuples < 1)
+ if (theNbOfTuples < 1)
return;
vtkDataArray* aFieldArray = NULL;
- switch( theGaussMetric ) {
+ switch (theGaussMetric) {
case VISU::AVERAGE_METRIC: aFieldArray = theInputData->GetArray("VISU_FIELD"); break;
case VISU::MINIMUM_METRIC: aFieldArray = theInputData->GetArray("VISU_FIELD_GAUSS_MIN"); break;
case VISU::MAXIMUM_METRIC: aFieldArray = theInputData->GetArray("VISU_FIELD_GAUSS_MAX"); break;
void *anInputPtr = aFieldArray->GetVoidPointer(0);
void *anOutputPtr = anOutputScalars->GetVoidPointer(0);
- if(theScalarMode == 0){
- switch(anInputDataType){
- vtkTemplateMacro3(Module2Scalars,
- aFieldArray,
- (VTK_TT *)(anOutputPtr),
- theNbOfTuples);
- default:
- break;
+ if (theScalarMode == 0) {
+ vtkDataArray* aFieldArrayMOD = theInputData->GetArray("VISU_FIELD_GAUSS_MOD");
+ if (aFieldArrayMOD) {
+ switch (anInputDataType) {
+ vtkTemplateMacro4(Module2ScalarsMOD,
+ aFieldArrayMOD,
+ (VTK_TT *)(anOutputPtr),
+ theNbOfTuples,
+ theGaussMetric);
+ default:
+ break;
+ }
+ }
+ else {
+ switch (anInputDataType) {
+ vtkTemplateMacro3(Module2Scalars,
+ aFieldArray,
+ (VTK_TT *)(anOutputPtr),
+ theNbOfTuples);
+ default:
+ break;
+ }
}
- }else{
- switch(anInputDataType){
+ } else {
+ switch (anInputDataType) {
vtkTemplateMacro5(Component2Scalars,
- aFieldArray,
- (VTK_TT *)(anInputPtr),
- (VTK_TT *)(anOutputPtr),
- theNbOfTuples,
- theScalarMode - 1);
+ aFieldArray,
+ (VTK_TT *)(anInputPtr),
+ (VTK_TT *)(anOutputPtr),
+ theNbOfTuples,
+ theScalarMode - 1);
default:
break;
}
}
-
+
theOutputData->SetScalars(anOutputScalars);
anOutputScalars->Delete();
}
+//---------------------------------------------------------------
+template<typename TDataSetAttributesType> void
+CutScalars(vtkIdType theNbOfTuples,
+ TDataSetAttributesType* theData)
+{
+ if (theNbOfTuples < 1)
+ return;
+
+ vtkDataArray *aScalars = theData->GetScalars();
+ if (!aScalars)
+ return;
+
+ vtkIdType aDataType = aScalars->GetDataType();
+ void *aPtr = aScalars->GetVoidPointer(0);
+
+ SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
+ // san: precision can be negative - this is used by double spin boxes
+ int aDecimals = std::abs( aResourceMgr->integerValue("VISU", "visual_data_precision", 6) );
+
+ switch(aDataType) {
+ vtkTemplateMacro3(CutScalarsTempl,
+ (VTK_TT *)(aPtr),
+ theNbOfTuples,
+ aDecimals);
+ default:
+ break;
+ }
+}
//---------------------------------------------------------------
int
VISU_Extractor
::RequestData(vtkInformation *theRequest,
- vtkInformationVector **theInputVector,
- vtkInformationVector *theOutputVector)
+ vtkInformationVector **theInputVector,
+ vtkInformationVector *theOutputVector)
{
vtkDataSet *anInput = VISU::GetInput( theInputVector, 0 );
vtkDataSet *anOutput = VISU::GetOutput( theOutputVector );
vtkPointData *anInputPointData = anInput->GetPointData();
vtkPointData *anOutputPointData = anOutput->GetPointData();
- anOutputPointData->PassData( anInputPointData );
+ anOutputPointData->PassData( anInputPointData );
if ( VISU::IsDataOnPoints( anInput ) ) {
int aNbElems = anInput->GetNumberOfPoints();
if ( anInputPointData->GetAttribute( vtkDataSetAttributes::VECTORS ) )
ExecuteScalars( aNbElems, myScalarMode, myGaussMetric, anInputPointData, anOutputPointData );
+ CutScalars( aNbElems, anOutputPointData );
}
-
+
vtkCellData *anInputCellData = anInput->GetCellData();
vtkCellData *anOutputCellData = anOutput->GetCellData();
- anOutputCellData->PassData( anInputCellData );
+ anOutputCellData->PassData( anInputCellData );
if ( VISU::IsDataOnCells( anInput ) ) {
int aNbElems = anInput->GetNumberOfCells();
if ( anInputCellData->GetAttribute( vtkDataSetAttributes::VECTORS ) )
ExecuteScalars( aNbElems, myScalarMode, myGaussMetric, anInputCellData, anOutputCellData );
+ CutScalars( aNbElems, anOutputCellData );
}
return 1;