I found vtkSTLWriter can help us to avoid error Can't follow edge
in vtkSelectPolyData as described in the article Is there a bug in vtkSelectPolyData?. The data after I/O operations in STL file format, it can be handled correctly by vtkSelectPolyData.
After tried vtkXMLPolyDataWriter, I find that the new data show Can't follow edge
again.
So it indicated that vtkXMLPolyDataWriter and vtkSTLWriter saved different data.
I have to figure out the two writer’s inheritance relationships before continuing to explore.
vtkXMLWriter <= vtkXMLUnstructuredDataWriter <= vtkXMLPolyDataWriter
vtkAlgorithm <= vtkXMLWriter <= vtkXMLUnstructuredDataWriter <= vtkXMLPolyDataWriter
The vtkSTLWriter object just stores the points which are used in cells, but the vtkXMLPolyDataWriter object saves all points no matter whether it’s valuable.
void vtkSTLWriter::WriteAsciiSTL(
vtkPoints *pts, vtkCellArray *polys, vtkCellArray *strips)
{
//...
for (polys->InitTraversal(); polys->GetNextCell(npts,indx); )
{
if (npts == 3)
{
pts->GetPoint(indx[0],v1);
pts->GetPoint(indx[1],v2);
pts->GetPoint(indx[2],v3);
vtkTriangle::ComputeNormal(pts, npts, indx, n);
fprintf(fp, " facet normal %.6g %.6g %.6g\n outer loop\n",
n[0], n[1], n[2]);
fprintf(fp, " vertex %.6g %.6g %.6g\n", v1[0], v1[1], v1[2]);
fprintf(fp, " vertex %.6g %.6g %.6g\n", v2[0], v2[1], v2[2]);
fprintf(fp, " vertex %.6g %.6g %.6g\n", v3[0], v3[1], v3[2]);
fprintf(fp, " endloop\n endfacet\n");
}
//...
}
void vtkXMLUnstructuredDataWriter::WriteInlinePiece(vtkIndent indent)
{
vtkPointSet* input = this->GetInputAsPointSet();
//...
// Write the point data arrays.
this->WritePointDataInline(input->GetPointData(), indent);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
// Set the range of progress for the cell data arrays.
this->SetProgressRange(progressRange, 1, fractions);
// Write the cell data arrays.
this->WriteCellDataInline(input->GetCellData(), indent);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
//...
// Write the point specification array.
this->WritePointsInline(input->GetPoints(), indent);
}
But how is the interface vtkXMLUnstructuredDataWriter::WriteInlinePiece
invoked in the project? I am very curious about it.
I read some source code and got the pipeline workflow.
The vtkExecutive object controls the logic of how to connect and execute a pipeline.
Every vtkAlgorithm object has its own executive that communicates with other executives. The class vtkAlgorithm is the superclass for all filters/sources/sinks in VTK and knows nothing about the pipeline.
vtkExecutive has an inheritance relationship.
vtkExecutive <= vtkDemandDrivenPipeline <= vtkStreamingDemandDrivenPipeline <= vtkCompositeDataPipeline
VTK uses pointer to make the executive object access algorithm and algorithm object access executive possible.
The interface vtkXMLUnstructuredDataWriter::WriteInlinePiece
is used in the following invoking stack.
void vtkAlgorithm::Update(int port)
{
this->GetExecutive()->Update(port);
}
vtkStreamingDemandDrivenPipeline::Update
<=
vtkStreamingDemandDrivenPipeline::PropagateUpdateExtent,
vtkStreamingDemandDrivenPipeline::PropagateTime,
vtkStreamingDemandDrivenPipeline::UpdateTimeDependentInformation
<=
vtkStreamingDemandDrivenPipeline::ProcessRequest
<=
vtkExecutive::CallAlgorithm
<=
vtkXMLUnstructuredDataWriter::ProcessRequest
<=
vtkXMLUnstructuredDataWriter::WriteAPiece
<=
vtkXMLUnstructuredDataWriter::WriteInlineMode
<=
vtkXMLUnstructuredDataWriter::WriteInlinePiece
The interface RequestData
is often used to define algorithm logic in the subclass of vtkAlgorithm, so it’s beneficial to figure out it’s invoking stack.
Now vtkSelectExplore project can avoid Can't follow edge
safely, its code has been uploaded to GitHub, vtkSelectExplore
vtkXMLUnstructuredDataWriter::ProcessRequest
<=
vtkXMLWriter::ProcessRequest
<=
vtkXMLWriter::RequestData
Pipeline browser in ParaView: