1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkSmoothingQuadEdgeMeshFilter_h
#define itkSmoothingQuadEdgeMeshFilter_h
#include "itkDelaunayConformingQuadEdgeMeshFilter.h"
#include "itkQuadEdgeMeshParamMatrixCoefficients.h"
namespace itk
{
/** \class SmoothingQuadEdgeMeshFilter
*
* \brief QuadEdgeMesh Smoothing Filter
*
* This filter adjusts point coordinates using Laplacian smoothing. The
* effect is to "relax" the mesh, making the cells better shaped and the
* vertices more evenly distributed.
*
* For one iteration the location of one vertex is computed as follows:
* \f[
* \boldsymbol{ v' }_i = v_i + m_RelaxationFactor \cdot \frac{ \sum_j w_{ij} ( \boldsymbol{ v_j } - \boldsymbol{ v_i } )
* }{ \sum_j w_{ij} } \f]
*
* where \f$ w_{ij} \f$ is computed by the means of the set functor
* CoefficientsComputation
*
* This process is then repeated for m_NumberOfIterations (the more iterations,
* the smoother the output mesh will be).
*
* At each iteration, one can run DelaunayConformingQuadEdgeMeshFilter
* resulting a more regular (in terms of connectivity) and smoother mesh.
* Depending on the mesh size and configuration it could be an expensive
* process to run it at each iterations, especially if the number of iterations
* is large. Note that one can still run N iterations without
* DelaunayConformingQuadEdgeMeshFilter, then run this filter and apply this
* process M times.
*
*
* \ingroup ITKQuadEdgeMeshFiltering
*/
template <typename TInputMesh, typename TOutputMesh = TInputMesh>
class ITK_TEMPLATE_EXPORT SmoothingQuadEdgeMeshFilter : public QuadEdgeMeshToQuadEdgeMeshFilter<TInputMesh, TOutputMesh>
{
public:
ITK_DISALLOW_COPY_AND_MOVE(SmoothingQuadEdgeMeshFilter);
using Self = SmoothingQuadEdgeMeshFilter;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;
using Superclass = QuadEdgeMeshToQuadEdgeMeshFilter<TInputMesh, TOutputMesh>;
/** \see LightObject::GetNameOfClass() */
itkOverrideGetNameOfClassMacro(SmoothingQuadEdgeMeshFilter);
/** New macro for creation of through a Smart Pointer */
itkNewMacro(Self);
using InputMeshType = TInputMesh;
using InputMeshPointer = typename InputMeshType::Pointer;
using OutputMeshType = TOutputMesh;
using OutputMeshPointer = typename OutputMeshType::Pointer;
using OutputEdgeCellType = typename OutputMeshType::EdgeCellType;
using OutputPolygonCellType = typename OutputMeshType::PolygonCellType;
using OutputQEType = typename OutputMeshType::QEType;
using OutputPointIdentifier = typename OutputMeshType::PointIdentifier;
using OutputPointType = typename OutputMeshType::PointType;
using OutputVectorType = typename OutputPointType::VectorType;
using OutputCoordType = typename OutputPointType::CoordRepType;
using OutputPointsContainer = typename OutputMeshType::PointsContainer;
using OutputPointsContainerPointer = typename OutputMeshType::PointsContainerPointer;
using OutputPointsContainerIterator = typename OutputMeshType::PointsContainerIterator;
using OutputCellsContainerPointer = typename OutputMeshType::CellsContainerPointer;
using OutputCellsContainerIterator = typename OutputMeshType::CellsContainerIterator;
static constexpr unsigned int PointDimension = OutputMeshType::PointDimension;
using CoefficientsComputation = MatrixCoefficients<OutputMeshType>;
void
SetCoefficientsMethod(CoefficientsComputation * iMethod);
/** Set/Get the number of iterations */
itkSetMacro(NumberOfIterations, unsigned int);
itkGetConstMacro(NumberOfIterations, unsigned int);
/** Set/Get if DelaunayConformingQuadEdgeMeshFilter is used at the end of each iterations */
itkBooleanMacro(DelaunayConforming);
itkSetMacro(DelaunayConforming, bool);
itkGetConstMacro(DelaunayConforming, bool);
/** Set/Get relaxation factor applied for each iteration */
itkSetMacro(RelaxationFactor, OutputCoordType);
itkGetConstMacro(RelaxationFactor, OutputCoordType);
protected:
SmoothingQuadEdgeMeshFilter();
~SmoothingQuadEdgeMeshFilter() override;
void
PrintSelf(std::ostream & os, Indent indent) const override;
CoefficientsComputation * m_CoefficientsMethod{};
using InputOutputDelaunayConformingType = DelaunayConformingQuadEdgeMeshFilter<InputMeshType, OutputMeshType>;
using InputOutputDelaunayConformingPointer = typename InputOutputDelaunayConformingType::Pointer;
InputOutputDelaunayConformingPointer m_InputDelaunayFilter{};
using OutputDelaunayConformingType = DelaunayConformingQuadEdgeMeshFilter<OutputMeshType, OutputMeshType>;
using OutputDelaunayConformingPointer = typename OutputDelaunayConformingType::Pointer;
OutputDelaunayConformingPointer m_OutputDelaunayFilter{};
bool m_DelaunayConforming{};
unsigned int m_NumberOfIterations{};
OutputCoordType m_RelaxationFactor{};
void
GenerateData() override;
};
} // namespace itk
#include "itkSmoothingQuadEdgeMeshFilter.hxx"
#endif
|