I used closed polygons as input polydata, but the result is not closed。
Anyone can give me some advice?
How to make the output closed?
Mesh reconstruction(const Ring3dList &ring_list, double slice_spacing)
{
// ring3d: {plane, ring2d};
// pre-condition: slices in contour list are parallel and equal spacing
Point3dDouble normal_vector = ring_list.front().first.getNormalVector();
Point3dDouble plane_origin = ring_list[0].first.getOrigin();
arma::mat matrix = transformMatrix(plane_origin, normal_vector); // use first plane as the z=0 plane.
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
for (size_t i = 0; i < ring_list.size(); i++) {
Points3dDoubleList pt_list;
for (auto &point : ring_list[i].second.points) {
Point3dDouble pt = ring_list[i].first.transfer2DTo3D(point);
pt_list.push_back(transform(matrix, pt));
}
vtkSmartPointer<vtkPolyData> data = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
points->SetNumberOfPoints(static_cast<long long>(pt_list.size()));
cells->Allocate(1, points->GetNumberOfPoints());
cells->InsertNextCell(static_cast<int>(points->GetNumberOfPoints()));
for (size_t j = 0; j < pt_list.size(); j++) {
Point3dDouble pt = pt_list[j];
points->SetPoint(static_cast<int>(j), pt.x(), pt.y(), pt.z());
cells->InsertCellPoint(static_cast<int>(j));
}
data->Initialize();
data->SetPolys(cells);
data->SetPoints(points);
appendFilter->AddInputData(data);
}
appendFilter->Update();
double bounds[6];
vtkPolyData* contours = appendFilter->GetOutput();
contours->GetBounds( bounds );
double origin[3] = {bounds[0], bounds[2], bounds[4] };
double spacing[3] = {(bounds[1] - bounds[0]) / K_RING_RESOLUTION,
(bounds[3] - bounds[2]) / K_RING_RESOLUTION,
slice_spacing};
vtkSmartPointer<vtkPolyData> poly = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkPoints* contourPoints = contours->GetPoints();
int numPoints = static_cast<int>(contourPoints->GetNumberOfPoints());
points->SetNumberOfPoints( numPoints );
for( int i = 0; i < numPoints; ++i )
{
double pt[3];
contourPoints->GetPoint( i, pt );
pt[0] = static_cast<int>( (pt[0] - origin[0]) / spacing[0] + 0.5 );
pt[1] = static_cast<int>( (pt[1] - origin[1]) / spacing[1] + 0.5 );
pt[2] = static_cast<int>( (pt[2] - origin[2]) / spacing[2] + 0.5 );
points->SetPoint( i, pt );
}
poly->SetPolys( contours->GetPolys() );
poly->SetPoints( points );
vtkSmartPointer<vtkVoxelContoursToSurfaceFilter> contoursToSurface =
vtkSmartPointer<vtkVoxelContoursToSurfaceFilter>::New();
contoursToSurface->SetInputData( poly );
contoursToSurface->SetSpacing( spacing[0], spacing[1], spacing[2] );
contoursToSurface->Update();
double scaleCenter[3];
contoursToSurface->GetOutput()->GetCenter( scaleCenter );
double center[3];
contours->GetCenter(center);
vtkSmartPointer<vtkTransform> translate = vtkSmartPointer<vtkTransform>::New();
translate->Translate(-scaleCenter[0], -scaleCenter[1], -scaleCenter[2]);
translate->Translate(center[0], center[1], center[2]);
translate->Update();
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter1 = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter1->SetInputConnection(contoursToSurface->GetOutputPort());
transformFilter1->SetTransform(translate);
transformFilter1->Update();
vtkSmartPointer<vtkTransform> reverse = vtkSmartPointer<vtkTransform>::New();
arma::mat reverse_matrix = matrix.i();
double m[16];
for (size_t i = 0; i < 16; i++) {
m[i] = reverse_matrix[(i % 4 ) * 4 + i / 4];
}
reverse->SetMatrix(m);
reverse->Update();
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter2 = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter2->SetInputConnection(transformFilter1->GetOutputPort());
transformFilter2->SetTransform(reverse);
transformFilter2->Update();
if (!isMeshDataValid(transformFilter2)) {
DLOG("Reconstruction of ring list failed!");
return Mesh();
}
MeshData mesh_data = cleanMeshData(transformFilter2);
MeshProp mesh_prop = getMeshDataProp(mesh_data);
DLOG("Reconstruction of ring list success!");
return Mesh{mesh_data, mesh_prop};
}
The result is
Thanks !!!