You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
7.6 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkSelectPolyData.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkSelectPolyData
* @brief select portion of polygonal mesh; generate selection scalars
*
* vtkSelectPolyData is a filter that selects polygonal data based on
* defining a "loop" and indicating the region inside of the loop. The
* mesh within the loop consists of complete cells (the cells are not
* cut). Alternatively, this filter can be used to generate scalars.
* These scalar values, which are a distance measure to the loop, can
* be used to clip, contour. or extract data (i.e., anything that an
* implicit function can do).
*
* The loop is defined by an array of x-y-z point coordinates.
* (Coordinates should be in the same coordinate space as the input
* polygonal data.) The loop can be concave and non-planar, but not
* self-intersecting. The input to the filter is a polygonal mesh
* (only surface primitives such as triangle strips and polygons); the
* output is either a) a portion of the original mesh laying within
* the selection loop (GenerateSelectionScalarsOff); or b) the same
* polygonal mesh with the addition of scalar values
* (GenerateSelectionScalarsOn).
*
* The algorithm works as follows. For each point coordinate in the
* loop, the closest point in the mesh is found. The result is a loop
* of closest point ids from the mesh. Then, the edges in the mesh
* connecting the closest points (and laying along the lines forming
* the loop) are found. A greedy edge tracking procedure is used as
* follows. At the current point, the mesh edge oriented in the
* direction of and whose end point is closest to the line is
* chosen. The edge is followed to the new end point, and the
* procedure is repeated. This process continues until the entire loop
* has been created.
*
* To determine what portion of the mesh is inside and outside of the
* loop, three options are possible. 1) the smallest connected region,
* 2) the largest connected region, and 3) the connected region
* closest to a user specified point. (Set the ivar SelectionMode.)
*
* Once the loop is computed as above, the GenerateSelectionScalars
* controls the output of the filter. If on, then scalar values are
* generated based on distance to the loop lines. Otherwise, the cells
* laying inside the selection loop are output. By default, the mesh
* laying within the loop is output; however, if InsideOut is on, then
* the portion of the mesh laying outside of the loop is output.
*
* The filter can be configured to generate the unselected portions of
* the mesh as output by setting GenerateUnselectedOutput. Use the
* method GetUnselectedOutput to access this output. (Note: this flag
* is pertinent only when GenerateSelectionScalars is off.)
*
* @warning
* Make sure that the points you pick are on a connected surface. If
* not, then the filter will generate an empty or partial result. Also,
* self-intersecting loops will generate unpredictable results.
*
* @warning
* During processing of the data, non-triangular cells are converted to
* triangles if GenerateSelectionScalars is off.
*
* @sa
* vtkImplicitSelectionLoop
*/
#ifndef vtkSelectPolyData_h
#define vtkSelectPolyData_h
#include "vtkFiltersModelingModule.h" // For export macro
#include "vtkPolyDataAlgorithm.h"
#define VTK_INSIDE_SMALLEST_REGION 0
#define VTK_INSIDE_LARGEST_REGION 1
#define VTK_INSIDE_CLOSEST_POINT_REGION 2
class vtkCharArray;
class vtkPoints;
class vtkIdList;
class VTKFILTERSMODELING_EXPORT vtkSelectPolyData : public vtkPolyDataAlgorithm
{
public:
/**
* Instantiate object with InsideOut turned off, and
* GenerateSelectionScalars turned off. The unselected output
* is not generated, and the inside mode is the smallest region.
*/
static vtkSelectPolyData* New();
vtkTypeMacro(vtkSelectPolyData, vtkPolyDataAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@{
/**
* Set/Get the flag to control behavior of the filter. If
* GenerateSelectionScalars is on, then the output of the filter
* is the same as the input, except that scalars are generated.
* If off, the filter outputs the cells laying inside the loop, and
* does not generate scalars.
*/
vtkSetMacro(GenerateSelectionScalars, vtkTypeBool);
vtkGetMacro(GenerateSelectionScalars, vtkTypeBool);
vtkBooleanMacro(GenerateSelectionScalars, vtkTypeBool);
//@}
//@{
/**
* Set/Get the InsideOut flag. When off, the mesh within the loop is
* extracted. When on, the mesh outside the loop is extracted.
*/
vtkSetMacro(InsideOut, vtkTypeBool);
vtkGetMacro(InsideOut, vtkTypeBool);
vtkBooleanMacro(InsideOut, vtkTypeBool);
//@}
//@{
/**
* Set/Get the array of point coordinates defining the loop. There must
* be at least three points used to define a loop.
*/
virtual void SetLoop(vtkPoints*);
vtkGetObjectMacro(Loop, vtkPoints);
//@}
//@{
/**
* Set/Get the point used in SelectionModeToClosestPointRegion.
*/
vtkSetVector3Macro(ClosestPoint, double);
vtkGetVector3Macro(ClosestPoint, double);
//@}
//@{
/**
* Control how inside/outside of loop is defined.
*/
vtkSetClampMacro(SelectionMode, int, VTK_INSIDE_SMALLEST_REGION, VTK_INSIDE_CLOSEST_POINT_REGION);
vtkGetMacro(SelectionMode, int);
void SetSelectionModeToSmallestRegion() { this->SetSelectionMode(VTK_INSIDE_SMALLEST_REGION); }
void SetSelectionModeToLargestRegion() { this->SetSelectionMode(VTK_INSIDE_LARGEST_REGION); }
void SetSelectionModeToClosestPointRegion()
{
this->SetSelectionMode(VTK_INSIDE_CLOSEST_POINT_REGION);
}
const char* GetSelectionModeAsString();
//@}
//@{
/**
* Control whether a second output is generated. The second output
* contains the polygonal data that's not been selected.
*/
vtkSetMacro(GenerateUnselectedOutput, vtkTypeBool);
vtkGetMacro(GenerateUnselectedOutput, vtkTypeBool);
vtkBooleanMacro(GenerateUnselectedOutput, vtkTypeBool);
//@}
/**
* Return output that hasn't been selected (if GenreateUnselectedOutput is
* enabled).
*/
vtkPolyData* GetUnselectedOutput();
/**
* Return the (mesh) edges of the selection region.
*/
vtkPolyData* GetSelectionEdges();
// Overload GetMTime() because we depend on Loop
vtkMTimeType GetMTime() override;
protected:
vtkSelectPolyData();
~vtkSelectPolyData() override;
int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
vtkTypeBool GenerateSelectionScalars;
vtkTypeBool InsideOut;
vtkPoints* Loop;
int SelectionMode;
double ClosestPoint[3];
vtkTypeBool GenerateUnselectedOutput;
private:
vtkPolyData* Mesh;
void GetPointNeighbors(vtkIdType ptId, vtkIdList* nei);
private:
vtkSelectPolyData(const vtkSelectPolyData&) = delete;
void operator=(const vtkSelectPolyData&) = delete;
};
//@{
/**
* Return the method of determining in/out of loop as a string.
*/
inline const char* vtkSelectPolyData::GetSelectionModeAsString(void)
{
if (this->SelectionMode == VTK_INSIDE_SMALLEST_REGION)
{
return "InsideSmallestRegion";
}
else if (this->SelectionMode == VTK_INSIDE_LARGEST_REGION)
{
return "InsideLargestRegion";
}
else
{
return "InsideClosestPointRegion";
}
}
//@}
#endif