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.

320 lines
12 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkClipClosedSurface.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 vtkClipClosedSurface
* @brief Clip a closed surface with a plane collection
*
* vtkClipClosedSurface will clip a closed polydata surface with a
* collection of clipping planes. It will produce a new closed surface
* by creating new polygonal faces where the input data was clipped.
*
* Non-manifold surfaces should not be used as input for this filter.
* The input surface should have no open edges, and must not have any
* edges that are shared by more than two faces. The vtkFeatureEdges
* filter can be used to verify that a data set satisfies these conditions.
* In addition, the input surface should not self-intersect, meaning
* that the faces of the surface should only touch at their edges.
*
* If GenerateOutline is on, this filter will generate an outline wherever
* the clipping planes intersect the data. The ScalarMode option
* will add cell scalars to the output, so that the generated faces
* can be visualized in a different color from the original surface.
*
* @warning
* The triangulation of new faces is done in O(n) time for simple convex
* inputs, but for non-convex inputs the worst-case time is O(n^2*m^2)
* where n is the number of points and m is the number of 3D cavities.
* The best triangulation algorithms, in contrast, are O(n log n).
* There are also rare cases where the triangulation will fail to produce
* a watertight output. Turn on TriangulationErrorDisplay to be notified
* of these failures.
* @sa
* vtkOutlineFilter vtkOutlineSource vtkVolumeOutlineSource
* @par Thanks:
* Thanks to David Gobbi for contributing this class to VTK.
*/
#ifndef vtkClipClosedSurface_h
#define vtkClipClosedSurface_h
#include "vtkFiltersGeneralModule.h" // For export macro
#include "vtkPolyDataAlgorithm.h"
class vtkPlaneCollection;
class vtkUnsignedCharArray;
class vtkDoubleArray;
class vtkIdTypeArray;
class vtkCellArray;
class vtkPointData;
class vtkCellData;
class vtkPolygon;
class vtkIdList;
class vtkCCSEdgeLocator;
enum
{
VTK_CCS_SCALAR_MODE_NONE = 0,
VTK_CCS_SCALAR_MODE_COLORS = 1,
VTK_CCS_SCALAR_MODE_LABELS = 2
};
class VTKFILTERSGENERAL_EXPORT vtkClipClosedSurface : public vtkPolyDataAlgorithm
{
public:
static vtkClipClosedSurface* New();
vtkTypeMacro(vtkClipClosedSurface, vtkPolyDataAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@{
/**
* Set the vtkPlaneCollection that holds the clipping planes.
*/
virtual void SetClippingPlanes(vtkPlaneCollection* planes);
vtkGetObjectMacro(ClippingPlanes, vtkPlaneCollection);
//@}
//@{
/**
* Set the tolerance for creating new points while clipping. If the
* tolerance is too small, then degenerate triangles might be produced.
* The default tolerance is 1e-6.
*/
vtkSetMacro(Tolerance, double);
vtkGetMacro(Tolerance, double);
//@}
//@{
/**
* Pass the point data to the output. Point data will be interpolated
* when new points are generated. This is off by default.
*/
vtkSetMacro(PassPointData, vtkTypeBool);
vtkBooleanMacro(PassPointData, vtkTypeBool);
vtkGetMacro(PassPointData, vtkTypeBool);
//@}
//@{
/**
* Set whether to generate an outline wherever an input face was
* cut by a plane. This is off by default.
*/
vtkSetMacro(GenerateOutline, vtkTypeBool);
vtkBooleanMacro(GenerateOutline, vtkTypeBool);
vtkGetMacro(GenerateOutline, vtkTypeBool);
//@}
//@{
/**
* Set whether to generate polygonal faces for the output. This is
* on by default. If it is off, then the output will have no polys.
*/
vtkSetMacro(GenerateFaces, vtkTypeBool);
vtkBooleanMacro(GenerateFaces, vtkTypeBool);
vtkGetMacro(GenerateFaces, vtkTypeBool);
//@}
//@{
/**
* Set whether to add cell scalars, so that new faces and outlines
* can be distinguished from original faces and lines. The options
* are "None", "Colors", and "Labels". For the "Labels" option,
* a scalar value of "0" indicates an original cell, "1" indicates
* a new cell on a cut face, and "2" indicates a new cell on the
* ActivePlane as set by the SetActivePlane() method. The default
* scalar mode is "None".
*/
vtkSetClampMacro(ScalarMode, int, VTK_CCS_SCALAR_MODE_NONE, VTK_CCS_SCALAR_MODE_LABELS);
void SetScalarModeToNone() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_NONE); }
void SetScalarModeToColors() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_COLORS); }
void SetScalarModeToLabels() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_LABELS); }
vtkGetMacro(ScalarMode, int);
const char* GetScalarModeAsString();
//@}
//@{
/**
* Set the color for all cells were part of the original geometry.
* If the input data already has color cell scalars, then those
* values will be used and parameter will be ignored. The default color
* is red. Requires SetScalarModeToColors.
*/
vtkSetVector3Macro(BaseColor, double);
vtkGetVector3Macro(BaseColor, double);
//@}
//@{
/**
* Set the color for any new geometry, either faces or outlines, that are
* created as a result of the clipping. The default color is orange.
* Requires SetScalarModeToColors.
*/
vtkSetVector3Macro(ClipColor, double);
vtkGetVector3Macro(ClipColor, double);
//@}
//@{
/**
* Set the active plane, so that the clipping from that plane can be
* displayed in a different color. Set this to -1 if there is no active
* plane. The default value is -1.
*/
vtkSetMacro(ActivePlaneId, int);
vtkGetMacro(ActivePlaneId, int);
//@}
//@{
/**
* Set the color for any new geometry produced by clipping with the
* ActivePlane, if ActivePlaneId is set. Default is yellow.
* Requires SetScalarModeToColors.
*/
vtkSetVector3Macro(ActivePlaneColor, double);
vtkGetVector3Macro(ActivePlaneColor, double);
//@}
//@{
/**
* Generate errors when the triangulation fails. Usually the
* triangulation errors are too small to see, but they result in
* a surface that is not watertight. This option has no impact
* on performance.
*/
vtkSetMacro(TriangulationErrorDisplay, vtkTypeBool);
vtkBooleanMacro(TriangulationErrorDisplay, vtkTypeBool);
vtkGetMacro(TriangulationErrorDisplay, vtkTypeBool);
//@}
protected:
vtkClipClosedSurface();
~vtkClipClosedSurface() override;
vtkPlaneCollection* ClippingPlanes;
double Tolerance;
vtkTypeBool PassPointData;
vtkTypeBool GenerateOutline;
vtkTypeBool GenerateFaces;
int ActivePlaneId;
int ScalarMode;
double BaseColor[3];
double ClipColor[3];
double ActivePlaneColor[3];
vtkTypeBool TriangulationErrorDisplay;
vtkIdList* IdList;
int ComputePipelineMTime(vtkInformation* request, vtkInformationVector** inputVector,
vtkInformationVector* outputVector, int requestFromOutputPort, vtkMTimeType* mtime) override;
int RequestData(vtkInformation* request, vtkInformationVector** inputVector,
vtkInformationVector* outputVector) override;
/**
* Method for clipping lines and copying the scalar data.
*/
void ClipLines(vtkPoints* points, vtkDoubleArray* pointScalars, vtkPointData* pointData,
vtkCCSEdgeLocator* edgeLocator, vtkCellArray* inputCells, vtkCellArray* outputLines,
vtkCellData* inCellData, vtkCellData* outLineData);
/**
* Clip and contour polys in one step, in order to guarantee
* that the contour lines exactly match the new free edges of
* the clipped polygons. This exact correspondence is necessary
* in order to guarantee that the surface remains closed.
*/
void ClipAndContourPolys(vtkPoints* points, vtkDoubleArray* pointScalars, vtkPointData* pointData,
vtkCCSEdgeLocator* edgeLocator, int triangulate, vtkCellArray* inputCells,
vtkCellArray* outputPolys, vtkCellArray* outputLines, vtkCellData* inPolyData,
vtkCellData* outPolyData, vtkCellData* outLineData);
/**
* A helper function for interpolating a new point along an edge. It
* stores the index of the interpolated point in "i", and returns 1 if
* a new point was added to the points. The values i0, i1, v0, v1 are
* the edge enpoints and scalar values, respectively.
*/
static int InterpolateEdge(vtkPoints* points, vtkPointData* pointData,
vtkCCSEdgeLocator* edgeLocator, double tol, vtkIdType i0, vtkIdType i1, double v0, double v1,
vtkIdType& i);
/**
* A robust method for triangulating a polygon. It cleans up the polygon
* and then applies the ear-cut method that is implemented in vtkPolygon.
* A zero return value indicates that triangulation failed.
*/
int TriangulatePolygon(vtkIdList* polygon, vtkPoints* points, vtkCellArray* triangles);
/**
* Given some closed contour lines, create a triangle mesh that
* fills those lines. The input lines must be single-segment lines,
* not polylines. The input lines do not have to be in order.
* Only lines from firstLine to will be used. Specify the normal
* of the clip plane, which will be opposite the normals
* of the polys that will be produced. If outCD has scalars, then color
* scalars will be added for each poly that is created.
*/
void TriangulateContours(vtkPolyData* data, vtkIdType firstLine, vtkIdType numLines,
vtkCellArray* outputPolys, const double normal[3]);
/**
* Break polylines into individual lines, copying scalar values from
* inputScalars starting at firstLineScalar. If inputScalars is zero,
* then scalars will be set to color. If scalars is zero, then no
* scalars will be generated.
*/
static void BreakPolylines(vtkCellArray* inputLines, vtkCellArray* outputLines,
vtkUnsignedCharArray* inputScalars, vtkIdType firstLineScalar,
vtkUnsignedCharArray* outputScalars, const unsigned char color[3]);
/**
* Copy polygons and their associated scalars to a new array.
* If inputScalars is set to zero, set polyScalars to color instead.
* If polyScalars is set to zero, don't generate scalars.
*/
static void CopyPolygons(vtkCellArray* inputPolys, vtkCellArray* outputPolys,
vtkUnsignedCharArray* inputScalars, vtkIdType firstPolyScalar,
vtkUnsignedCharArray* outputScalars, const unsigned char color[3]);
/**
* Break triangle strips and add the triangles to the output. See
* CopyPolygons for more information.
*/
static void BreakTriangleStrips(vtkCellArray* inputStrips, vtkCellArray* outputPolys,
vtkUnsignedCharArray* inputScalars, vtkIdType firstStripScalar,
vtkUnsignedCharArray* outputScalars, const unsigned char color[3]);
/**
* Squeeze the points and store them in the output. Only the points that
* are used by the cells will be saved, and the pointIds of the cells will
* be modified.
*/
static void SqueezeOutputPoints(
vtkPolyData* output, vtkPoints* points, vtkPointData* pointData, int outputPointDataType);
/**
* Take three colors as doubles, and convert to unsigned char.
*/
static void CreateColorValues(const double color1[3], const double color2[3],
const double color3[3], unsigned char colors[3][3]);
private:
vtkClipClosedSurface(const vtkClipClosedSurface&) = delete;
void operator=(const vtkClipClosedSurface&) = delete;
};
#endif