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