vtk类设计与思想--vtkExecutive

* vtkExecutive is the superclass for all pipeline executives in VTK.
 * A VTK executive is responsible for controlling one instance of
 * vtkAlgorithm.  A pipeline consists of one or more executives that
 * control data flow.  Every reader, source, writer, or data
 * processing algorithm in the pipeline is implemented in an instance
 * of vtkAlgorithm.

vtkExective 是所有管道处理的父类,一个vtkExective对象处理一个vtkAlgorithm实例,但一个管道可以有多个vtkexective对象来处理数据流,读写器,数据对象显示源都要继承vtkAlgorithm类。

以vtkPolydatareader类为例。

vtkPolyDataReader is a source object that reads ASCII or binary
 * polygonal data files in vtk format (see text for format details).
 * The output of this reader is a single vtkPolyData data object.
 * The superclass of this class, vtkDataReader, provides many methods for
 * controlling the reading of the data file, see vtkDataReader for more
 * information.
 * @warning
 * Binary files written on one system may not be readable on other systems.
 * @sa
 * vtkPolyData vtkDataReader

官方解释如上,此类就是来读取.vtk文件来生成vtkpolydata数据(包含里点、线、面及相互的拓扑关系,随后详细展开)。从源文件分析此类。.vtk文件格式解析之前的一篇可以查看。
 


  static vtkPolyDataReader *New(); 实例化对象
  vtkTypeMacro(vtkPolyDataReader,vtkDataReader);父子继承类型宏,用来追踪父子关系,能看出来vtkpolydatareader继承vtkDataReader类。他的父类不再展开说了。
  void PrintSelf(ostream& os, vtkIndent indent) override;打印这是vtkbaseobject祖师类的方法了。
  vtkPolyData *GetOutput(int idx); 得到第idx端口的数据,可以有多端口,根据实际类型情况分析,vtkPolydatareader是单输出口,idx为0.
  void SetOutput(vtkPolyData *output);

这是最核心的读取方法类,不同的格式读取主要重写这个方法。
  int ReadMeshSimple(const std::string& fname,
                     vtkDataObject* output) override;

详细分析此方法,便于书写.off等官方未重写的文件读取方法。

# vtk DataFile Version 3.0
vtk output
ASCII
DATASET POLYDATA
POINTS 989 float
-0.300020 -0.500000 0.000000

节选文件的一部分。

int vtkPolyDataReader::ReadMeshSimple(
  const std::string& fname, vtkDataObject* doOutput)
{
  vtkIdType numPts=0;
  char line[256];
  vtkIdType npts, size = 0, ncells, i;
  vtkPolyData *output = vtkPolyData::SafeDownCast(doOutput);
  int *tempArray;
  vtkIdType *idArray;

  vtkDebugMacro(<<"Reading vtk polygonal data...");

//vtkdebug输出正在读取vtkpolydata数据。

  if ( !(this->OpenVTKFile(fname.c_str())) || !this->ReadHeader(fname.c_str()))
  {
    return 1;
  }
//打不开vtk文件
// Read polygonal data specific stuff
//文件读取完毕
  if (!this->ReadString(line))
  {
    vtkErrorMacro(<<"Data file ends prematurely!");
    this->CloseVTKFile ();
    return 1;
  }

  if ( !strncmp(this->LowerCase(line),"dataset",(unsigned long)7) )
  {
//判断是否是dataset数据格式。
// Make sure we're reading right type of geometry
//读完文件
    if (!this->ReadString(line))
    {
      vtkErrorMacro(<<"Data file ends prematurely!");
      this->CloseVTKFile ();
      return 1;
    }

//确定是polydata文件格式。

    if ( strncmp(this->LowerCase(line),"polydata",8) )
    {
      vtkErrorMacro(<< "Cannot read dataset type: " << line);
      this->CloseVTKFile ();
      return 1;
    }
//
// Might find points, vertices, lines, polygons, or triangle strips
//文件读取正确
    while (true)
    {
      if (!this->ReadString(line))
      {
        break;
      }

//读取完毕,下面的判读不知道是兼容哪个版本的,3.0vtk中polydata格式中没有发现field字段。或者在一些兼容格式中有field字段类型。

      if (! strncmp(this->LowerCase(line), "field", 5))
      {
        vtkFieldData* fd = this->ReadFieldData();//需要说明下vtkfielddata类,继承vtkObject,主要用来对field这种类型的文件流读取处理。读取的是字符串数组。后面介绍vtkdatareader类。
        output->SetFieldData(fd);
        fd->Delete(); // ?
      }

//开始正常的vtk文件读取。先从points开始。
      else if ( ! strncmp(line, "points",6) )
      {
        if (!this->Read(&numPts))
        {
          vtkErrorMacro(<<"Cannot read number of points!");
          this->CloseVTKFile ();
          return 1;
        }

//读取点坐标

// this->IS->getline(line,256); istream IS
 //       this->IS->read((char *)ptr,sizeof(unsigned char)*(numTuples*numComp+7)/8);

        this->ReadPointCoordinates(output, numPts);
      }

//顶点坐标

      else if ( ! strncmp(line,"vertices",8) )
      {
        vtkCellArray *verts = vtkCellArray::New();
        if (!(this->Read(&ncells) && this->Read(&size)))
        {
          vtkErrorMacro(<<"Cannot read vertices!");
          this->CloseVTKFile ();
          return 1;
        }

        tempArray = new int[size];
        idArray = verts->WritePointer(ncells, size);
        this->ReadCells(size, tempArray);
//        this->ReadCells(size, verts->WritePointer(ncells,size));
        for (i = 0; i < size; i++)
        {
          idArray[i] = tempArray[i];
        }
        output->SetVerts(verts);
        verts->Delete();
        delete [] tempArray;
        vtkDebugMacro(<<"Read " << ncells << " vertices");
      }

      else if ( ! strncmp(line,"lines",5) )
      {
        vtkCellArray *lines = vtkCellArray::New();
        if (!(this->Read(&ncells) && this->Read(&size)))
        {
          vtkErrorMacro(<<"Cannot read lines!");
          this->CloseVTKFile ();
          return 1;
        }
        tempArray = new int[size];
        idArray = lines->WritePointer(ncells, size);
        this->ReadCells(size, tempArray);
//        this->ReadCells(size, lines->WritePointer(ncells,size));
        for (i = 0; i < size; i++)
        {
          idArray[i] = tempArray[i];
        }

        output->SetLines(lines);
        lines->Delete();
        delete [] tempArray;
        vtkDebugMacro(<<"Read " << ncells << " lines");
      }

//读取三角面片

      else if ( ! strncmp(line,"polygons",8) )
      {
        vtkCellArray *polys = vtkCellArray::New();
        if (!(this->Read(&ncells) && this->Read(&size)))
        {
          vtkErrorMacro(<<"Cannot read polygons!");
          this->CloseVTKFile ();
          return 1;
        }

        tempArray = new int[size];
        idArray = polys->WritePointer(ncells, size);
        this->ReadCells(size, tempArray);
//        this->ReadCells(size, polys->WritePointer(ncells,size));
        for (i = 0; i < size; i++)
        {
          idArray[i] = tempArray[i];
        }
        output->SetPolys(polys);
        polys->Delete();
        delete [] tempArray;
        vtkDebugMacro(<<"Read " << ncells << " polygons");
      }

      else if ( ! strncmp(line,"triangle_strips",15) )
      {
        vtkCellArray *tris = vtkCellArray::New();
        if (!(this->Read(&ncells) && this->Read(&size)))
        {
          vtkErrorMacro(<<"Cannot read triangle strips!");
          this->CloseVTKFile ();
          return 1;
        }

        tempArray = new int[size];
        idArray = tris->WritePointer(ncells, size);
        this->ReadCells(size, tempArray);
//        this->ReadCells(size, tris->WritePointer(ncells,size));
        for (i = 0; i < size; i++)
        {
          idArray[i] = tempArray[i];
        }
        output->SetStrips(tris);
        tris->Delete();
        delete [] tempArray;
        vtkDebugMacro(<<"Read " << ncells << " triangle strips");
      }

//读取cell_data scalar值

      else if ( ! strncmp(line, "cell_data", 9) )
      {
        if (!this->Read(&ncells))
        {
          vtkErrorMacro(<<"Cannot read cell data!");
          this->CloseVTKFile ();
          return 1;
        }

        if ( ncells != output->GetNumberOfCells() )
        {
          vtkErrorMacro(<<"Number of cells don't match number data values!");
          return 1;
        }

        this->ReadCellData(output, ncells);
        break; //out of this loop
      }

      else if ( ! strncmp(line, "point_data", 10) )
      {
        if (!this->Read(&npts))
        {
          vtkErrorMacro(<<"Cannot read point data!");
          this->CloseVTKFile ();
          return 1;
        }

        if ( npts != numPts )
        {
          vtkErrorMacro(<<"Number of points don't match number data values!");
          return 1;
        }

        this->ReadPointData(output, npts);
        break; //out of this loop
      }

      else
      {
        vtkErrorMacro(<< "Unrecognized keyword: " << line);
        this->CloseVTKFile ();
        return 1;
      }
    }

      if ( ! output->GetPoints() ) vtkWarningMacro(<<"No points read!");
      if ( !(output->GetVerts() || output->GetLines() ||
      output->GetPolys() || output->GetStrips()) )
        vtkWarningMacro(<<"No topology read!");
  }

  else if ( !strncmp(line, "cell_data", 9) )
  {
    vtkWarningMacro(<<"No geometry defined in data file!");
    if (!this->Read(&ncells))
    {
      vtkErrorMacro(<<"Cannot read cell data!");
      this->CloseVTKFile ();
      return 1;
    }

    this->ReadCellData(output, ncells);
  }

  else if ( !strncmp(line, "point_data", 10) )
  {
    vtkWarningMacro(<<"No geometry defined in data file!");
    if (!this->Read(&numPts))
    {
      vtkErrorMacro(<<"Cannot read point data!");
      this->CloseVTKFile ();
      return 1;
    }

    this->ReadPointData(output, numPts);
  }

  else
  {
    vtkErrorMacro(<< "Unrecognized keyword: " << line);
  }
  this->CloseVTKFile ();

  return 1;
}

//读取fielddata

vtkFieldData *vtkDataReader::ReadFieldData(FieldType fieldType)
{
  int i, numArrays=0, skipField=0;
  vtkFieldData *f;
  char name[256], type[256];
  vtkIdType numComp, numTuples;
  vtkAbstractArray *data;

  if ( !(this->ReadString(name) && this->Read(&numArrays)) )
  {
    const char* fname = this->CurrentFileName.c_str();
    vtkErrorMacro(<<"Cannot read field header!" << " for file: "
                  << (fname?fname:"(Null FileName)"));
    return nullptr;
  }

  // See whether field data name (if specified)
  if ( (this->FieldDataName && strcmp(name,this->FieldDataName)) )
  {
    skipField = 1;
  }

  f = vtkFieldData::New();
  f->AllocateArrays(numArrays);

  // Read the number of arrays specified
  for (i=0; i<numArrays; i++)
  {
    char buffer[1024];
    this->ReadString(buffer);
    if ( strcmp(buffer, "NULL_ARRAY") == 0 )
    {
      continue;
    }
    this->DecodeString(name, buffer);
    this->Read(&numComp);
    this->Read(&numTuples);
    this->ReadString(type);
    data = this->ReadArray(type, numTuples, numComp);
    if ( data != nullptr )
    {
      if ( ! skipField  || this->ReadAllFields )
      {
        data->SetName(name);
        this->ConvertGhostLevelsToGhostType(fieldType, data);
        f->AddArray(data);
      }
      data->Delete();
    }
    else
    {
      f->Delete();
      return nullptr;
    }
  }

  if ( skipField && ! this->ReadAllFields )
  {
    f->Delete();
    return nullptr;
  }
  else
  {
    return f;
  }
}

// Read point coordinates. Return 0 if error. 读取坐标方法解析
int vtkDataReader::ReadPointCoordinates(vtkPointSet *ps, vtkIdType numPts)
{
  char line[256];
  vtkDataArray *data;

  if (!this->ReadString(line))
  {
    const char* fname = this->CurrentFileName.c_str();
    vtkErrorMacro(<<"Cannot read points type!" << " for file: " << (fname?fname:"(Null FileName)"));
    return 0;
  }

//一行是三个xyz坐标值

  data = vtkArrayDownCast<vtkDataArray>(
    this->ReadArray(line, numPts, 3));
  if ( data != nullptr )
  {
    vtkPoints *points=vtkPoints::New();
    points->SetData(data);
    data->Delete();
    ps->SetPoints(points);//点集合
    points->Delete();
  }
  else
  {
    return 0;
  }

  vtkDebugMacro(<<"Read " << ps->GetNumberOfPoints() << " points");
  float progress = this->GetProgress();
  this->UpdateProgress(progress + 0.5*(1.0 - progress));

//该类继承算法类,updateProgress后面的参数要求在(0,1)之间,属于激活事件将调用此算法的所有数据进行通知更新。在vtkAlgorithm类中有详细介绍,可参考。

  return 1;
}

总结下,vtk文件存的可以认为是字符串,在数据读取时都认为是字符串的提取就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值