Issue Using StreamTracer with Calculator

Hello everyone
I’m trying to create streamline for both Scalar and Vector array.
I have no issue when my data array is scalar but I have issue when handling Vector.
My issue is that for Vector, after getting PolyData from StreamTracer output, the number of array from Point Data return 0.
Below is the code I’m using.
Could you please tell me what I’m doing wrong?

bool bArrayIsVector = TargetDataArray.GetNumberOfComponents() == 3;

//first run Calculator
string FeatureName = TargetDataArray.GetName();
string Function = "iHat*" + FeatureName + "+jHat*" + FeatureName + "+kHat*" + FeatureName;

vtkArrayCalculator Calculator = vtkArrayCalculator.New();
if(!bArrayIsVector)
{
    Calculator.SetInputData(DataSet);
    Calculator.AddScalarArrayName(FeatureName, 0);
    Calculator.SetFunction(Function);
    Calculator.SetResultArrayName("vector_attr");
    Calculator.Update();
}
else
{
    Calculator.SetInputData(DataSet);
    Calculator.AddVectorArrayName(FeatureName, 0, 1, 2);
    Calculator.SetFunction(Function);
    Calculator.SetResultArrayName("vector_attr");
    Calculator.Update();
}

//set plane source
vtkPlaneSource planeSource = vtkPlaneSource.New();
[...]

//set streamtracer
vtkStreamTracer StreamTracer = vtkStreamTracer.New();
StreamTracer.SetInputConnection(Calculator.GetOutputPort());
StreamTracer.SetSourceConnection(planeSource.GetOutputPort());
StreamTracer.SetIntegratorTypeToRungeKutta45();
StreamTracer.SetIntegrationDirectionToForward();
StreamTracer.SetComputeVorticity(true);
StreamTracer.SetMaximumPropagation(StreamlineLengthPropagation);
StreamTracer.SetInitialIntegrationStep(0.3);
vtkInformationVector inArrayVec = StreamTracer.GetInformation().Get(vtkAlgorithm.INPUT_ARRAYS_TO_PROCESS());
vtkInformation inArrayInfo = inArrayVec.GetInformationObject(0);
inArrayInfo.Set(vtkDataObject.FIELD_NAME(), "vector_attr");
StreamTracer.Update();

//get polydata
vtkPolyData MyData = StreamTracer.GetOutput();
StreamTracer.Update();
MyData.BuildCells();
MyData.BuildLinks(0);
 
vtkPointData PointDatas = MyData.GetPointData();
int NbArray = PointDatas.GetNumberOfArrays(); // ->NbArray is 0 if array is vector

below is the error from the OutputWindow

ERROR: In C:\Users\Lucas\Projects\Unity\CI\VTK-9.0.1\Common\Misc\vtkFunctionParser.cxx, line 238
vtkFunctionParser (00000248BDC2C920): multiply expecting either 2 scalars or a scalar and a vector

ERROR: In C:\Users\Lucas\Projects\Unity\CI\VTK-9.0.1\Common\Misc\vtkFunctionParser.cxx, line 133
vtkFunctionParser (00000248BDC2C920): Parse: Error deciding between ambiguous operators

ERROR: In C:\Users\Lucas\Projects\Unity\CI\VTK-9.0.1\Common\Misc\vtkFunctionParser.cxx, line 238
vtkFunctionParser (00000248BDC2C920): multiply expecting either 2 scalars or a scalar and a vector

ERROR: In C:\Users\Lucas\Projects\Unity\CI\VTK-9.0.1\Common\Misc\vtkFunctionParser.cxx, line 133
vtkFunctionParser (00000248BDC2C920): Parse: Error deciding between ambiguous operators

Warning: In C:\Users\Lucas\Projects\Unity\CI\VTK-9.0.1\Filters\Core\vtkArrayCalculator.cxx, line 348
vtkArrayCalculator (0000024952EBFBE0): An error occurred when parsing the calculator’s function. See previous errors.

I really thank you in advance for your help

For 2 Vectors, correct operator isn’t ‘*’ but ‘.’ so my function will be
Function = “iHat.” + FeatureName + “+jHat.” + FeatureName + “+kHat.” + FeatureName;

however when running the application I’ve got the following error lot of time before getting the result

ERROR: In c:\users\lucas\projects\unity\ci\vtk-9.0.1\common\core\vtkGenericDataArray.txx, line 700
vtkDoubleArray (0000024950D55A70): Number of components for input and output do not match.
Source: 1
Destination: 3

Any idea why this happen?

Hello,

Can you, please, enclose the code between a ```cpp and a ```? This will make the code much more readable.

best,

PC

Hello
Thank you for telling me about ` ``cpp and a ```, I didn’t know this I could use this one.
I have edited my original post

Best regards

Try to reduce the function to a trivial case:

string Function = "0.0";

See whether this works.

Thank you for your help.
I’m still getting the following error in the output windows

ERROR: In c:\users\lucas\projects\unity\ci\vtk-9.0.1\common\core\vtkGenericDataArray.txx, line 700
vtkDoubleArray (0000021810CD5DA0): Number of components for input and output do not match.
Source: 1
Destination: 3

Which line of code triggers the error?

Hello
The error was triggered on the following line

StreamTracer.Update();

I was able to fix the error by addind the following code before calling StreamTracer.Update()

if (bArrayIsVector)
{
    inArrayInfo.Set(vtkDataObject.FIELD_NAME(), FeatureName);
}

Below is the working solution

bool bArrayIsVector = TargetDataArray.GetNumberOfComponents() == 3;

vtkDataSet DataSet = MyReader.GetOutput();

string FeatureName = TargetDataArray.GetName();
string ResultDataArrayName = "vector_attr";
vtkArrayCalculator Calculator = vtkArrayCalculator.New();
if (bArrayIsVector)
{
    string Function = "iHat." + FeatureName + "+jHat." + FeatureName + "+kHat." + FeatureName;
    Calculator.SetInputData(DataSet);
    Calculator.AddVectorArrayName(FeatureName, 0, 1, 2);
    Calculator.SetFunction(Function);
    Calculator.SetResultArrayName(ResultDataArrayName);
    Calculator.Update();
}
else
{
    string Function = "iHat*" + FeatureName + "+jHat*" + FeatureName + "+kHat*" + FeatureName;
    Calculator.SetInputData(DataSet);
    Calculator.AddScalarArrayName(FeatureName, 0);
    Calculator.SetFunction(Function);
    Calculator.SetResultArrayName(ResultDataArrayName);
    Calculator.Update();
}

vtkPlaneSource planeSource = vtkPlaneSource.New();
[...]
planeSource.Update();

vtkStreamTracer StreamTracer = vtkStreamTracer.New();
StreamTracer.SetInputConnection(Calculator.GetOutputPort());
StreamTracer.SetSourceConnection(planeSource.GetOutputPort());
StreamTracer.SetIntegratorTypeToRungeKutta45();

StreamTracer.SetIntegrationDirectionToForward();
StreamTracer.SetComputeVorticity(true);
StreamTracer.SetMaximumPropagation(StreamlineLengthPropagation);
StreamTracer.SetInitialIntegrationStep(0.3);
//WARNING: Set FIELD_NAME() so it can be processed by vtkAlgorithm
vtkInformationVector inArrayVec = StreamTracer.GetInformation().Get(vtkAlgorithm.INPUT_ARRAYS_TO_PROCESS());

vtkInformation inArrayInfo = inArrayVec.GetInformationObject(0);
inArrayInfo.Set(vtkDataObject.FIELD_NAME(), ResultDataArrayName);

if (bArrayIsVector)
{
    inArrayInfo.Set(vtkDataObject.FIELD_NAME(), FeatureName);
}

StreamTracer.Update();

vtkPolyData MyData = StreamTracer.GetOutput();
StreamTracer.Update();
MyData.BuildCells();
MyData.BuildLinks(0);

vtkPointData PointDatas = MyData.GetPointData();

1 Like