C++:我如何使用vtk库从vti网格中读取双精度标量数据?

huangapple go评论67阅读模式
英文:

c++: How can I read double scalar data from a vti grid using the vtk library?

问题

我正在尝试从我的vti文件中的网格中读取双精度(double)值。然而,从GetScalarPointer返回的值,在我尝试访问其中的任何元素时(例如scalarPtr[0]),会生成分段错误(segmentation fault):

#include <vtkSmartPointer.h>
#include <vtkXMLImageDataReader.h>
#include <vtkImageData.h>

int main(){
  vtkSmartPointer<vtkXMLImageDataReader> reader =
      vtkSmartPointer<vtkXMLImageDataReader>::New();
  reader->SetFileName("my_file.vti");
  reader->Update();
  vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::Take(reader->GetOutput());
  double* scalarPtr = static_cast<double*>(imageData->GetScalarPointer());
  std::cout << scalarPtr[0] << std::endl; // segmentation fault
}

我知道类型是double,因为imageData->GetDataType()返回11,对应于VTK_DOUBLE

我还尝试了看是否是值的字节顺序导致的问题,但是下面的代码也导致分段错误,可能是因为scalarPtr不可访问:

double* scalarPtr = static_cast<double*>(imageData->GetScalarPointer());
const vtkIdType numScalars = imageData->GetNumberOfPoints();
const int scalarSize = sizeof(double);
vtkByteSwap::SwapVoidRange(scalarPtr, numScalars, scalarSize);

这是我的vtkImageData类的内容:

vtkImageData (0x556e1ad5afd0)
  Debug: Off
  Modified Time: 307
  Reference Count: 1
  Registered Events: (none)
  Information: 0x556e1ad5b470
  Data Released: False
  Global Release Data: Off
  UpdateTime: 0
  Field Data:
    Debug: Off
    Modified Time: 307
    Reference Count: 1
    Registered Events: (none)
    Number Of Arrays: 1
    Array 0 name = comments
    Number Of Components: 1
    Number Of Tuples: 1
  Number Of Points: 2431
  Number Of Cells: 1920
  Cell Data:
    Debug: Off
    Modified Time: 302
    Reference Count: 1
    Registered Events:
      Registered Observers:
        vtkObserver (0x556e1ad5cb00)
          Event: 33
          EventName: ModifiedEvent
          Command: 0x556e1ad5c6a0
          Priority: 0
          Tag: 1
    Number Of Arrays: 1
    Array 0 name = material
    Number Of Components: 1
    Number Of Tuples: 1920
    Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 1 1 1 )
    Interpolate Flags: ( 1 1 1 1 1 0 0 1 1 1 1 )
    Pass Through Flags: ( 1 1 1 1 1 1 1 1 1 1 1 )
    Scalars: (none)
    Vectors: (none)
    Normals: (none)
    TCoords: (none)
    Tensors: (none)
    GlobalIds: (none)
    PedigreeIds: (none)
    EdgeFlag: (none)
    Tangents: (none)
    RationalWeights: (none)
    HigherOrderDegrees: (none)
  Point Data:
    Debug: Off
    Modified Time: 304
    Reference Count: 1
    Registered Events:
      Registered Observers:
        vtkObserver (0x556e1ad5c8e0)
          Event: 33
          EventName: ModifiedEvent
          Command: 0x556e1ad5c6a0
          Priority: 0
          Tag: 1
    Number Of Arrays: 0
    Number Of Components: 0
    Number Of Tuples: 0
    Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 1 1 1 )
    Interpolate Flags: ( 1 1 1 1 1 0 0 1 1 1 1 )
    Pass Through Flags: ( 1 1 1 1 1 1 1 1 1 1 1 )
    Scalars: (none)
    Vectors: (none)
    Normals: (none)
    TCoords: (none)
    Tensors: (none)
    GlobalIds: (none)
    PedigreeIds: (none)
    EdgeFlag: (none)
    Tangents: (none)
    RationalWeights: (none)
    HigherOrderDegrees: (none)
  Bounds:
    Xmin,Xmax: (0, 5e-06)
    Ymin,Ymax: (0, 8e-06)
    Zmin,Zmax: (0, 6e-06)
  Compute Time: 308
  Spacing: (5e-07, 5e-07, 5e-07)
  Origin: (0, 0, 0)
  Direction: (1, 0, 0, 0, 1, 0, 0, 0, 1)
  Dimensions: (11, 17, 13)
  Increments: (0, 0, 0)
  Extent: (0, 10, 0, 16, 0, 12)

在访问网格值方面,我可能存在什么问题?

英文:

I am trying to read the double values from a grid in my vti file. However, the return value I get from GetScalarPointer generates a segmentation fault when I try to access any element inside of it, e.g. with scalarPtr[0]:

#include &lt;vtkSmartPointer.h&gt;
#include &lt;vtkXMLImageDataReader.h&gt;
#include &lt;vtkImageData.h&gt;
int main(){
vtkSmartPointer&lt;vtkXMLImageDataReader&gt; reader =
vtkSmartPointer&lt;vtkXMLImageDataReader&gt;::New();
reader-&gt;SetFileName(&quot;my_file.vti&quot;);
reader-&gt;Update();
vtkSmartPointer&lt;vtkImageData&gt; imageData = vtkSmartPointer&lt;vtkImageData&gt;::Take(reader-&gt;GetOutput());
double* scalarPtr = static_cast&lt;double*&gt;(imageData-&gt;GetScalarPointer());
std::cout &lt;&lt; scalarPtr[0] &lt;&lt; std::endl; // segmentation fault
}

I know the type is double because imageData-&gt;GetDataType() returns 11, which corresponds to VTK_DOUBLE.

I also tried to see if it was due to the endianness of the values, but

double* scalarPtr = static_cast&lt;double*&gt;(imageData-&gt;GetScalarPointer());
const vtkIdType numScalars = imageData-&gt;GetNumberOfPoints();
const int scalarSize = sizeof(double);
vtkByteSwap::SwapVoidRange(scalarPtr, numScalars, scalarSize);

also results in a segmentation fault, probably because scalarPtr is not accessible.

These are the contents of my vtkImageData class:

vtkImageData (0x556e1ad5afd0)
Debug: Off
Modified Time: 307
Reference Count: 1
Registered Events: (none)
Information: 0x556e1ad5b470
Data Released: False
Global Release Data: Off
UpdateTime: 0
Field Data:
Debug: Off
Modified Time: 307
Reference Count: 1
Registered Events: (none)
Number Of Arrays: 1
Array 0 name = comments
Number Of Components: 1
Number Of Tuples: 1
Number Of Points: 2431
Number Of Cells: 1920
Cell Data:
Debug: Off
Modified Time: 302
Reference Count: 1
Registered Events:
Registered Observers:
vtkObserver (0x556e1ad5cb00)
Event: 33
EventName: ModifiedEvent
Command: 0x556e1ad5c6a0
Priority: 0
Tag: 1
Number Of Arrays: 1
Array 0 name = material
Number Of Components: 1
Number Of Tuples: 1920
Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 1 1 1 )
Interpolate Flags: ( 1 1 1 1 1 0 0 1 1 1 1 )
Pass Through Flags: ( 1 1 1 1 1 1 1 1 1 1 1 )
Scalars: (none)
Vectors: (none)
Normals: (none)
TCoords: (none)
Tensors: (none)
GlobalIds: (none)
PedigreeIds: (none)
EdgeFlag: (none)
Tangents: (none)
RationalWeights: (none)
HigherOrderDegrees: (none)
Point Data:
Debug: Off
Modified Time: 304
Reference Count: 1
Registered Events:
Registered Observers:
vtkObserver (0x556e1ad5c8e0)
Event: 33
EventName: ModifiedEvent
Command: 0x556e1ad5c6a0
Priority: 0
Tag: 1
Number Of Arrays: 0
Number Of Components: 0
Number Of Tuples: 0
Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 1 1 1 )
Interpolate Flags: ( 1 1 1 1 1 0 0 1 1 1 1 )
Pass Through Flags: ( 1 1 1 1 1 1 1 1 1 1 1 )
Scalars: (none)
Vectors: (none)
Normals: (none)
TCoords: (none)
Tensors: (none)
GlobalIds: (none)
PedigreeIds: (none)
EdgeFlag: (none)
Tangents: (none)
RationalWeights: (none)
HigherOrderDegrees: (none)
Bounds:
Xmin,Xmax: (0, 5e-06)
Ymin,Ymax: (0, 8e-06)
Zmin,Zmax: (0, 6e-06)
Compute Time: 308
Spacing: (5e-07, 5e-07, 5e-07)
Origin: (0, 0, 0)
Direction: (1, 0, 0, 0, 1, 0, 0, 0, 1)
Dimensions: (11, 17, 13)
Increments: (0, 0, 0)
Extent: (0, 10, 0, 16, 0, 12)

What am I doing wrong in terms of how I am accessing the grid values?

答案1

得分: 0

以下是代码的翻译部分:

解决方案是选择正确的XML嵌套级别,即ImageData -> CellData -> DataArray:

#include <vtkSmartPointer.h>
#include <vtkXMLImageDataReader.h>
#include <vtkImageData.h>
#include <vtkCellData.h>
#include <vtkIntArray.h>

int main() {
  vtkSmartPointer<vtkXMLImageDataReader> reader =
      vtkSmartPointer<vtkXMLImageDataReader>::New();
  reader->SetFileName("my_file.vti");
  reader->Update();

  vtkSmartPointer<vtkImageData> imageData = reader->GetOutput();
  vtkSmartPointer<vtkCellData> cellData = imageData->GetCellData();
  vtkSmartPointer<vtkDataArray> dataArray = cellData->GetArray("material");

  int dims[3];
  imageData->GetDimensions(dims);
  for (int i = 0; i < 3; ++i) dims[i] = dims[i] - 1;

  for (int k = 0; k <= dims[2]; k++) {
      for (int j = 0; j <= dims[1]; j++) {
          for (int i = 0; i <= dims[0]; i++) {
              double value = dataArray->GetComponent(
                  i + j * dims[0] + k * dims[0] * dims[1], 0);
              std::cout << "Value at (" << i << ", " << j << ", " << k << "): " 
                        << value << std::endl;
          }
      }
  }
}

希望这对你有所帮助。如果你有任何其他问题,可以随时提出。

英文:

The solution was to select the correct XML nesting level, which was ImageData -> CellData -> DataArray:

#include &lt;vtkSmartPointer.h&gt;
#include &lt;vtkXMLImageDataReader.h&gt;
#include &lt;vtkImageData.h&gt;
#include &lt;vtkCellData.h&gt;
#include &lt;vtkIntArray.h&gt;
int main(){
vtkSmartPointer&lt;vtkXMLImageDataReader&gt; reader =
vtkSmartPointer&lt;vtkXMLImageDataReader&gt;::New();
reader-&gt;SetFileName(&quot;my_file.vti&quot;);
reader-&gt;Update();
vtkSmartPointer&lt;vtkImageData&gt; imageData = reader-&gt;GetOutput();
vtkSmartPointer&lt;vtkCellData&gt; cellData = imageData-&gt;GetCellData();
vtkSmartPointer&lt;vtkDataArray&gt; dataArray = cellData-&gt;GetArray(&quot;material&quot;);
int dims[3];
imageData-&gt;GetDimensions(dims);
for (int i = 0; i &lt; 3; ++i) dims[i] = dims[i]-1;
for (int k = 0; k &lt;= dims[2]; k++) {
for (int j = 0; j &lt;= dims[1]; j++) {
for (int i = 0; i &lt;= dims[0]; i++) {
double value = dataArray-&gt;GetComponent(
i + j * dims[0] + k * dims[0] * dims[1], 0);
std::cout &lt;&lt; &quot;Value at (&quot; &lt;&lt; i &lt;&lt; &quot;, &quot; &lt;&lt; j &lt;&lt; &quot;, &quot; &lt;&lt; k &lt;&lt; &quot;): &quot; 
&lt;&lt; value &lt;&lt; std::endl;
}
}
}
}

huangapple
  • 本文由 发表于 2023年3月3日 23:08:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628757.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定