ERROR: Glyph filter input array index not specified

I am trying to combine Calculator Filter with Glyph Filter but I think there is an issue with how both filters are linking. I can’t find the “Result” array of calculator in Orientation or Scale array of Glyph and I get this error:

ERROR: In vtkAlgorithm.cxx, line 570
myPVGlyphFilter (000001F9644D4950): Attempt to get an input array for an index that has not been specified

This is the RequestData function of my new filter:

int vtkMyForceFilter::RequestData(
    vtkInformation *request,
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector)
{

  int arrayCalcResult = this->ArrayCalculator->RequestData(request, inputVector, outputVector);

   // Get the output of ArrayCalculator
  vtkDataSet *arrayCalcOutput = vtkDataSet::SafeDownCast(outputVector->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
  vtkPointData* pointData = arrayCalcOutput->GetPointData();


  // Create a new input vector for GlyphFilter
  vtkInformationVector* glyphInputVector = vtkInformationVector::New();
  vtkInformation* glyphInputInfo = vtkInformation::New();
  glyphInputInfo->Set(vtkDataObject::DATA_OBJECT(), arrayCalcOutput);
  glyphInputVector->SetInformationObject(0, glyphInputInfo);


  int glyphFilterResult = this->GlyphFilter->RequestData(request, &glyphInputVector, outputVector);

  // Clean up
  glyphInputInfo->Delete();
  glyphInputVector->Delete();

  return glyphFilterResult;
}

Firstly, calling RequestData on internal filters directly is not recommend. Instead follow the the following pattern:


auto* input0 = vtkDataObject::GetData(inputVector[0], 0);
this->ArrayCalculator->SetInputDataObject(input0);

this->GlyphFilter->SetInputConnection(this->ArrayCalculator->GetOutputPort());
this->GlyphFilter->Update();

Secondly, Glyph filter needs multiple inputs. Have you specified the “Source” input somewhere?

Thanks for the response, I am new to creating filters so I wasn’t sure what’s the right way. So I will tell you how I am doing this.

  • Because I am combining two filters (Calculator and Glyph) I am using composition instead of inheritance (becuase vtk does not allow inheriting from two classes)
vtkTypeMacro(vtkMyForceFilter, vtkPassInputTypeAlgorithm);
  • I create two objects of my filters in private of my new filter class
  vtkSmartPointer<myPVArrayCalculator> ArrayCalculator;
  vtkSmartPointer<myPVGlyphFilter> GlyphFilter;

And then initialize them in my constructor.

  • In my .cxx file of my filter I have the RequestData Function which I shared above.

    • As for your suggestion I have a few questions (again because I am just starting writing these filters and I appreciate your help):

    • If at the start of my RequestData I am running this:

      auto* input0 = vtkDataObject::GetData(inputVector[0], 0);
      this->ArrayCalculator->SetInputDataObject(input0);
      

But how would all other functions which are actually called from ArrayCalculator’s RequestData would be called (I mean all the code in ArrayCalculator’s RequestData)?

  • Do I also need to call this->ArrayCalculator->Update() as you are calling for GlyphFilter?

  • As for the GlyphFilter I was just calling the RequestData with input as the output of ArrayCalculator’s output (as I shared above) so I did not specify Source input because I thought if I am calling GlyphFilter->RequestData it would be taken care of there.

I have actually not specified the source input. Where and how should I do that?

I believe this is the issue. So I tried debugging, in the RequestData function I found out that number of source inputs are 0

    vtkInformationVector* sourceVector = inputVector[1];
    int numSourceInputs = this->GetNumberOfInputConnections(1); // 1 for the source port
    logFile << "Number of source inputs: " << numSourceInputs << std::endl;

I get Number of source inputs: 0
Moreover, in the Execute function OrientArray and ScaleArrays are not there:

vtkDataArray* scaleArray = this->GetInputArrayToProcess(0, input);
    vtkDataArray* orientArray = this->GetInputArrayToProcess(1, input);

I believe this is the issue. I added some debugging statements and found out that Number of Source Inputs are 0

    vtkInformationVector* sourceVector = inputVector[1];
    int numSourceInputs = this->GetNumberOfInputConnections(1); // 1 for the source port
    logFile << "Number of source inputs: " << numSourceInputs << std::endl;

It prints Number of source inputs: 0

Moreover, in Execute function I OrientArray and ScaleArrays are also not found.

    vtkDataArray* scaleArray = this->GetInputArrayToProcess(0, input);
    vtkDataArray* orientArray = this->GetInputArrayToProcess(1, input);
        

But I am not sure how to fix it, would you be able to guide me?

Checkout this GlyphFilter example: https://kitware.github.io/vtk-examples/site/Java/Filtering/Glyph3D/
This shows how to setup the source input. In the example a vtkCubeSource is used to produce the dataset to use as a glyph. You can ofcourse choose the type you want.

vtkAlgorithm::SetInputArrayToProcess is used to select arrays for scale and orientation. For example,

glyph->SetInputArrayToProcess(0 /* index for scale array*/, /*port=*/0, /*connection=*/ 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Result");

This will attempt to use the a point array named “Result” from the 0th input connnection on input port index 0.

Since you are new to VTK pipelines, I’d suggest trying to modifying the VTK Python example to setup your pipeline and get it to work that way before attempting to package it in a filter to use in ParaView. It’ll perhaps be easier to debug any issues like these in the VTK code – just a suggestion, of course.

Thank you so much again!
Sorry to keep on bugging you. I have a couple of more questions:

  • Let’s say I set the source using vtkCubeSource, will my filter be restricted to cubes structure only? I want my filter to be general so that it can be applied on any object (just like actual Glyph filter in Paraview)

  • Is there any example where another filter/s are being used in the RequestData which I can follow. I want to see an example where something of this sort is happening:

auto* input0 = vtkDataObject::GetData(inputVector[0], 0);
this->ArrayCalculator->SetInputDataObject(input0);

this->GlyphFilter->SetInputConnection(this->ArrayCalculator->GetOutputPort());
this->GlyphFilter->Update();
  • By VTK Python example you mean the python code in the link you shared?

I’d really recommend playing with the VTK example to understand how the glyph filter works. The “source” input for the Glyph filter is the geometry used for the glyph. The Glyph filter takes two inputs: one is the geometry and the other is the dataset that provides the points on which to place the glyphs.

Yes.

Thank you for your help and suggestions. I was able to get rid of the errors and warnings, but glyph part of my filter cannot see “Result” array and it does not show in dropdown of Orientation and Scale arrays. And the glyphs also does not show up.

But I can see “Result” array in ArrayCalculator output, also in Glyph input.
Just as a reminder ArrayCalculator is an object of vtkPVArrayCalculator and GlyphFilter is an object of vtkPVGlyphFilter

Here is my Request Data function:

int vtkMyForceFilter::RequestData(
    vtkInformation *request,
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector)
{
  auto* input0 = vtkDataObject::GetData(inputVector[0], 0);
  this->ArrayCalculator->SetInputDataObject(input0);

  if (input0)
  {
    logFile << "Input dataset: "  << std::endl;
    input0->Print(logFile);
  }
  else
  {
    logFile << "Input dataset not available." << std::endl;
  }

  this->ArrayCalculator->Update();

  vtkDataObject* arrayCalcOutput = this->ArrayCalculator->GetOutputDataObject(0);
  if (!arrayCalcOutput)
  {
    logFile << "ArrayCalculator output not generated." << std::endl;
    return 0; // ArrayCalculator failed, return 0 to indicate failure
  }

  else{
    logFile << "ArrayCalculator output: "  << std::endl;
    arrayCalcOutput->Print(logFile);
  }

// Glyph Parts
  vtkNew<vtkArrowSource> arrowSource;

  this->GlyphFilter->SetSourceConnection(arrowSource->GetOutputPort());

  this->GlyphFilter->SetInputConnection(0,this->ArrayCalculator->GetOutputPort(0));

  // Set the vector array
  this->GlyphFilter->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Result");

  
  this->GlyphFilter->Update();
  // Get the output data object of the GlyphFilter
  vtkDataObject* glyphOutput = this->GlyphFilter->GetOutputDataObject(0);

  // Get the output data object of vtkMyForceFilter
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkDataObject* outputDataObject = outInfo->Get(vtkDataObject::DATA_OBJECT());

  // Shallow copy the output of GlyphFilter to the output of vtkMyForceFilter
 
  if (glyphOutput)
  {
    outputDataObject->ShallowCopy(glyphOutput);
    glyphOutput->Print(logFile);
  }
  else
  {
    logFile << "GlyphFilter output not generated." << std::endl;
  }

return 1;

Hi,
Thanks for your help again. In think I have almost made the filter. I can see the glyphs being generated.

I have two issues left now:

  1. If I make any changes in my filter more than once in the GUI, e.g. if I change the vector equation or change the color and click “Apply” for the second time the changes does not show. So essentially I can only see the changes once (for the first time only)
    I have checked that my filter’s RequestData function does not get called for the second time (if I click “Apply” for the second time)

  2. The orientation array and the scale array of Glyph part does not get updated and does not show “Result” array of calculator part in the dropdown.

This is my RequestData function now:

int vtkMyForceFilter::RequestData(
    vtkInformation *request,
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector)
{
 
  auto* input0 = vtkDataObject::GetData(inputVector[0], 0);
  vtkDataSet* output = vtkDataSet::GetData(outputVector);

  this->ArrayCalculator->SetInputData(input0);

  this->ArrayCalculator->Update();

  vtkDataObject* arrayCalcOutput = this->ArrayCalculator->GetOutputDataObject(0);

   vtkDataSet* dataset = vtkDataSet::SafeDownCast(arrayCalcOutput);

// Glyph Part
  vtkNew<vtkArrowSource> arrowSource;

  this->GlyphFilter->SetSourceConnection(arrowSource->GetOutputPort());
  this->GlyphFilter->SetInputData(dataset);

  this->GlyphFilter->SetInputConnection(this->ArrayCalculator->GetOutputPort());


  // // Set the vector array 
  this->GlyphFilter->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Result");

  this->GlyphFilter->Update();

  vtkDataObject* glyphOutput = this->GlyphFilter->GetOutput();

  // Shallow copy the output of GlyphFilter to the output of vtkMyForceFilter
 
  if (glyphOutput)
  {

    output->ShallowCopy(glyphOutput);

  }
  else
  {
    logFile << "GlyphFilter output not generated." << std::endl;
  }

  return 1;
}

Please share the whole class. You are probably missing Modified calls.

Hi, this is my .cxx file:

#include "vtkMyForceFilter.h"
#include "vtkPVGlyphFilter.h"
#include "vtkObjectFactory.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUnstructuredGrid.h"
#include "vtkGeometryFilter.h"
#include "vtkDataObject.h"

#include <string>
#include <iostream>
#include <vtkOutputWindow.h>
#include <iostream>
#include "vtkPointData.h"
#include <fstream>
#include "LogFile.h"
#include "vtkArrowSource.h"
#include "vtkPolyDataMapper.h"


vtkStandardNewMacro(vtkMyForceFilter);

vtkMyForceFilter::vtkMyForceFilter()

{
  
  logFile.open("MyForceFilter.log", std::ios_base::app);
  
  this->ArrayCalculator = vtkSmartPointer<vtkPVArrayCalculator>::New();

  this->GlyphFilter = vtkSmartPointer<vtkPVGlyphFilter>::New();
  // this->SetNumberOfInputPorts(2);
}

vtkMyForceFilter::~vtkMyForceFilter()
{
  logFile.close();

}

void vtkMyForceFilter::SetAttributeType(int value)
{
  this->ArrayCalculator->SetAttributeType(value);
}

void vtkMyForceFilter::SetCoordinateResults(int value)
{
  this->ArrayCalculator->SetCoordinateResults(value);
}
void vtkMyForceFilter::SetResultNormals(int value)
{
  this->ArrayCalculator->SetResultNormals(value);
}

void vtkMyForceFilter::SetResultTCoords(int value)
{
  this->ArrayCalculator->SetResultTCoords(value);
}
void vtkMyForceFilter::SetResultArrayName(std::string value)
{
  this->ArrayCalculator->SetResultArrayName(value.c_str());
}

void vtkMyForceFilter::SetFunction(std::string value)
{
  
  this->ArrayCalculator->SetFunction(value.c_str());
}

void vtkMyForceFilter::SetReplaceInvalidValues(int value)
{
  this->ArrayCalculator->SetReplaceInvalidValues(value);
}

void vtkMyForceFilter::SetReplacementValue(double value)
{
  this->ArrayCalculator->SetReplacementValue(value);
}

void vtkMyForceFilter::SetResultArrayType(int value)
{
  this->ArrayCalculator->SetResultArrayType(value);
}

void vtkMyForceFilter::SetFunctionParserTypeFromInt(int value)
{
  this->ArrayCalculator->SetFunctionParserTypeFromInt(value);
}


// Glyph Methods 

void vtkMyForceFilter::SetVectorScaleMode(int value)
{
  this->GlyphFilter->SetVectorScaleMode(value);
}

void vtkMyForceFilter::SetScaleFactor(double value)
{
  this->GlyphFilter->SetScaleFactor(value);
}
void vtkMyForceFilter::SetGlyphMode(int value)
{
  this->GlyphFilter->SetGlyphMode(value);
}
void vtkMyForceFilter::SetMaximumNumberOfSamplePoints(int value)
{
  this->GlyphFilter->SetMaximumNumberOfSamplePoints(value);
}
void vtkMyForceFilter::SetSeed(int value)
{
  this->GlyphFilter->SetSeed(value);
}
void vtkMyForceFilter::SetStride(int value)
{
  this->GlyphFilter->SetStride(value);
}

void vtkMyForceFilter::SetSourceTransform(vtkTransform* transform)
{
    this->GlyphFilter->SetSourceTransform(transform);
}

// This method is taken from Paraview's vtkPVGlyphFIlter.cxx
// Specify a source object at a specified table location.
void vtkMyForceFilter::SetSourceConnection(int id, vtkAlgorithmOutput* algOutput)
{
  if (id < 0)
  {
    vtkErrorMacro("Bad index " << id << " for source.");
    return;
  }

  int numConnections = this->GetNumberOfInputConnections(1);
  if (id < numConnections)
  {
    this->SetNthInputConnection(1, id, algOutput);
  }
  else if (id == numConnections && algOutput)
  {
    this->AddInputConnection(1, algOutput);
  }
  else if (algOutput)
  {
    vtkWarningMacro("The source id provided is larger than the maximum "
                    "source id, using "
      << numConnections << " instead.");
    this->AddInputConnection(1, algOutput);
  }
}

int vtkMyForceFilter::FillInputPortInformation(int port, vtkInformation* info)
{
  return this->GlyphFilter->FillInputPortInformation(port, info);
}


void vtkMyForceFilter::SetInputArrayToProcess(int idx, int port, int connection, int fieldAssociation, const char *name)
{
    this->GlyphFilter->SetInputArrayToProcess(idx, port, connection, fieldAssociation, name);
}


int vtkMyForceFilter::RequestData(
    vtkInformation *request,
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector)
{

  auto* input0 = vtkDataObject::GetData(inputVector[0], 0);
  vtkDataSet* output = vtkDataSet::GetData(outputVector);

  this->ArrayCalculator->SetInputData(input0);

  this->ArrayCalculator->Update();

  vtkDataObject* arrayCalcOutput = this->ArrayCalculator->GetOutputDataObject(0);

  vtkDataSet* dataset = vtkDataSet::SafeDownCast(arrayCalcOutput);

// Glyph Parts
  vtkNew<vtkArrowSource> arrowSource;

  this->GlyphFilter->SetSourceConnection(arrowSource->GetOutputPort());
  this->GlyphFilter->SetInputData(dataset);

  this->GlyphFilter->SetInputConnection(this->ArrayCalculator->GetOutputPort());


  // // Set the vector array 
  this->GlyphFilter->SetInputArrayToProcess(1, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Result");

  this->GlyphFilter->Update();
  // Get the output data object of the GlyphFilter
  // vtkDataObject* glyphOutput = this->GlyphFilter->GetOutputDataObject(0);
  vtkDataObject* glyphOutput = this->GlyphFilter->GetOutput();

  // Get the output data object of vtkMyForceFilter
  // vtkInformation* outInfo = outputVector->GetInformationObject(0);
  // vtkDataObject* outputDataObject = outInfo->Get(vtkDataObject::DATA_OBJECT());

  // Shallow copy the output of GlyphFilter to the output of vtkMyForceFilter
 
  if (glyphOutput)
  {
    output->ShallowCopy(glyphOutput);
  }
  else
  {
    logFile << "GlyphFilter output not generated." << std::endl;
  }

  return 1;
}

void vtkMyForceFilter::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

And this is my XML file. I have essentially just copied the XML files of Calculator and Glyph Filters.

<ServerManagerConfiguration>
  <ProxyGroup name="filters">
    <SourceProxy name="MyForceFilter" class="vtkMyForceFilter" label="MyForce">
      <Documentation long_help="Combines vtkPVArrayCalculator and vtkPVGlyphFilter functionality in a single filter.">
        This filter combines the functionalities of vtkPVArrayCalculator and vtkPVGlyphFilter in a single filter.
      </Documentation>

      <InputProperty command="SetInputConnection"
                     name="Input">
        <ProxyGroupDomain name="groups">
          <Group name="sources" />
          <Group name="filters" />
        </ProxyGroupDomain>
        <DataTypeDomain name="input_type">
          <DataType value="vtkDataSet" />
          <DataType value="vtkGraph"/>
          <DataType value="vtkTable"/>
          <DataType value="vtkHyperTreeGrid"/>
        </DataTypeDomain>
        <InputArrayDomain name="input_array" optional="1"/>


        <Documentation>This property specifies the input dataset (vtkDataSet, vtkTable or vtkGraph) to the
        Calculator filter. The scalar and vector variables may be chosen from
        this dataset's arrays.</Documentation>
      </InputProperty>


      <IntVectorProperty command="SetAttributeType"
                         default_values="0"
                         name="AttributeType"
                         number_of_elements="1">
        <FieldDataDomain name="enum">
          <RequiredProperties>
            <Property function="Input"
                      name="Input" />
          </RequiredProperties>
        </FieldDataDomain>
        <Documentation>This property determines on which types of field data the computation is to
        be performed on.</Documentation>
      </IntVectorProperty>
      <IntVectorProperty command="SetCoordinateResults"
                         default_values="0"
                         name="CoordinateResults"
                         number_of_elements="1">
        <BooleanDomain name="bool" />
        <Hints>
            <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="AttributeType" value="0" inverse="0" />
        </Hints>
        <Documentation>The value of this property determines whether the
        results of this computation should be used as point coordinates or as a
        new array.</Documentation>
      </IntVectorProperty>
      <IntVectorProperty command="SetResultNormals"
                         default_values="0"
                         name="ResultNormals"
                         number_of_elements="1"
                         panel_visibility="advanced">
        <BooleanDomain name="bool" />
        <Documentation>Set whether to output results as point/cell
        normals. Outputting as normals is only valid with vector
        results. Point or cell normals are selected using
        AttributeMode.</Documentation>
      </IntVectorProperty>
      <IntVectorProperty command="SetResultTCoords"
                         default_values="0"
                         name="ResultTCoords"
                         number_of_elements="1"
                         panel_visibility="advanced">
        <BooleanDomain name="bool" />
        <Documentation>Set whether to output results as point/cell
        texture coordinates.  Point or cell texture coordinates are
        selected using AttributeMode. 2-component texture coordinates
        cannot be generated at this time.</Documentation>
      </IntVectorProperty>
      <StringVectorProperty command="SetResultArrayName"
                            default_values="Result"
                            name="ResultArrayName"
                            number_of_elements="1">
        <Documentation>This property contains the name for the output array
        containing the result of this computation.</Documentation>
      </StringVectorProperty>
      <StringVectorProperty command="SetFunction"
                            name="Function"
                            number_of_elements="1"
                            panel_widget="calculator" >
        <Documentation>
This property contains the equation for computing the new
array.
        </Documentation>
      </StringVectorProperty>
      <IntVectorProperty command="SetReplaceInvalidValues"
                         default_values="1"
                         label="Replace Invalid Results"
                         name="ReplaceInvalidValues"
                         number_of_elements="1"
                         panel_visibility="advanced">
        <BooleanDomain name="bool" />
        <Documentation>This property determines whether invalid values in the
        computation will be replaced with a specific value. (See the
        ReplacementValue property.)</Documentation>
      </IntVectorProperty>
      <DoubleVectorProperty command="SetReplacementValue"
                            default_values="0.0"
                            name="ReplacementValue"
                            number_of_elements="1"
                            panel_visibility="advanced">
        <DoubleRangeDomain name="range" />
        <Documentation>If invalid values in the computation are to be replaced
        with another value, this property contains that value.</Documentation>
      </DoubleVectorProperty>
      <IntVectorProperty command="SetResultArrayType"
                         default_values="11"
                         label="Result Array Type"
                         name="ResultArrayType"
                         number_of_elements="1"
                         panel_visibility="advanced">
        <EnumerationDomain name="enum">
          <Entry text="Char"
                 value="2" />
          <Entry text="Signed Char"
                 value="15" />
          <Entry text="Unsigned Char"
                 value="3" />
          <Entry text="Short"
                 value="4" />
          <Entry text="Unsigned Short"
                 value="5" />
          <Entry text="Int"
                 value="6" />
          <Entry text="Unsigned Int"
                 value="7" />
          <Entry text="Long"
                 value="8" />
          <Entry text="Unsigned Long"
                 value="9" />
          <Entry text="Float"
                 value="10" />
          <Entry text="Double"
                 value="11" />
          <Entry text="Id Type"
                 value="12" />
        </EnumerationDomain>
        <Documentation>This property determines what array type to output.
        The default is a vtkDoubleArray.</Documentation>
      </IntVectorProperty>
      <IntVectorProperty name="FunctionParserType"
                         command="SetFunctionParserTypeFromInt"
                         default_values="1"
                         number_of_elements="1"
                         panel_visibility="never">
        <Documentation>Hidden property that specifies whether the old (ParaView 5.9 and before)
        expression parser or new (ParaView 5.10) vtkPVLinearExtrusionFilter is used.</Documentation>
      </IntVectorProperty>


      <InputProperty command="SetSourceConnection"
                     label="Glyph Type"
                     name="Source">
        <ProxyGroupDomain name="groups">
          <Group name="sources" />
          <Group name="glyph_sources" />
        </ProxyGroupDomain>
        <DataTypeDomain name="input_type">
          <DataType value="vtkPolyData" />
        </DataTypeDomain>
        <ProxyListDomain name="proxy_list">
          <Proxy group="sources" name="ArrowSource" />
          <Proxy group="sources" name="ConeSource" />
          <Proxy group="sources" name="CubeSource" />
          <Proxy group="sources" name="CylinderSource" />
          <Proxy group="sources" name="LineSource" />
          <Proxy group="sources" name="SphereSource" />
          <Proxy group="sources" name="GlyphSource2D" />
        </ProxyListDomain>
        <Hints>
          <ProxyPropertyWidget selected_proxy_panel_visibility="advanced" />
          <!-- show the selected proxy's panel, only in advanced mode. -->
        </Hints>
        <Documentation>
This property determines which type of glyph will be placed at the
points in the input dataset.
        </Documentation>
      </InputProperty>
      <StringVectorProperty command="SetInputArrayToProcess"
                            default_values="1"
                            element_types="0 0 0 0 2"
                            name="OrientationArray"
                            number_of_elements="5">
        <!-- default value=1 so normals go to the right place -->
        <ArrayListDomain attribute_type="Vectors"
                         input_domain_name="vector_array"
                         name="array_list"
                         none_string="No orientation array">
          <RequiredProperties>
            <Property function="Input"
                      name="Input" />
          </RequiredProperties>

        </ArrayListDomain>
        <Documentation>
Select the input array to use for orienting the glyphs.
        </Documentation>
      </StringVectorProperty>
      <StringVectorProperty command="SetInputArrayToProcess"
                            default_values="0"
                            element_types="0 0 0 0 2"
                            name="ScaleArray"
                            number_of_elements="5">
        <ArrayListDomain attribute_type="Scalars"
                         input_domain_name="scale_array"
                         name="array_list"
                         none_string="No scale array">
          <RequiredProperties>
            <Property function="Input"
                      name="Input" />
          </RequiredProperties>
 
        </ArrayListDomain>
        <Documentation>
Select the input array to be used for scaling the glyphs. If the scale
array is a vector array, you can control how the glyphs are scaled with
the **Vector Scale Mode** property.
        </Documentation>
      </StringVectorProperty>
      <IntVectorProperty command="SetVectorScaleMode"
                         default_values="0"
                         name="VectorScaleMode"
                         number_of_elements="1">
        <EnumerationDomain name="enum">
          <Entry text="Scale by Magnitude"
                 value="0" />
          <Entry text="Scale by Components"
                 value="1" />
        </EnumerationDomain>
        <Documentation>
Select the mode when the scaling array is a vector. **Scale by Magnitude** scales the glyph by
the vector magnitude. **Scale by Components** scales glyphs by each vector component in the dimension
that component represents, e.g., the x-direction is scaled by component 0, the y-direction is
scaled by component 1, and so on.
        </Documentation>
        <Hints>
          <PropertyWidgetDecorator type="GenericDecorator"
                                   mode="visibility"
                                   property="ScaleArray"
                                   number_of_components="3"
                                   index="4" />
        </Hints>
      </IntVectorProperty>

      <IntVectorProperty information_only="1"
                         name="ComponentSelection"
                         default_values="4"
                         number_of_elements="1"
                         panel_visibility="never">
        <Documentation>
Specifies array component to use. Fixed at 4 to ensure the
ArrayRangeDomain is set to the vector magnitude for up to 3-component
arrays.
        </Documentation>
      </IntVectorProperty>
      <DoubleVectorProperty command="SetScaleFactor"
                            default_values="1.0"
                            name="ScaleFactor"
                            number_of_elements="1"
                            panel_widget="glyph_scale_factor">
        <BoundsDomain mode="scaled_extent" name="bounds" scale_factor="0.1">
          <RequiredProperties>
            <Property function="Input" name="Input" />
          </RequiredProperties>
        </BoundsDomain>
        <ArrayRangeDomain name="scalar_range">
          <RequiredProperties>
            <Property function="Input" name="Input" />
            <Property function="ArraySelection" name="ScaleArray" />
          </RequiredProperties>
        </ArrayRangeDomain>
        <ArrayRangeDomain name="vector_range">
          <RequiredProperties>
            <Property function="Input" name="Input" />
            <Property function="ArraySelection" name="OrientationArray" />
          </RequiredProperties>
        </ArrayRangeDomain>
        <Documentation>Specify the constant multiplier to use to scale the glyphs.
        </Documentation>
      </DoubleVectorProperty>
      <ProxyProperty command="SetSourceTransform"
                     name="GlyphTransform"
                     panel_visibility="advanced">
        <ProxyListDomain name="proxy_list">
          <Proxy group="extended_sources"
                 name="Transform2" />
        </ProxyListDomain>
        <Documentation>
The values in this property allow you to specify the transform
(translation, rotation, and scaling) to apply to the glyph
source.</Documentation>
      </ProxyProperty>

      <IntVectorProperty command="SetGlyphMode"
                         default_values="2"
                         name="GlyphMode"
                         number_of_elements="1"
                         panel_visibility="default">
        <EnumerationDomain name="enum">
          <Entry text="All Points" value="0"/>
          <Entry text="Every Nth Point" value="1"/>
          <Entry text="Uniform Spatial Distribution (Bounds Based)" value="2"/>
          <Entry text="Uniform Spatial Distribution (Surface Sampling)" value="3"/>
          <Entry text="Uniform Spatial Distribution (Volume Sampling)" value="4"/>
        </EnumerationDomain>
        <Documentation>
This property indicates the mode that will be used to generate
glyphs from the dataset.
        </Documentation>
      </IntVectorProperty>
      <IntVectorProperty command="SetMaximumNumberOfSamplePoints"
                        number_of_elements="1"
                        default_values="5000"
                        name="MaximumNumberOfSamplePoints">
        <IntRangeDomain min="1" name="range" />
        <Documentation>
This property specifies the maximum number of sample points to use
when sampling the space when Uniform Spatial Distribution is used.
        </Documentation>
        <Hints>
          <PropertyWidgetDecorator type="CompositeDecorator">
            <Expression type="or">
              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="2" inverse="0" />
              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="3" inverse="0" />
              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="4" inverse="0" />
            </Expression>
          </PropertyWidgetDecorator>
          <!-- show this widget when GlyphMode==2||3||4 -->
        </Hints>
      </IntVectorProperty>
      <IntVectorProperty command="SetSeed"
                        number_of_elements="1"
                        default_values="10339"
                        name="Seed">
        <IntRangeDomain min="1" name="range"/>
        <Documentation>
This property specifies the seed that will be used for generating a
uniform distribution of glyph points when a Uniform Spatial
Distribution is used.
        </Documentation>
        <Hints>
          <PropertyWidgetDecorator type="CompositeDecorator">
            <Expression type="or">
              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="2" inverse="0" />
              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="3" inverse="0" />
              <PropertyWidgetDecorator type="GenericDecorator" mode="visibility" property="GlyphMode" value="4" inverse="0" />
            </Expression>
          </PropertyWidgetDecorator>
          <!-- show this widget when GlyphMode==2||3||4 -->
        </Hints>
      </IntVectorProperty>
      <IntVectorProperty command="SetStride"
                         number_of_elements="1"
                         default_values="1"
                         name="Stride">
        <IntRangeDomain min="1" name="range"/>
        <Documentation>
This property specifies the stride that will be used when glyphing by
Every Nth Point.
        </Documentation>
        <Hints>
          <PropertyWidgetDecorator type="GenericDecorator"
                                   mode="visibility"
                                   property="GlyphMode"
                                   value="1" />
          <!-- show this widget when GlyphMode==1 -->
        </Hints>
     </IntVectorProperty>

      <PropertyGroup label="Glyph Source">
        <Property name="Source" />
      </PropertyGroup>
      <PropertyGroup label="Orientation">
        <Property name="OrientationArray" />
      </PropertyGroup>
      <PropertyGroup label="Scale">
        <Property name="ScaleArray" />
        <Property name="VectorScaleMode" />
        <Property name="ScaleFactor" />
      </PropertyGroup>
      <PropertyGroup label="Glyph Transform">
        <Property name="GlyphTransform" />
      </PropertyGroup>
      <PropertyGroup label="Masking">
        <Property name="GlyphMode" />
        <Property name="MaximumNumberOfSamplePoints" />
        <Property name="Seed" />
        <Property name="Stride" />
      </PropertyGroup>

      <Hints>
        <!-- Visibility Element can be used to suggest the GUI about
          visibility of this filter (or its input) on creation.
          replace_input="0" implies that the input visibility is not
            changed on creation of this filter (defaults to "1")
       -->
        <Visibility replace_input="0" />
        <WarnOnCreate>
          <DataTypeDomain name="input_type">
            <DataType value="vtkDataSet" />
          </DataTypeDomain>
          <MemoryUsage relative="500" />
          <Text title="Potentially running out of memory">
            **Glyph** filter will create one geometry by point
            if configured as such in the "Glyph Mode" property,
            which you may not have enough memory to do.
            Do you want to continue?
          </Text>
        </WarnOnCreate>
      </Hints>

    </SourceProxy>
  </ProxyGroup>
</ServerManagerConfiguration>

Add this->Modified() on every single setter.

Thank you so much, that fixed the first issue. Now I can update vector equation and other properties.

The only thing left is that Orientation Array and Scale Array in glyph part does not show “Result” array in the dropdown.

My guess is that the issue could be in either XML or in this line maybe: this->GlyphFilter->SetInputData(dataset);

  vtkDataObject* arrayCalcOutput = this->ArrayCalculator->GetOutputDataObject(0);
  
   vtkDataSet* dataset = vtkDataSet::SafeDownCast(arrayCalcOutput);

  vtkNew<vtkArrowSource> arrowSource;

  this->GlyphFilter->SetSourceConnection(arrowSource->GetOutputPort());
  this->GlyphFilter->SetInputData(dataset);

  this->GlyphFilter->SetInputConnection(this->ArrayCalculator->GetOutputPort());

BTW in the information tab of pipeline browser, I can see “Result” and “Tcoords” arrays but the orientation and scale arrays show “Normals” and “TCoords”

wdym ?

So, the vector equation or the function in the Calculator filter is referred to as “Result”. When I write a vector equation in the Calculator filter part of my filter and click “Apply” I can see that “Result” array is generated in the Information tab. And glyphs also change direction based on the equation I write in the Calculator.

But the orientation and scale arrays of Glyph filter part does not gets updated with “Result” array/vector.

Whereas, if I don’t combine these two filters into one and just use Paraview’s given calculator and glyph filter one by one, the glyph filter’s orientation and scale arrays do show “Result” array/vector from the calculator filter, and I am able to change both the scale and orientation of the glyphs based on the arrays/vectors I choose from their dropdown menus.