英文:
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 <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
}
I know the type is double because imageData->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<double*>(imageData->GetScalarPointer());
const vtkIdType numScalars = imageData->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 <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;
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论