1 /*=========================================================================
3 Program: Visualization Toolkit
4 Module: $RCSfile: vtksmoothpolydatafilter2.cpp,v $
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
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.
14 =========================================================================*/
15 #include "vtksmoothpolydatafilter2.h"
17 #include "vtkCellArray.h"
18 #include "vtkCellData.h"
19 #include "vtkCellLocator.h"
20 #include "vtkFloatArray.h"
22 #include "vtkInformation.h"
23 #include "vtkInformationVector.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkPointData.h"
26 #include "vtkPolyData.h"
27 #include "vtkPolygon.h"
28 #include "vtkStreamingDemandDrivenPipeline.h"
29 #include "vtkTriangleFilter.h"
31 #include <QTextStream>
32 #include "egvtkobject.h"
34 vtkCxxRevisionMacro(vtkSmoothPolyDataFilter2
, "$Revision: 1.1.2.2 $");
35 vtkStandardNewMacro(vtkSmoothPolyDataFilter2
);
37 // The following code defines a helper class for performing mesh smoothing
38 // across the surface of another mesh.
39 typedef struct _vtkSmoothPoint
{
40 vtkIdType cellId
; // cell
41 int subId
; // cell sub id
42 double p
[3]; // parametric coords in cell
45 class vtkSmoothPoints
{ //;prevent man page generation
52 delete [] this->Array
;
55 vtkIdType
GetNumberOfPoints() {return this->MaxId
+ 1;};
56 vtkSmoothPoint
*GetSmoothPoint(vtkIdType i
) {return this->Array
+ i
;};
57 vtkSmoothPoint
*InsertSmoothPoint(vtkIdType ptId
)
59 if ( ptId
>= this->Size
)
63 if ( ptId
> this->MaxId
)
67 return this->Array
+ ptId
;
69 vtkSmoothPoint
*Resize(vtkIdType sz
); //reallocates data
70 void Reset() {this->MaxId
= -1;};
72 vtkSmoothPoint
*Array
; // pointer to data
73 vtkIdType MaxId
; // maximum index inserted thus far
74 vtkIdType Size
; // allocated size of data
75 vtkIdType Extend
; // grow array by this amount
78 vtkSmoothPoints::vtkSmoothPoints()
81 this->Array
= new vtkSmoothPoint
[1000];
86 vtkSmoothPoint
*vtkSmoothPoints::Resize(vtkIdType sz
)
88 vtkSmoothPoint
*newArray
;
93 newSize
= this->Size
+
94 this->Extend
*(((sz
-this->Size
)/this->Extend
)+1);
101 newArray
= new vtkSmoothPoint
[newSize
];
103 memcpy(newArray
, this->Array
,
104 (sz
< this->Size
? sz
: this->Size
) * sizeof(vtkSmoothPoint
));
106 this->Size
= newSize
;
107 delete [] this->Array
;
108 this->Array
= newArray
;
113 // The following code defines methods for the vtkSmoothPolyDataFilter2 class
116 // Construct object with number of iterations 20; relaxation factor .01;
117 // feature edge smoothing turned off; feature
118 // angle 45 degrees; edge angle 15 degrees; and boundary smoothing turned
119 // on. Error scalars and vectors are not generated (by default). The
120 // convergence criterion is 0.0 of the bounding box diagonal.
121 vtkSmoothPolyDataFilter2::vtkSmoothPolyDataFilter2()
123 this->Convergence
= 0.0; //goes to number of specied iterations
124 this->NumberOfIterations
= 20;
126 this->RelaxationFactor
= .01;
128 this->FeatureAngle
= 45.0;
129 this->EdgeAngle
= 15.0;
130 this->FeatureEdgeSmoothing
= 0;
131 this->BoundarySmoothing
= 1;
133 this->GenerateErrorScalars
= 0;
134 this->GenerateErrorVectors
= 0;
136 // optional second input
137 this->SetNumberOfInputPorts(2);
140 void vtkSmoothPolyDataFilter2::SetSource(vtkPolyData
*source
)
142 this->SetInput(1, source
);
145 vtkPolyData
*vtkSmoothPolyDataFilter2::GetSource()
147 if (this->GetNumberOfInputConnections(1) < 1)
151 return vtkPolyData::SafeDownCast(
152 this->GetExecutive()->GetInputData(1, 0));
155 // #define VTK_SIMPLE_VERTEX 0
156 // #define VTK_FIXED_VERTEX 1
157 // #define VTK_FEATURE_EDGE_VERTEX 2
158 // #define VTK_BOUNDARY_EDGE_VERTEX 3
160 // Special structure for marking vertices
161 typedef struct _vtkMeshVertex
164 vtkIdList
*edges
; // connected edges (list of connected point ids)
165 } vtkMeshVertex
, *vtkMeshVertexPtr
;
167 int vtkSmoothPolyDataFilter2::RequestData(
168 vtkInformation
*vtkNotUsed(request
),
169 vtkInformationVector
**inputVector
,
170 vtkInformationVector
*outputVector
)
172 cout
<<"=================="<<endl
;
174 // get the info objects
175 vtkInformation
*inInfo
= inputVector
[0]->GetInformationObject(0);
176 vtkInformation
*sourceInfo
= inputVector
[1]->GetInformationObject(0);
177 vtkInformation
*outInfo
= outputVector
->GetInformationObject(0);
179 // get the input and ouptut
180 vtkPolyData
*input
= vtkPolyData::SafeDownCast(
181 inInfo
->Get(vtkDataObject::DATA_OBJECT()));
182 vtkPolyData
*source
= 0;
185 source
= vtkPolyData::SafeDownCast(
186 sourceInfo
->Get(vtkDataObject::DATA_OBJECT()));
188 vtkPolyData
*output
= vtkPolyData::SafeDownCast(
189 outInfo
->Get(vtkDataObject::DATA_OBJECT()));
191 vtkIdType numPts
, numCells
, i
, numPolys
, numStrips
;
196 double x
[3], y
[3], deltaX
[3], xNew
[3], conv
, maxDist
, dist
, factor
;
197 double x1
[3], x2
[3], x3
[3], l1
[3], l2
[3];
198 double CosFeatureAngle
; //Cosine of angle between adjacent polys
199 double CosEdgeAngle
; // Cosine of angle between adjacent edges
200 double closestPt
[3], dist2
, *w
= NULL
;
201 int iterationNumber
, abortExecute
;
202 vtkIdType numSimple
=0, numBEdges
=0, numFixed
=0, numFEdges
=0;
203 vtkPolyData
*inMesh
, *Mesh
;
205 vtkTriangleFilter
*toTris
=NULL
;
206 vtkCellArray
*inVerts
, *inLines
, *inPolys
, *inStrips
;
208 vtkMeshVertexPtr Verts
;
209 vtkCellLocator
*cellLocator
=NULL
;
213 numPts
=input
->GetNumberOfPoints();
214 numCells
=input
->GetNumberOfCells();
215 if (numPts
< 1 || numCells
< 1)
217 vtkErrorMacro(<<"No data to smooth!");
222 cos((double) vtkMath::DegreesToRadians() * this->FeatureAngle
);
223 CosEdgeAngle
= cos((double) vtkMath::DegreesToRadians() * this->EdgeAngle
);
225 vtkDebugMacro(<<"Smoothing " << numPts
<< " vertices, " << numCells
227 << "\tConvergence= " << this->Convergence
<< "\n"
228 << "\tIterations= " << this->NumberOfIterations
<< "\n"
229 << "\tRelaxation Factor= " << this->RelaxationFactor
<< "\n"
230 << "\tEdge Angle= " << this->EdgeAngle
<< "\n"
231 << "\tBoundary Smoothing " << (this->BoundarySmoothing
? "On\n" : "Off\n")
232 << "\tFeature Edge Smoothing " << (this->FeatureEdgeSmoothing
? "On\n" : "Off\n")
233 << "\tError Scalars " << (this->GenerateErrorScalars
? "On\n" : "Off\n")
234 << "\tError Vectors " << (this->GenerateErrorVectors
? "On\n" : "Off\n"));
236 if ( this->NumberOfIterations
<= 0 || this->RelaxationFactor
== 0.0)
237 { //don't do anything! pass data through
238 output
->CopyStructure(input
);
239 output
->GetPointData()->PassData(input
->GetPointData());
240 output
->GetCellData()->PassData(input
->GetCellData());
244 // Peform topological analysis. What we're gonna do is build a connectivity
245 // array of connected vertices. The outcome will be one of three
246 // classifications for a vertex: VTK_SIMPLE_VERTEX, VTK_FIXED_VERTEX. or
247 // VTK_EDGE_VERTEX. Simple vertices are smoothed using all connected
248 // vertices. FIXED vertices are never smoothed. Edge vertices are smoothed
249 // using a subset of the attached vertices.
251 cout
<<"Analyzing topology..."<<endl
;
252 cout
<<"0:numPts="<<numPts
<<endl
;
253 Verts
= new vtkMeshVertex
[numPts
];
254 for (i
=0; i
<numPts
; i
++)
256 cout
<<"0:VTK_SIMPLE_VERTEX"<<endl
;
257 Verts
[i
].type
= VTK_SIMPLE_VERTEX
; //can smooth
258 Verts
[i
].edges
= NULL
;
261 inPts
= input
->GetPoints();
262 conv
= this->Convergence
* input
->GetLength();
264 // check vertices first. Vertices are never smoothed_--------------
265 for (inVerts
=input
->GetVerts(), inVerts
->InitTraversal();
266 inVerts
->GetNextCell(npts
,pts
); )
268 for (j
=0; j
<npts
; j
++)
270 cout
<<"pts[j]="<<pts
[j
]<<"->vertices:VTK_FIXED_VERTEX"<<endl
;
271 Verts
[pts
[j
]].type
= VTK_FIXED_VERTEX
;
274 this->UpdateProgress(0.10);
276 // now check lines. Only manifold lines can be smoothed------------
277 for (inLines
=input
->GetLines(), inLines
->InitTraversal();
278 inLines
->GetNextCell(npts
,pts
); )
280 for (j
=0; j
<npts
; j
++)
282 cout
<<"pts[j]="<<pts
[j
]<<"->lines"<<endl
;
283 if ( Verts
[pts
[j
]].type
== VTK_SIMPLE_VERTEX
)
285 if ( j
== (npts
-1) ) //end-of-line marked FIXED
287 cout
<<"pts[j]="<<pts
[j
]<<"2:VTK_FIXED_VERTEX"<<endl
;
288 Verts
[pts
[j
]].type
= VTK_FIXED_VERTEX
;
290 else if ( j
== 0 ) //beginning-of-line marked FIXED
292 cout
<<"pts[j]="<<pts
[j
]<<"3:VTK_FIXED_VERTEX"<<endl
;
293 Verts
[pts
[0]].type
= VTK_FIXED_VERTEX
;
294 inPts
->GetPoint(pts
[0],x2
);
295 inPts
->GetPoint(pts
[1],x3
);
297 else //is edge vertex (unless already edge vertex!)
299 cout
<<"pts[j]="<<pts
[j
]<<"4:VTK_FEATURE_EDGE_VERTEX"<<endl
;
300 Verts
[pts
[j
]].type
= VTK_FEATURE_EDGE_VERTEX
;
301 Verts
[pts
[j
]].edges
= vtkIdList::New();
302 Verts
[pts
[j
]].edges
->SetNumberOfIds(2);
303 Verts
[pts
[j
]].edges
->SetId(0,pts
[j
-1]);
304 Verts
[pts
[j
]].edges
->SetId(1,pts
[j
+1]);
308 else if ( Verts
[pts
[j
]].type
== VTK_FEATURE_EDGE_VERTEX
)
309 { //multiply connected, becomes fixed!
310 cout
<<"pts[j]="<<pts
[j
]<<"5:VTK_FIXED_VERTEX"<<endl
;
311 Verts
[pts
[j
]].type
= VTK_FIXED_VERTEX
;
312 Verts
[pts
[j
]].edges
->Delete();
313 Verts
[pts
[j
]].edges
= NULL
;
316 } //for all points in this line
318 this->UpdateProgress(0.25);
320 // now polygons and triangle strips-------------------------------
321 inPolys
=input
->GetPolys();
322 numPolys
= inPolys
->GetNumberOfCells();
323 inStrips
=input
->GetStrips();
324 numStrips
= inStrips
->GetNumberOfCells();
326 cout
<<"numPolys="<<numPolys
<<endl
;
327 cout
<<"numStrips="<<numStrips
<<endl
;
330 if ( numPolys
> 0 || numStrips
> 0 )
331 { //build cell structure
334 int numNei
, nei
, edge
;
337 double normal
[3], neiNormal
[3];
338 vtkIdList
*neighbors
;
340 neighbors
= vtkIdList::New();
341 neighbors
->Allocate(VTK_CELL_SIZE
);
343 inMesh
= vtkPolyData::New();
344 inMesh
->SetPoints(inPts
);
345 inMesh
->SetPolys(inPolys
);
348 if ( (numStrips
= inStrips
->GetNumberOfCells()) > 0 )
349 { // convert data to triangles
350 inMesh
->SetStrips(inStrips
);
351 toTris
= vtkTriangleFilter::New();
352 toTris
->SetInput(inMesh
);
354 Mesh
= toTris
->GetOutput();
357 Mesh
->BuildLinks(); //to do neighborhood searching
358 polys
= Mesh
->GetPolys();
359 this->UpdateProgress(0.375);
361 for (cellId
=0, polys
->InitTraversal(); polys
->GetNextCell(npts
,pts
);
364 cout
<<"->cellId="<<cellId
<<endl
;
365 for (i
=0; i
< npts
; i
++)
367 cout
<<"-->i="<<i
<<endl
;
369 p2
= pts
[(i
+1)%npts
];
371 if ( Verts
[p1
].edges
== NULL
)
373 Verts
[p1
].edges
= vtkIdList::New();
374 Verts
[p1
].edges
->Allocate(16,6);
376 if ( Verts
[p2
].edges
== NULL
)
378 Verts
[p2
].edges
= vtkIdList::New();
379 Verts
[p2
].edges
->Allocate(16,6);
382 Mesh
->GetCellEdgeNeighbors(cellId
,p1
,p2
,neighbors
);
383 numNei
= neighbors
->GetNumberOfIds();
384 cout
<<"-->numNei="<<numNei
<<endl
;
386 edge
= VTK_SIMPLE_VERTEX
;
389 edge
= VTK_BOUNDARY_EDGE_VERTEX
;
392 else if ( numNei
>= 2 )
394 // check to make sure that this edge hasn't been marked already
395 for (j
=0; j
< numNei
; j
++)
397 if ( neighbors
->GetId(j
) < cellId
)
404 edge
= VTK_FEATURE_EDGE_VERTEX
;
408 else if ( numNei
== 1 && (nei
=neighbors
->GetId(0)) > cellId
)
410 vtkPolygon::ComputeNormal(inPts
,npts
,pts
,normal
);
411 Mesh
->GetCellPoints(nei
,numNeiPts
,neiPts
);
412 vtkPolygon::ComputeNormal(inPts
,numNeiPts
,neiPts
,neiNormal
);
414 if ( this->FeatureEdgeSmoothing
&&
415 vtkMath::Dot(normal
,neiNormal
) <= CosFeatureAngle
)
417 edge
= VTK_FEATURE_EDGE_VERTEX
;
420 else // a visited edge; skip rest of analysis
425 if ( edge
&& Verts
[p1
].type
== VTK_SIMPLE_VERTEX
)
427 Verts
[p1
].edges
->Reset();
428 Verts
[p1
].edges
->InsertNextId(p2
);
429 Verts
[p1
].type
= edge
;
431 else if ( (edge
&& Verts
[p1
].type
== VTK_BOUNDARY_EDGE_VERTEX
) ||
432 (edge
&& Verts
[p1
].type
== VTK_FEATURE_EDGE_VERTEX
) ||
433 (!edge
&& Verts
[p1
].type
== VTK_SIMPLE_VERTEX
) )
435 Verts
[p1
].edges
->InsertNextId(p2
);
436 if ( Verts
[p1
].type
&& edge
== VTK_BOUNDARY_EDGE_VERTEX
)
438 Verts
[p1
].type
= VTK_BOUNDARY_EDGE_VERTEX
;
442 if ( edge
&& Verts
[p2
].type
== VTK_SIMPLE_VERTEX
)
444 Verts
[p2
].edges
->Reset();
445 Verts
[p2
].edges
->InsertNextId(p1
);
446 Verts
[p2
].type
= edge
;
448 else if ( (edge
&& Verts
[p2
].type
== VTK_BOUNDARY_EDGE_VERTEX
) ||
449 (edge
&& Verts
[p2
].type
== VTK_FEATURE_EDGE_VERTEX
) ||
450 (!edge
&& Verts
[p2
].type
== VTK_SIMPLE_VERTEX
) )
452 Verts
[p2
].edges
->InsertNextId(p1
);
453 if ( Verts
[p2
].type
&& edge
== VTK_BOUNDARY_EDGE_VERTEX
)
455 Verts
[p2
].type
= VTK_BOUNDARY_EDGE_VERTEX
;
462 if (toTris
) {toTris
->Delete();}
465 }//if strips or polys
467 this->UpdateProgress(0.50);
469 //post-process edge vertices to make sure we can smooth them
470 for (i
=0; i
<numPts
; i
++)
472 if ( Verts
[i
].type
== VTK_SIMPLE_VERTEX
)
477 else if ( Verts
[i
].type
== VTK_FIXED_VERTEX
)
482 else if ( Verts
[i
].type
== VTK_FEATURE_EDGE_VERTEX
||
483 Verts
[i
].type
== VTK_BOUNDARY_EDGE_VERTEX
)
484 { //see how many edges; if two, what the angle is
486 if ( !this->BoundarySmoothing
&&
487 Verts
[i
].type
== VTK_BOUNDARY_EDGE_VERTEX
)
489 Verts
[i
].type
= VTK_FIXED_VERTEX
;
493 else if ( (npts
= Verts
[i
].edges
->GetNumberOfIds()) != 2 )
495 Verts
[i
].type
= VTK_FIXED_VERTEX
;
499 else //check angle between edges
501 inPts
->GetPoint(Verts
[i
].edges
->GetId(0),x1
);
502 inPts
->GetPoint(i
,x2
);
503 inPts
->GetPoint(Verts
[i
].edges
->GetId(1),x3
);
507 l1
[k
] = x2
[k
] - x1
[k
];
508 l2
[k
] = x3
[k
] - x2
[k
];
510 if ( vtkMath::Normalize(l1
) >= 0.0 &&
511 vtkMath::Normalize(l2
) >= 0.0 &&
512 vtkMath::Dot(l1
,l2
) < CosEdgeAngle
)
515 Verts
[i
].type
= VTK_FIXED_VERTEX
;
519 if ( Verts
[i
].type
== VTK_FEATURE_EDGE_VERTEX
)
532 cout
<<"Found\n\t" << numSimple
<< " simple vertices\n\t"
533 << numFEdges
<< " feature edge vertices\n\t"
534 << numBEdges
<< " boundary edge vertices\n\t"
535 << numFixed
<< " fixed vertices\n\t"<<endl
;
536 cout
<<"1:numPts="<<numPts
<<endl
;
538 for (i
=0; i
<numPts
; i
++)
540 cout
<<"Verts["<<i
<<"].type="<<vertex_type(Verts
[i
].type
)<<endl
;
541 if(Verts
[i
].edges
!= NULL
&& (npts
= Verts
[i
].edges
->GetNumberOfIds()) > 0)
543 for (j
=0; j
<npts
; j
++)
545 cout
<<"Verts["<<i
<<"].edges->GetId("<<j
<<")="<<Verts
[i
].edges
->GetId(j
)<<endl
;
546 }//for all connected points
550 cout
<<"Beginning smoothing iterations..."<<endl
;
551 cout
<<"2:numPts="<<numPts
<<endl
;
553 // We've setup the topology...now perform Laplacian smoothing
555 newPts
= vtkPoints::New();
556 newPts
->SetNumberOfPoints(numPts
);
558 // If Source defined, we do constrained smoothing (that is, points are
559 // constrained to the surface of the mesh object).
562 this->SmoothPoints
= new vtkSmoothPoints
;
563 vtkSmoothPoint
*sPtr
;
564 cellLocator
= vtkCellLocator::New();
565 w
= new double[source
->GetMaxCellSize()];
567 cellLocator
->SetDataSet(source
);
568 cellLocator
->BuildLocator();
570 for (i
=0; i
< numPts
; i
++)
572 sPtr
= this->SmoothPoints
->InsertSmoothPoint(i
);
573 cellLocator
->FindClosestPoint(inPts
->GetPoint(i
), closestPt
,
574 sPtr
->cellId
, sPtr
->subId
, dist2
);
575 newPts
->SetPoint(i
, closestPt
);
578 else //smooth normally
580 for (i
=0; i
<numPts
; i
++) //initialize to old coordinates
582 newPts
->SetPoint(i
,inPts
->GetPoint(i
));
586 factor
= this->RelaxationFactor
;
587 for ( maxDist
=VTK_DOUBLE_MAX
, iterationNumber
=0, abortExecute
=0;
588 maxDist
> conv
&& iterationNumber
< this->NumberOfIterations
&& !abortExecute
;
592 if ( iterationNumber
&& !(iterationNumber
% 5) )
594 this->UpdateProgress (0.5 + 0.5*iterationNumber
/this->NumberOfIterations
);
595 if (this->GetAbortExecute())
597 cout
<<"ABOOOOOOOOOOOOOOOORT!!!!!!!!!!"<<endl
;
604 // cout<<"numPts="<<numPts<<endl;
605 for (i
=0; i
<numPts
; i
++)
607 // cout<<"Verts["<<i<<"].type="<<(int)Verts[i].type<<endl;
608 if ( Verts
[i
].type
!= VTK_FIXED_VERTEX
&& Verts
[i
].edges
!= NULL
&&
609 (npts
= Verts
[i
].edges
->GetNumberOfIds()) > 0 )
611 newPts
->GetPoint(i
, x
); //use current points
612 deltaX
[0] = deltaX
[1] = deltaX
[2] = 0.0;
613 for (j
=0; j
<npts
; j
++)
615 newPts
->GetPoint(Verts
[i
].edges
->GetId(j
), y
);
618 deltaX
[k
] += (y
[k
] - x
[k
]) / npts
;
620 }//for all connected points
624 xNew
[k
] = x
[k
] + factor
* deltaX
[k
];
627 // Constrain point to surface
630 vtkSmoothPoint
*sPtr
= this->SmoothPoints
->GetSmoothPoint(i
);
633 if ( sPtr
->cellId
>= 0 ) //in cell
635 cell
= source
->GetCell(sPtr
->cellId
);
638 if ( !cell
|| cell
->EvaluatePosition(xNew
, closestPt
,
639 sPtr
->subId
, sPtr
->p
, dist2
, w
) == 0)
640 { // not in cell anymore
641 cellLocator
->FindClosestPoint(xNew
, closestPt
, sPtr
->cellId
,
646 xNew
[k
] = closestPt
[k
];
650 newPts
->SetPoint(i
,xNew
);
651 if ( (dist
= vtkMath::Norm(deltaX
)) > maxDist
)
657 } //for not converged or within iteration count
659 vtkDebugMacro(<<"Performed " << iterationNumber
<< " smoothing passes");
662 cellLocator
->Delete();
663 delete this->SmoothPoints
;
667 // Update output. Only point coordinates have changed.
669 output
->GetPointData()->PassData(input
->GetPointData());
670 output
->GetCellData()->PassData(input
->GetCellData());
672 if ( this->GenerateErrorScalars
)
674 vtkFloatArray
*newScalars
= vtkFloatArray::New();
675 newScalars
->SetNumberOfTuples(numPts
);
676 for (i
=0; i
<numPts
; i
++)
678 inPts
->GetPoint(i
,x1
);
679 newPts
->GetPoint(i
,x2
);
680 newScalars
->SetComponent(i
,0,
681 sqrt(vtkMath::Distance2BetweenPoints(x1
,x2
)));
682 cout
<<"dist["<<i
<<"]="<<sqrt(vtkMath::Distance2BetweenPoints(x1
,x2
))<<endl
;
684 int idx
= output
->GetPointData()->AddArray(newScalars
);
685 cout
<<"ERROR SCALARS STORED IN ARRAY "<<idx
<<endl
;
686 output
->GetPointData()->SetActiveAttribute(idx
, vtkDataSetAttributes::SCALARS
);
687 for (i
=0; i
<numPts
; i
++)
689 double dist
=newScalars
->GetComponent(i
-1,idx
);
690 cout
<<"dist["<<i
<<"]="<<dist
<<endl
;
693 newScalars
->Delete();
696 if ( this->GenerateErrorVectors
)
698 vtkFloatArray
*newVectors
= vtkFloatArray::New();
699 newVectors
->SetNumberOfComponents(3);
700 newVectors
->SetNumberOfTuples(numPts
);
701 for (i
=0; i
<numPts
; i
++)
703 inPts
->GetPoint(i
,x1
);
704 newPts
->GetPoint(i
,x2
);
707 x3
[j
] = x2
[j
] - x1
[j
];
709 newVectors
->SetTuple(i
,x3
);
711 output
->GetPointData()->SetVectors(newVectors
);
712 newVectors
->Delete();
715 output
->SetPoints(newPts
);
718 output
->SetVerts(input
->GetVerts());
719 output
->SetLines(input
->GetLines());
720 output
->SetPolys(input
->GetPolys());
721 output
->SetStrips(input
->GetStrips());
723 //free up connectivity storage
724 for (i
=0; i
<numPts
; i
++)
726 if ( Verts
[i
].edges
!= NULL
)
728 Verts
[i
].edges
->Delete();
729 Verts
[i
].edges
= NULL
;
737 int vtkSmoothPolyDataFilter2::FillInputPortInformation(int port
,
738 vtkInformation
*info
)
740 if (!this->Superclass::FillInputPortInformation(port
, info
))
747 info
->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
752 void vtkSmoothPolyDataFilter2::PrintSelf(ostream
& os
, vtkIndent indent
)
754 this->Superclass::PrintSelf(os
,indent
);
756 os
<< indent
<< "Convergence: " << this->Convergence
<< "\n";
757 os
<< indent
<< "Number of Iterations: " << this->NumberOfIterations
<< "\n";
758 os
<< indent
<< "Relaxation Factor: " << this->RelaxationFactor
<< "\n";
759 os
<< indent
<< "Feature Edge Smoothing: " << (this->FeatureEdgeSmoothing
? "On\n" : "Off\n");
760 os
<< indent
<< "Feature Angle: " << this->FeatureAngle
<< "\n";
761 os
<< indent
<< "Edge Angle: " << this->EdgeAngle
<< "\n";
762 os
<< indent
<< "Boundary Smoothing: " << (this->BoundarySmoothing
? "On\n" : "Off\n");
763 os
<< indent
<< "Generate Error Scalars: " << (this->GenerateErrorScalars
? "On\n" : "Off\n");
764 os
<< indent
<< "Generate Error Vectors: " << (this->GenerateErrorVectors
? "On\n" : "Off\n");
765 if ( this->GetSource() )
767 os
<< indent
<< "Source: " << (void *)this->GetSource() << "\n";
771 os
<< indent
<< "Source (none)\n";