-// VISU OBJECT : interactive object for VISU entities implementation
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// 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
// 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_Extractor.hxx"
#include "VISU_PipeLineUtils.hxx"
+#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 <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vector>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
-using namespace std;
-
+#define USE_SPRINTF 1
+//----------------------------------------------------------------------------
vtkStandardNewMacro(VISU_Extractor);
-VISU_Extractor::VISU_Extractor()
+//----------------------------------------------------------------------------
+VISU_Extractor
+::VISU_Extractor():
+ myScalarMode(1),
+ myGaussMetric(VISU::AVERAGE_METRIC)
{
- myScalarMode = 1;
}
-VISU_Extractor::~VISU_Extractor()
+
+//----------------------------------------------------------------------------
+VISU_Extractor
+::~VISU_Extractor()
{}
-void VISU_Extractor::SetScalarMode(int theScalarMode)
+
+//----------------------------------------------------------------------------
+void
+VISU_Extractor
+::SetScalarMode(int theScalarMode)
{
if(myScalarMode != theScalarMode){
myScalarMode = theScalarMode;
}
}
-template<typename TypeData> void
-execute(int theNbElems,
- int theScalarMode,
- TypeData* theInputData,
- TypeData* theOutputData)
+//----------------------------------------------------------------------------
+int
+VISU_Extractor
+::GetScalarMode()
+{
+ return myScalarMode;
+}
+
+
+//----------------------------------------------------------------------------
+void
+VISU_Extractor
+::SetGaussMetric(VISU::TGaussMetric theGaussMetric)
+{
+ if(myGaussMetric != theGaussMetric){
+ myGaussMetric = theGaussMetric;
+ Modified();
+ }
+}
+
+//----------------------------------------------------------------------------
+VISU::TGaussMetric
+VISU_Extractor
+::GetGaussMetric()
{
- if(theNbElems < 1 )
+ return myGaussMetric;
+}
+
+//----------------------------------------------------------------------------
+vtkFloatingPointType CutValue (vtkFloatingPointType theValue, int theDecimals)
+{
+ vtkFloatingPointType v = theValue;
+
+#ifdef USE_SPRINTF
+ char aFormat[16];
+ sprintf(aFormat, "%%.%dg", theDecimals);
+ char aStr [256];
+ sprintf(aStr, aFormat, theValue);
+ v = atof(aStr);
+#else
+
+#ifndef USE_OLD_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
+
+#endif
+
+ return v;
+}
+
+//----------------------------------------------------------------------------
+template<typename TValueType>
+void
+Module2Scalars(vtkDataArray *theInputDataArray,
+ 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]);
+ *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;
- vtkDataArray* aFieldArray = theInputData->GetArray("VISU_FIELD");
- if(vtkFloatArray *aFloatArray = dynamic_cast<vtkFloatArray*>(aFieldArray)){
- int aNbComp = aFloatArray->GetNumberOfComponents();
- std::vector<vtkFloatingPointType> anArray(aNbComp < 3? 3: aNbComp);
- //
- vtkFloatArray *aScalars = vtkFloatArray::New();
- aScalars->SetNumberOfTuples(theNbElems);
- aScalars->SetNumberOfComponents(1);
- //
- if(!theScalarMode){
- for(int anId = 0; anId < theNbElems; anId++){
- aFloatArray->GetTuple(anId,&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]);
- aScalars->SetTuple1(anId,aScalar);
+ 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>
+void
+Component2Scalars(vtkDataArray *theInputDataArray,
+ TValueType* theInputPtr,
+ TValueType* theOutputPtr,
+ vtkIdType theNbOfTuples,
+ vtkIdType theComponentId)
+{
+ vtkIdType aNbComp = theInputDataArray->GetNumberOfComponents();
+ 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)
+{
+ if (theNbOfTuples < 1)
+ return;
+
+ vtkDataArray* aFieldArray = NULL;
+ 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;
+ }
+ if( !aFieldArray )
+ return;
+
+ vtkIdType anInputDataType = aFieldArray->GetDataType();
+ vtkDataArray *anOutputScalars = vtkDataArray::CreateDataArray(anInputDataType);
+ anOutputScalars->SetNumberOfComponents(1);
+ anOutputScalars->SetNumberOfTuples(theNbOfTuples);
+
+ void *anInputPtr = aFieldArray->GetVoidPointer(0);
+ void *anOutputPtr = anOutputScalars->GetVoidPointer(0);
+
+ 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{
- for(int anId = 0; anId < theNbElems; anId++){
- aFloatArray->GetTuple(anId,&anArray[0]);
- aScalars->SetTuple1(anId,anArray[theScalarMode - 1]);
+ }
+ else {
+ switch (anInputDataType) {
+ vtkTemplateMacro3(Module2Scalars,
+ aFieldArray,
+ (VTK_TT *)(anOutputPtr),
+ theNbOfTuples);
+ default:
+ break;
}
}
- theOutputData->SetScalars(aScalars);
- aScalars->Delete();
+ } else {
+ switch (anInputDataType) {
+ vtkTemplateMacro5(Component2Scalars,
+ 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;
}
}
-void VISU_Extractor::Execute(){
- vtkDataSet *input = this->GetInput(), *output = this->GetOutput();
- output->CopyStructure(input);
- output->GetPointData()->CopyAllOff();
- output->GetCellData()->CopyAllOff();
- if(input->GetPointData()->GetNumberOfArrays()){
- output->GetPointData()->CopyVectorsOn();
- int aNbElems = input->GetNumberOfPoints();
- vtkPointData *inData = input->GetPointData(), *outData = output->GetPointData();
- if(inData->GetAttribute(vtkDataSetAttributes::VECTORS))
- execute(aNbElems,myScalarMode,inData,outData);
- else
- output->GetPointData()->CopyScalarsOn();
- outData->PassData(inData);
- outData->AddArray(inData->GetArray("VISU_FIELD"));
- }else{
- output->GetCellData()->CopyVectorsOn();
- int aNbElems = input->GetNumberOfCells();
- vtkCellData *inData = input->GetCellData(), *outData = output->GetCellData();
- if(inData->GetAttribute(vtkDataSetAttributes::VECTORS))
- execute(aNbElems,myScalarMode,inData,outData);
- else
- output->GetCellData()->CopyScalarsOn();
- outData->PassData(inData);
- outData->AddArray(inData->GetArray("VISU_FIELD"));
+//---------------------------------------------------------------
+int
+VISU_Extractor
+::RequestData(vtkInformation *theRequest,
+ vtkInformationVector **theInputVector,
+ vtkInformationVector *theOutputVector)
+{
+ vtkDataSet *anInput = VISU::GetInput( theInputVector, 0 );
+ vtkDataSet *anOutput = VISU::GetOutput( theOutputVector );
+
+ anOutput->CopyStructure( anInput );
+
+ vtkPointData *anInputPointData = anInput->GetPointData();
+ vtkPointData *anOutputPointData = anOutput->GetPointData();
+ 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 );
+ if ( VISU::IsDataOnCells( anInput ) ) {
+ int aNbElems = anInput->GetNumberOfCells();
+ if ( anInputCellData->GetAttribute( vtkDataSetAttributes::VECTORS ) )
+ ExecuteScalars( aNbElems, myScalarMode, myGaussMetric, anInputCellData, anOutputCellData );
+ CutScalars( aNbElems, anOutputCellData );
}
+
+ return 1;
}