1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkClipClosedSurface.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /** 16 * @class vtkClipClosedSurface 17 * @brief Clip a closed surface with a plane collection 18 * 19 * vtkClipClosedSurface will clip a closed polydata surface with a 20 * collection of clipping planes. It will produce a new closed surface 21 * by creating new polygonal faces where the input data was clipped. 22 * 23 * Non-manifold surfaces should not be used as input for this filter. 24 * The input surface should have no open edges, and must not have any 25 * edges that are shared by more than two faces. The vtkFeatureEdges 26 * filter can be used to verify that a data set satisfies these conditions. 27 * In addition, the input surface should not self-intersect, meaning 28 * that the faces of the surface should only touch at their edges. 29 * 30 * If GenerateOutline is on, this filter will generate an outline wherever 31 * the clipping planes intersect the data. The ScalarMode option 32 * will add cell scalars to the output, so that the generated faces 33 * can be visualized in a different color from the original surface. 34 * 35 * @warning 36 * The triangulation of new faces is done in O(n) time for simple convex 37 * inputs, but for non-convex inputs the worst-case time is O(n^2*m^2) 38 * where n is the number of points and m is the number of 3D cavities. 39 * The best triangulation algorithms, in contrast, are O(n log n). 40 * There are also rare cases where the triangulation will fail to produce 41 * a watertight output. Turn on TriangulationErrorDisplay to be notified 42 * of these failures. 43 * @sa 44 * vtkOutlineFilter vtkOutlineSource vtkVolumeOutlineSource 45 * @par Thanks: 46 * Thanks to David Gobbi for contributing this class to VTK. 47 */ 48 49 #ifndef vtkClipClosedSurface_h 50 #define vtkClipClosedSurface_h 51 52 #include "vtkFiltersGeneralModule.h" // For export macro 53 #include "vtkPolyDataAlgorithm.h" 54 55 class vtkPlaneCollection; 56 class vtkUnsignedCharArray; 57 class vtkDoubleArray; 58 class vtkIdTypeArray; 59 class vtkCellArray; 60 class vtkPointData; 61 class vtkCellData; 62 class vtkPolygon; 63 class vtkIdList; 64 class vtkCCSEdgeLocator; 65 66 enum 67 { 68 VTK_CCS_SCALAR_MODE_NONE = 0, 69 VTK_CCS_SCALAR_MODE_COLORS = 1, 70 VTK_CCS_SCALAR_MODE_LABELS = 2 71 }; 72 73 class VTKFILTERSGENERAL_EXPORT vtkClipClosedSurface : public vtkPolyDataAlgorithm 74 { 75 public: 76 static vtkClipClosedSurface* New(); 77 vtkTypeMacro(vtkClipClosedSurface, vtkPolyDataAlgorithm); 78 void PrintSelf(ostream& os, vtkIndent indent) override; 79 80 ///@{ 81 /** 82 * Set the vtkPlaneCollection that holds the clipping planes. 83 */ 84 virtual void SetClippingPlanes(vtkPlaneCollection* planes); 85 vtkGetObjectMacro(ClippingPlanes, vtkPlaneCollection); 86 ///@} 87 88 ///@{ 89 /** 90 * Set the tolerance for creating new points while clipping. If the 91 * tolerance is too small, then degenerate triangles might be produced. 92 * The default tolerance is 1e-6. 93 */ 94 vtkSetMacro(Tolerance, double); 95 vtkGetMacro(Tolerance, double); 96 ///@} 97 98 ///@{ 99 /** 100 * Pass the point data to the output. Point data will be interpolated 101 * when new points are generated. This is off by default. 102 */ 103 vtkSetMacro(PassPointData, vtkTypeBool); 104 vtkBooleanMacro(PassPointData, vtkTypeBool); 105 vtkGetMacro(PassPointData, vtkTypeBool); 106 ///@} 107 108 ///@{ 109 /** 110 * Set whether to generate an outline wherever an input face was 111 * cut by a plane. This is off by default. 112 */ 113 vtkSetMacro(GenerateOutline, vtkTypeBool); 114 vtkBooleanMacro(GenerateOutline, vtkTypeBool); 115 vtkGetMacro(GenerateOutline, vtkTypeBool); 116 ///@} 117 118 ///@{ 119 /** 120 * Set whether to generate polygonal faces for the output. This is 121 * on by default. If it is off, then the output will have no polys. 122 */ 123 vtkSetMacro(GenerateFaces, vtkTypeBool); 124 vtkBooleanMacro(GenerateFaces, vtkTypeBool); 125 vtkGetMacro(GenerateFaces, vtkTypeBool); 126 ///@} 127 128 ///@{ 129 /** 130 * Set whether to add cell scalars, so that new faces and outlines 131 * can be distinguished from original faces and lines. The options 132 * are "None", "Colors", and "Labels". For the "Labels" option, 133 * a scalar value of "0" indicates an original cell, "1" indicates 134 * a new cell on a cut face, and "2" indicates a new cell on the 135 * ActivePlane as set by the SetActivePlane() method. The default 136 * scalar mode is "None". 137 */ 138 vtkSetClampMacro(ScalarMode, int, VTK_CCS_SCALAR_MODE_NONE, VTK_CCS_SCALAR_MODE_LABELS); SetScalarModeToNone()139 void SetScalarModeToNone() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_NONE); } SetScalarModeToColors()140 void SetScalarModeToColors() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_COLORS); } SetScalarModeToLabels()141 void SetScalarModeToLabels() { this->SetScalarMode(VTK_CCS_SCALAR_MODE_LABELS); } 142 vtkGetMacro(ScalarMode, int); 143 const char* GetScalarModeAsString(); 144 ///@} 145 146 ///@{ 147 /** 148 * Set the color for all cells were part of the original geometry. 149 * If the input data already has color cell scalars, then those 150 * values will be used and parameter will be ignored. The default color 151 * is red. Requires SetScalarModeToColors. 152 */ 153 vtkSetVector3Macro(BaseColor, double); 154 vtkGetVector3Macro(BaseColor, double); 155 ///@} 156 157 ///@{ 158 /** 159 * Set the color for any new geometry, either faces or outlines, that are 160 * created as a result of the clipping. The default color is orange. 161 * Requires SetScalarModeToColors. 162 */ 163 vtkSetVector3Macro(ClipColor, double); 164 vtkGetVector3Macro(ClipColor, double); 165 ///@} 166 167 ///@{ 168 /** 169 * Set the active plane, so that the clipping from that plane can be 170 * displayed in a different color. Set this to -1 if there is no active 171 * plane. The default value is -1. 172 */ 173 vtkSetMacro(ActivePlaneId, int); 174 vtkGetMacro(ActivePlaneId, int); 175 ///@} 176 177 ///@{ 178 /** 179 * Set the color for any new geometry produced by clipping with the 180 * ActivePlane, if ActivePlaneId is set. Default is yellow. 181 * Requires SetScalarModeToColors. 182 */ 183 vtkSetVector3Macro(ActivePlaneColor, double); 184 vtkGetVector3Macro(ActivePlaneColor, double); 185 ///@} 186 187 ///@{ 188 /** 189 * Generate errors when the triangulation fails. Usually the 190 * triangulation errors are too small to see, but they result in 191 * a surface that is not watertight. This option has no impact 192 * on performance. 193 */ 194 vtkSetMacro(TriangulationErrorDisplay, vtkTypeBool); 195 vtkBooleanMacro(TriangulationErrorDisplay, vtkTypeBool); 196 vtkGetMacro(TriangulationErrorDisplay, vtkTypeBool); 197 ///@} 198 199 protected: 200 vtkClipClosedSurface(); 201 ~vtkClipClosedSurface() override; 202 203 vtkPlaneCollection* ClippingPlanes; 204 205 double Tolerance; 206 207 vtkTypeBool PassPointData; 208 vtkTypeBool GenerateOutline; 209 vtkTypeBool GenerateFaces; 210 int ActivePlaneId; 211 int ScalarMode; 212 double BaseColor[3]; 213 double ClipColor[3]; 214 double ActivePlaneColor[3]; 215 216 vtkTypeBool TriangulationErrorDisplay; 217 218 vtkIdList* IdList; 219 220 int ComputePipelineMTime(vtkInformation* request, vtkInformationVector** inputVector, 221 vtkInformationVector* outputVector, int requestFromOutputPort, vtkMTimeType* mtime) override; 222 223 int RequestData(vtkInformation* request, vtkInformationVector** inputVector, 224 vtkInformationVector* outputVector) override; 225 226 /** 227 * Method for clipping lines and copying the scalar data. 228 */ 229 void ClipLines(vtkPoints* points, vtkDoubleArray* pointScalars, vtkPointData* pointData, 230 vtkCCSEdgeLocator* edgeLocator, vtkCellArray* inputCells, vtkCellArray* outputLines, 231 vtkCellData* inCellData, vtkCellData* outLineData); 232 233 /** 234 * Clip and contour polys in one step, in order to guarantee 235 * that the contour lines exactly match the new free edges of 236 * the clipped polygons. This exact correspondence is necessary 237 * in order to guarantee that the surface remains closed. 238 */ 239 void ClipAndContourPolys(vtkPoints* points, vtkDoubleArray* pointScalars, vtkPointData* pointData, 240 vtkCCSEdgeLocator* edgeLocator, int triangulate, vtkCellArray* inputCells, 241 vtkCellArray* outputPolys, vtkCellArray* outputLines, vtkCellData* inCellData, 242 vtkCellData* outPolyData, vtkCellData* outLineData); 243 244 /** 245 * A helper function for interpolating a new point along an edge. It 246 * stores the index of the interpolated point in "i", and returns 1 if 247 * a new point was added to the points. The values i0, i1, v0, v1 are 248 * the edge enpoints and scalar values, respectively. 249 */ 250 static int InterpolateEdge(vtkPoints* points, vtkPointData* pointData, 251 vtkCCSEdgeLocator* edgeLocator, double tol, vtkIdType i0, vtkIdType i1, double v0, double v1, 252 vtkIdType& i); 253 254 /** 255 * A robust method for triangulating a polygon. It cleans up the polygon 256 * and then applies the ear-cut method that is implemented in vtkPolygon. 257 * A zero return value indicates that triangulation failed. 258 */ 259 int TriangulatePolygon(vtkIdList* polygon, vtkPoints* points, vtkCellArray* triangles); 260 261 /** 262 * Given some closed contour lines, create a triangle mesh that 263 * fills those lines. The input lines must be single-segment lines, 264 * not polylines. The input lines do not have to be in order. 265 * Only lines from firstLine to will be used. Specify the normal 266 * of the clip plane, which will be opposite the normals 267 * of the polys that will be produced. If outCD has scalars, then color 268 * scalars will be added for each poly that is created. 269 */ 270 void TriangulateContours(vtkPolyData* data, vtkIdType firstLine, vtkIdType numLines, 271 vtkCellArray* outputPolys, const double normal[3]); 272 273 /** 274 * Break polylines into individual lines, copying scalar values from 275 * inputScalars starting at firstLineScalar. If inputScalars is zero, 276 * then scalars will be set to color. If scalars is zero, then no 277 * scalars will be generated. 278 */ 279 static void BreakPolylines(vtkCellArray* inputLines, vtkCellArray* outputLines, 280 vtkUnsignedCharArray* inputScalars, vtkIdType firstLineScalar, 281 vtkUnsignedCharArray* outputScalars, const unsigned char color[3]); 282 283 /** 284 * Copy polygons and their associated scalars to a new array. 285 * If inputScalars is set to zero, set polyScalars to color instead. 286 * If polyScalars is set to zero, don't generate scalars. 287 */ 288 static void CopyPolygons(vtkCellArray* inputPolys, vtkCellArray* outputPolys, 289 vtkUnsignedCharArray* inputScalars, vtkIdType firstPolyScalar, 290 vtkUnsignedCharArray* outputScalars, const unsigned char color[3]); 291 292 /** 293 * Break triangle strips and add the triangles to the output. See 294 * CopyPolygons for more information. 295 */ 296 static void BreakTriangleStrips(vtkCellArray* inputStrips, vtkCellArray* outputPolys, 297 vtkUnsignedCharArray* inputScalars, vtkIdType firstStripScalar, 298 vtkUnsignedCharArray* outputScalars, const unsigned char color[3]); 299 300 /** 301 * Squeeze the points and store them in the output. Only the points that 302 * are used by the cells will be saved, and the pointIds of the cells will 303 * be modified. 304 */ 305 static void SqueezeOutputPoints( 306 vtkPolyData* output, vtkPoints* points, vtkPointData* pointData, int outputPointDataType); 307 308 /** 309 * Take three colors as doubles, and convert to unsigned char. 310 */ 311 static void CreateColorValues(const double color1[3], const double color2[3], 312 const double color3[3], unsigned char colors[3][3]); 313 314 private: 315 vtkClipClosedSurface(const vtkClipClosedSurface&) = delete; 316 void operator=(const vtkClipClosedSurface&) = delete; 317 }; 318 319 #endif 320