1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDistancePolyDataFilter.cxx
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 #include "vtkDistancePolyDataFilter.h"
16
17 #include "vtkCellData.h"
18 #include "vtkDoubleArray.h"
19 #include "vtkImplicitPolyDataDistance.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24 #include "vtkStreamingDemandDrivenPipeline.h"
25 #include "vtkTriangle.h"
26
27 vtkStandardNewMacro(vtkDistancePolyDataFilter);
28
29 //-----------------------------------------------------------------------------
vtkDistancePolyDataFilter()30 vtkDistancePolyDataFilter::vtkDistancePolyDataFilter() : vtkPolyDataAlgorithm()
31 {
32 this->SignedDistance = 1;
33 this->NegateDistance = 0;
34 this->ComputeSecondDistance = 1;
35
36 this->SetNumberOfInputPorts(2);
37 this->SetNumberOfOutputPorts(2);
38 }
39
40 //-----------------------------------------------------------------------------
~vtkDistancePolyDataFilter()41 vtkDistancePolyDataFilter::~vtkDistancePolyDataFilter()
42 {
43 }
44
45
46 //-----------------------------------------------------------------------------
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)47 int vtkDistancePolyDataFilter::RequestData(vtkInformation* vtkNotUsed(request),
48 vtkInformationVector** inputVector,
49 vtkInformationVector* outputVector)
50 {
51 vtkPolyData *input0 = vtkPolyData::GetData(inputVector[0], 0);
52 vtkPolyData *input1 = vtkPolyData::GetData(inputVector[1], 0);
53 vtkPolyData* output0 = vtkPolyData::GetData(outputVector, 0);
54 vtkPolyData* output1 = vtkPolyData::GetData(outputVector, 1);
55
56 output0->CopyStructure(input0);
57 output0->GetPointData()->PassData(input0->GetPointData());
58 output0->GetCellData()->PassData(input0->GetCellData());
59 output0->BuildCells();
60 this->GetPolyDataDistance(output0, input1);
61
62 if (this->ComputeSecondDistance)
63 {
64 output1->CopyStructure(input1);
65 output1->GetPointData()->PassData(input1->GetPointData());
66 output1->GetCellData()->PassData(input1->GetCellData());
67 output1->BuildCells();
68 this->GetPolyDataDistance(output1, input0);
69 }
70 return 1;
71 }
72
73 //-----------------------------------------------------------------------------
GetPolyDataDistance(vtkPolyData * mesh,vtkPolyData * src)74 void vtkDistancePolyDataFilter::GetPolyDataDistance(vtkPolyData* mesh, vtkPolyData* src)
75 {
76 vtkDebugMacro(<<"Start vtkDistancePolyDataFilter::GetPolyDataDistance");
77
78 if (mesh->GetNumberOfPolys() == 0 || mesh->GetNumberOfPoints() == 0)
79 {
80 vtkErrorMacro(<<"No points/cells to operate on");
81 return;
82 }
83
84 if (src->GetNumberOfPolys() == 0 || src->GetNumberOfPoints() == 0)
85 {
86 vtkErrorMacro(<<"No points/cells to difference from");
87 return;
88 }
89
90 vtkImplicitPolyDataDistance* imp = vtkImplicitPolyDataDistance::New();
91 imp->SetInput( src );
92
93 // Calculate distance from points.
94 int numPts = mesh->GetNumberOfPoints();
95
96 vtkDoubleArray* pointArray = vtkDoubleArray::New();
97 pointArray->SetName( "Distance" );
98 pointArray->SetNumberOfComponents( 1 );
99 pointArray->SetNumberOfTuples( numPts );
100
101 for (vtkIdType ptId = 0; ptId < numPts; ptId++)
102 {
103 double pt[3];
104 mesh->GetPoint( ptId, pt );
105 double val = imp->EvaluateFunction( pt );
106 double dist = SignedDistance ? (NegateDistance ? -val : val) : fabs(val);
107 pointArray->SetValue( ptId, dist );
108 }
109
110 mesh->GetPointData()->AddArray( pointArray );
111 pointArray->Delete();
112 mesh->GetPointData()->SetActiveScalars( "Distance" );
113
114 // Calculate distance from cell centers.
115 int numCells = mesh->GetNumberOfCells();
116
117 vtkDoubleArray* cellArray = vtkDoubleArray::New();
118 cellArray->SetName( "Distance" );
119 cellArray->SetNumberOfComponents( 1 );
120 cellArray->SetNumberOfTuples( numCells );
121
122 for (vtkIdType cellId = 0; cellId < numCells; cellId++)
123 {
124 vtkCell *cell = mesh->GetCell( cellId );
125 int subId;
126 double pcoords[3], x[3], weights[256];
127
128 cell->GetParametricCenter( pcoords );
129 cell->EvaluateLocation( subId, pcoords, x, weights );
130
131 double val = imp->EvaluateFunction( x );
132 double dist = SignedDistance ? (NegateDistance ? -val : val) : fabs(val);
133 cellArray->SetValue( cellId, dist );
134 }
135
136 mesh->GetCellData()->AddArray( cellArray );
137 cellArray->Delete();
138 mesh->GetCellData()->SetActiveScalars("Distance");
139
140 imp->Delete();
141
142 vtkDebugMacro(<<"End vtkDistancePolyDataFilter::GetPolyDataDistance");
143 }
144
145 //-----------------------------------------------------------------------------
GetSecondDistanceOutput()146 vtkPolyData* vtkDistancePolyDataFilter::GetSecondDistanceOutput()
147 {
148 if (!this->ComputeSecondDistance)
149 {
150 return 0;
151 }
152 return vtkPolyData::SafeDownCast(this->GetOutputDataObject(1));
153 }
154
155 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)156 void vtkDistancePolyDataFilter::PrintSelf(ostream& os, vtkIndent indent)
157 {
158 this->Superclass::PrintSelf(os,indent);
159 os << indent << "SignedDistance: " << this->SignedDistance << "\n";
160 os << indent << "NegateDistance: " << this->NegateDistance << "\n";
161 os << indent << "ComputeSecondDistance: " << this->ComputeSecondDistance << "\n";
162 }
163