/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkWeightedTransformFilter.h,v $ 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. =========================================================================*/ // .NAME vtkWeightedTransformFilter - transform based on per-point or per-cell weighting functions. // .SECTION Description // vtkWeightedTransformFilter is a filter that can be used to "skin" // structures and to create new and complex shapes. Unlike a // traditional transform filter (which has one transform for a data // set) or an assembly (which has one transform per part or group of // parts), a weighted transform produces the weighted sum of // transforms on a per-point or per-cell basis. // // Each point or cell in the filter's input has an attached DataArray // that contains tuples of weighting functions, one per point or cell. // The filter also has a set of fixed transforms. When the filter // executes, each input point/cell is transformed by each of the // transforms. These results are weighted by the point/cell's // weighting factors to produce final output data. // // Linear transforms are performance-optimized. Using arbitrary // transforms will work, but performance may suffer. // // As an example of the utility of weighted transforms, here's how // this filter can be used for "skinning." Skinning is the process of // putting a mesh cover over an underlying structure, like skin over // bone. Joints are difficult to skin because deformation is hard to // do. Visualize skin over an elbow joint. Part of the skin moves // with one bone, part of the skin moves with the other bone, and the // skin in the middle moves a little with each. // // Weighted filtering can be used for a simple and efficient kind of // skinning. Begin with a cylindrical mesh. Create a FloatArray with // two components per tuple, and one tuple for each point in the mesh. // Assign transform weights that linear interpolate the distance along // the cylinder (one component is the distance along the cylinder, the // other is one minus that distance). Set the filter up to use two // transforms, the two used to transform the two bones. Now, when the // transforms change, the mesh will deform so as to, hopefully, // continue to cover the bones. // // vtkWeightedTransformFilter is also useful for creating "strange and // complex" shapes using pinching, bending, and blending. // // .SECTION Caveats // Weighted combination of normals and vectors are probably not appropriate // in many cases. Surface normals are treated somewhat specially, but // in many cases you may need to regenerate the surface normals. // // Cell data can only be transformed if all transforms are linear. // // // .SECTION See Also // vtkAbstractTransform vtkLinearTransform vtkTransformPolyDataFilter vtkActor #ifndef __vtkWeightedTransformFilter_h #define __vtkWeightedTransformFilter_h #include "vtkPointSetAlgorithm.h" class vtkAbstractTransform; class VTK_HYBRID_EXPORT vtkWeightedTransformFilter : public vtkPointSetAlgorithm { public: static vtkWeightedTransformFilter *New(); vtkTypeRevisionMacro(vtkWeightedTransformFilter,vtkPointSetAlgorithm); void PrintSelf(ostream& os, vtkIndent indent); // Description: // Return the MTime also considering the filter's transforms. unsigned long GetMTime(); // Description: // WeightArray is the string name of the DataArray in the input's // FieldData that holds the weighting coefficients for each point. // The filter will first look for the array in the input's PointData // FieldData. If the array isn't there, the filter looks in the // input's FieldData. The WeightArray can have tuples of any length, // but must have a tuple for every point in the input data set. // This array transforms points, normals, and vectors. vtkSetStringMacro(WeightArray); vtkGetStringMacro(WeightArray); // Description: // TransformIndexArray is the string name of the DataArray in the input's // FieldData that holds the indices for the transforms for each point. // These indices are used to select which transforms each weight of // the DataArray refers. If the TransformIndexArray is not specified, // the weights of each point are assumed to map directly to a transform. // This DataArray must be of type UnsignedShort, which effectively // limits the number of transforms to 65536 if a transform index // array is used. // // The filter will first look for the array in the input's PointData // FieldData. If the array isn't there, the filter looks in the // input's FieldData. The TransformIndexArray can have tuples of any // length, but must have a tuple for every point in the input data set. // This array transforms points, normals, and vectors. vtkSetStringMacro(TransformIndexArray); vtkGetStringMacro(TransformIndexArray); // Description: // The CellDataWeightArray is analogous to the WeightArray, except // for CellData. The array is searched for first in the CellData // FieldData, then in the input's FieldData. The data array must have // a tuple for each cell. This array is used to transform only normals // and vectors. vtkSetStringMacro(CellDataWeightArray); vtkGetStringMacro(CellDataWeightArray); //Description: // The CellDataTransformIndexArray is like a TransformIndexArray, // except for cell data. The array must have type UnsignedShort. vtkSetStringMacro(CellDataTransformIndexArray); vtkGetStringMacro(CellDataTransformIndexArray); // Description: // Set or Get one of the filter's transforms. The transform number must // be less than the number of transforms allocated for the object. Setting // a transform slot to NULL is equivalent to assigning an overriding weight // of zero to that filter slot. virtual void SetTransform(vtkAbstractTransform *transform, int num); virtual vtkAbstractTransform *GetTransform(int num); // Description: // Set the number of transforms for the filter. References to non-existent // filter numbers in the data array is equivalent to a weight of zero // (i.e., no contribution of that filter or weight). The maximum number of // transforms is limited to 65536 if transform index arrays are used. virtual void SetNumberOfTransforms(int num); vtkGetMacro(NumberOfTransforms, int); // Description: // If AddInputValues is true, the output values of this filter will be // offset from the input values. The effect is exactly equivalent to // having an identity transform of weight 1 added into each output point. vtkBooleanMacro(AddInputValues, int); vtkSetMacro(AddInputValues, int); vtkGetMacro(AddInputValues, int); protected: vtkAbstractTransform **Transforms; int NumberOfTransforms; int AddInputValues; char *CellDataWeightArray; char *WeightArray; char *CellDataTransformIndexArray; char *TransformIndexArray; vtkWeightedTransformFilter(); ~vtkWeightedTransformFilter(); int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); private: vtkWeightedTransformFilter(const vtkWeightedTransformFilter&); // Not implemented. void operator=(const vtkWeightedTransformFilter&); // Not implemented. }; #endif