vtkWarpVector does not work. Any possible bug?

Dear all,

I want to scale the spline from its center as an offset (the same it does with the right mouse but we do not have access to use this function). I have tried many ways with no success. I have checked this vtkWarpVector that it scales as an offset. But it is not clear to me why it does not work. It does not return anything.
can it be a bug?. I do not know if this is the correct forum because i never get any answer.

The code is the following:

                 	vtkNew<vtkSplineRepresentation> spline;
		new_points = global_scene->get_curve_points();
		spline->InitializeHandles(new_points);

		vtkSmartPointer<vtkParametricFunctionSource> functionSource =
				vtkSmartPointer<vtkParametricFunctionSource>::New();
		functionSource->SetParametricFunction(spline->GetParametricSpline());
		functionSource->Update();


		// Generate normals
		vtkSmartPointer<vtkPolyDataNormals> normals =
		vtkSmartPointer<vtkPolyDataNormals>::New();
	        normals->SetInputConnection(functionSource->GetOutputPort());
		normals->SplittingOff();

		// Warp using the normals
		vtkSmartPointer<vtkWarpVector> warp =
		vtkSmartPointer<vtkWarpVector>::New();
		warp->SetInputData(normals->GetOutput());
		warp->SetInputArrayToProcess(0, 0, 0,
		vtkDataObject::FIELD_ASSOCIATION_POINTS,
		vtkDataSetAttributes::NORMALS);
		warp->SetScaleFactor(2);

		warp->Update();

Do you get any output from your vtkPolyDataNormals?
I suspect not, because the vtkParametricFunctionSource would generate lines and vtkPolyDataNormals will not calculate normals for lines.

Thank you for your answer. I have also tried to use a polidata defines by points and cells with no sucess. I have also tried to compute the normals but

the results was not ok either. I get the same points as the original ones.

Thanks

vtkSmartPointer vertices =
vtkSmartPointer::New();

            vtkSmartPointer<vtkPoints> points =
                vtkSmartPointer<vtkPoints>::New();

           
            for (int i = 0; i < new_points->GetNumberOfPoints(); ++i)
            {
                //Declare a variable to store the index of the point that gets added. This behaves just like an unsigned int.
                vtkIdType pid[1];
                double pts1[3];
                new_points->GetPoint(i, pts1);

                //Add a point to the polydata and save its index, which we will use to create the vertex on that point.
                pid[0] = points->InsertNextPoint(pts1);

                //create a vertex cell on the point that was just added.
                vertices->InsertNextCell(1, pid);
            }

            //add the points and vertices to a polydata
            vtkSmartPointer<vtkPolyData> polydata =
                vtkSmartPointer<vtkPolyData>::New();
            polydata->SetPoints(points);
            polydata->SetVerts(vertices);

           

            // Generate normals
            vtkSmartPointer<vtkPolyDataNormals> normals =
                vtkSmartPointer<vtkPolyDataNormals>::New();
            normals->SetInputData(polydata);
            normals->SplittingOff();
            normals->ConsistencyOn();
            normals->ComputePointNormalsOn();
            normals->Update();

            // Warp using the normals
            vtkSmartPointer<vtkWarpVector> warp =
                vtkSmartPointer<vtkWarpVector>::New();
            warp->SetInputArrayToProcess(0, 0, 0,
                vtkDataObject::FIELD_ASSOCIATION_POINTS,
                vtkDataSetAttributes::NORMALS);
            warp->SetInputData(polydata);
            warp->SetScaleFactor(2.5);
            warp->Update();

           
            new_points->Initialize();
            for (int i = 0; i < warp->GetOutput()->GetNumberOfPoints(); i++)
            {
                double p[3];
                warp->GetOutput()->GetPoint(i, p);
                new_points->InsertNextPoint(p);
                // This is identical to:
                // polydata->GetPoints()->GetPoint(i,p);
                std::cout << "Point " << i << " : (" << p[0] << " " << p[1] << " " << p[2] << ")" << std::endl;
            }

Normals can only be computed for polygons and triangle strips. The polydata you make has only vertices, and there’s no way the vtkPolyDataNormals can decide in which direction you want to point the normals.

If you have polygons, then you can tell the vtkPolyDataNormals to produce normals in point data or in cell data or both by using ComputePointNormalsOn and ComputeCellNormalsOn. Neither of these will have any effect if your input polydata has only vertices and/or lines. Note that when you polydata has lines and/or vertices in addition to polygons and/or strips, the normals will be calculated only for the polygons+strips, leading to ‘corrupt’ output.

Considering what you want I don’t think vtkPolyDataNormals is the right algorithm to use, and I’m not sure if there is a dedicated algorithm. You could try and use vtkArrayCalculator?

Hi for answering. I tried this way too but the offset is taken from a different origin even if i define it. I will keep thinking. Thank you

center_point[0] = center_point[0] / new_points->GetNumberOfPoints();
center_point[1] = center_point[1] / new_points->GetNumberOfPoints();
center_point[2] = center_point[2] / new_points->GetNumberOfPoints();*/

            vtkSmartPointer<vtkTransform> transform =
                vtkSmartPointer<vtkTransform>::New();
            transform->Identity();
            transform->Translate(-center_point[0], -center_point[1], -center_point[2]);
            transform->Scale(1.5, 1.5, 1);
            transform->Translate(center_point[0], center_point[1], center_point[2]);

            vtkSmartPointer<vtkTransformFilter> transformFilter =
                vtkSmartPointer<vtkTransformFilter>::New();
            transformFilter->SetInputConnection(functionSource->GetOutputPort());

            transformFilter->SetTransform(transform);
            transformFilter->Update();

solved with geometry. Thanks