VTK notes - clipping, segmentation - irregular closed loop clipping - vtkiplicitselectionloop class


Vtkiplicitselectionloop is a subclass of vtkiplicitfunction class. It calculates implicit function values and function gradients for an irregular cylindrical object whose cross section is defined by a set of points forming a loop. The loop does not have to be a convex polygon, and all points do not have to be on the same plane. However, when projected onto a plane defined by the cumulative cross product around the loop (that is, the axis of the loop), the ring must be non self intersecting (or you can specify the normal to use.)
The SetClipFunction of vtkClipPolyData uses the subclass of vtkplicitfunction. After the vtkCylinder class is input to vtkClipPolyData, the input source data through vtkClipPolyData will be generated. The vtkplicitselectionloop is relatively in the vtkCylinder class, but its cross section is an irregular polygon composed of multiple continuous surrounding points, The connecting lines between the current point and the previous point do not cross each other to ensure that a closed polygon can be defined; Generally, the externally set point sets are points on the same plane. Vtkiplicitselectionloop can automatically calculate the normal vector of the plane where these points are located. This normal vector is the depth vector of the cylinder, which determines the data to be cropped and those data to be cropped; Each point of the loop is first projected onto the plane defined by the loop normal, which forms a polygon. Then, in order to calculate the implicit function value, use inside/outside to determine whether x is in the polygon, and calculate the distance to the closed polygon boundary of the loop (negative value is in the loop).


Input point set

Set and obtain the vtkPoints collection by calling the methods SetLoop and GetLoop;
It is required that the order of points can form a closed polygon without self intersection;

vtkPoints* Loop;
virtual void SetLoop(vtkPoints*);
vtkGetObjectMacro(Loop, vtkPoints);

normal vector

The input Loop point set constitutes the same projection plane, and the starting point and Normal vector of the plane are recorded by Origin and Normal member variables;

double Normal[3];
vtkSetVector3Macro(Normal, double);
vtkGetVectorMacro(Normal, double, 3);
double Origin[3];
double Bounds[6]; // bounds of the projected polyon

Use the AutomaticNormalGeneration control to turn on / off the automatic calculation of normal vectors;
By default, normals are calculated based on the cumulative cross product of edges; You can also specify the normals to use.

vtkTypeBool AutomaticNormalGeneration;
vtkSetMacro(AutomaticNormalGeneration, vtkTypeBool);
vtkGetMacro(AutomaticNormalGeneration, vtkTypeBool);
vtkBooleanMacro(AutomaticNormalGeneration, vtkTypeBool);

Calculate the distance between the point and the boundary

EvaluateFunction returns a signed value. According to the symbol, you can judge whether the point is in a closed curve on the projection plane; Deciding whether to cut or not is of little use at present;

using vtkImplicitFunction::EvaluateFunction;
double EvaluateFunction(double x[3]) override;  
void EvaluateGradient(double x[3], double n[3]) override;


Draw a loop on the mesh surface and use it to clip or extract cells from the loop.

#include "vtk_include.h"
#include <vtkClipPolyData.h>
#include <vtkImplicitSelectionLoop.h>
#include <vtkLODActor.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
class Test_ImplicitSelectionLoop {
	static void Test() {
		vtkNew<vtkNamedColors> colors;

		vtkNew<vtkSphereSource> sphereSource;

		vtkNew<vtkPoints> selectionPoints;
		selectionPoints->InsertPoint(0, -0.16553, 0.135971, 0.451972);
		selectionPoints->InsertPoint(1, -0.0880123, -0.134952, 0.4747);
		selectionPoints->InsertPoint(2, 0.00292618, -0.134604, 0.482459);
		selectionPoints->InsertPoint(3, 0.0641941, 0.067112, 0.490947);
		selectionPoints->InsertPoint(4, 0.15577, 0.0734765, 0.469245);
		selectionPoints->InsertPoint(5, 0.166667, -0.129217, 0.454622);
		selectionPoints->InsertPoint(6, 0.241259, -0.123363, 0.420581);
		selectionPoints->InsertPoint(7, 0.240334, 0.0727106, 0.432555);
		selectionPoints->InsertPoint(8, 0.308529, 0.0844311, 0.384357);
		selectionPoints->InsertPoint(9, 0.32672, -0.121674, 0.359187);
		selectionPoints->InsertPoint(10, 0.380721, -0.117342, 0.302527);
		selectionPoints->InsertPoint(11, 0.387804, 0.0455074, 0.312375);
		selectionPoints->InsertPoint(12, 0.43943, -0.111673, 0.211707);
		selectionPoints->InsertPoint(13, 0.470984, -0.0801913, 0.147919);
		selectionPoints->InsertPoint(14, 0.436777, 0.0688872, 0.233021);
		selectionPoints->InsertPoint(15, 0.44874, 0.188852, 0.109882);
		selectionPoints->InsertPoint(16, 0.391352, 0.254285, 0.176943);
		selectionPoints->InsertPoint(17, 0.373274, 0.154162, 0.294296);
		selectionPoints->InsertPoint(18, 0.274659, 0.311654, 0.276609);
		selectionPoints->InsertPoint(19, 0.206068, 0.31396, 0.329702);
		selectionPoints->InsertPoint(20, 0.263789, 0.174982, 0.387308);
		selectionPoints->InsertPoint(21, 0.213034, 0.175485, 0.417142);
		selectionPoints->InsertPoint(22, 0.169113, 0.261974, 0.390286);
		selectionPoints->InsertPoint(23, 0.102552, 0.25997, 0.414814);
		selectionPoints->InsertPoint(24, 0.131512, 0.161254, 0.454705);
		selectionPoints->InsertPoint(25, 0.000192443, 0.156264, 0.475307);
		selectionPoints->InsertPoint(26, -0.0392091, 0.000251724, 0.499943);
		selectionPoints->InsertPoint(27, -0.096161, 0.159646, 0.46438);

		vtkNew<vtkImplicitSelectionLoop> loop;

		vtkNew<vtkClipPolyData> clip;

		vtkNew<vtkPolyDataMapper> clipMapper;

		vtkNew<vtkProperty> backProp;

		vtkNew<vtkLODActor> clipActor;

		vtkNew<vtkRenderer> renderer;
		vtkNew<vtkRenderWindow> renderWindow;
		vtkNew<vtkRenderWindowInteractor> interactor;

		// Add the actors to the renderer, set the background and size

		renderWindow->SetSize(500, 500);


Modify the interior point coordinate information of selectionPoints

vtkNew<vtkPoints> selectionPoints;
selectionPoints->InsertPoint(0, 0, 0, 0);
selectionPoints->InsertPoint(1, 0.25, 0, 0);
selectionPoints->InsertPoint(2, 0.25, 0.25, 0);
selectionPoints->InsertPoint(3, 0, 0.25, 0);
selectionPoints->InsertPoint(4, 0.125, 0.125, 0);

Use GetNormal to obtain the normal vector of the closed polygon formed by the current point set;

double x[3] = { 0 };

The value of x obtained is (0,0,1), indicating that the direction of the cylinder is Z direction, perpendicular to the XY plane;

Modify the interior point coordinate information of selectionPoints

vtkNew<vtkPoints> selectionPoints;
selectionPoints->InsertPoint(0, 0, 0, 0);
selectionPoints->InsertPoint(1, 0, 0.25, 0);
selectionPoints->InsertPoint(2, 0, 0.25, 0.25);
selectionPoints->InsertPoint(3, 0, 0, 0.25);
selectionPoints->InsertPoint(4, 0, 0.125, 0.125);

Use GetNormal to obtain the normal vector of the closed polygon formed by the current point set, and it is found that the normal vector is still (0,0,1);
In renderwindow - > render(); After using GetNormal, the normal vector is (1,0,0); The direction of the column is along the X-axis and perpendicular to the YZ plane;

reference material

1.ImplicitSelectionLoop example
2.vtkImplicitSelectionLoop Class Reference

Keywords: vtk

Added by Shock_CNOP on Thu, 27 Jan 2022 08:44:20 +0200