我正试图用C写入一个要读取到VisIt中的旧版.vtk
文件。不幸的是,我安装的VisIt程序拒绝呈现我正在写入的VTK文件,读取的是:"本地主机失败"
以下是用于从一个文件中读取数据并将其转换为传统VTK文件的代码。我使用宏XPIX
、YPIX
和ZPIX
来描述像素网格的尺寸。每个像素都包含一个标量密度值。我已经使用行主排序在"网格文件"中列出了像素:即
int list_index(x,y,z) = YPIX * ZPIX * x + ZPIX * y + z;
该像素列表中的每个条目都被读取到一个名为grid[]
的double类型的数组中,并被写入传统VTK头数据下的outfile
:
/*Write vtk header */
fprintf(outfile,"# vtk DataFile Version 3.0n");
fprintf(outfile,"Galaxy density gridnASCIInDATASET STRUCTURED_POINTSn");
fprintf(outfile,"DIMENSIONS %d %d %d n", (XPIX+1), (YPIX+1), (ZPIX+1));
fprintf(outfile,"ORIGIN 0 0 0n");
fprintf(outfile,"SPACING 1 1 1n");//or ASPECT_RATIO
fprintf(outfile,"CELL_DATA %dn", totalpix);
fprintf(outfile,"SCALARS cell_density float 1n");
fprintf(outfile, "LOOKUP_TABLE defaultn");
/*Create Memory Space to store Pixel Grid*/
double *grid;
grid = malloc(XPIX * YPIX * ZPIX * sizeof(double));
if (grid == NULL ){
fprintf(stderr, "Pixel grid of type double failed to initializen");
exit(EXIT_FAILURE);
}
fprintf(stderr,"Pixel grid has been initialized.n Now reading infilen");
/*Read infile contents into double grid[], using Row-Major Indexing*/
double rho;
char newline;
int i, j, k;
for(i = 0; i < XPIX; i++){
for(j = 0; j < YPIX; j++){
for(k = 0; k < ZPIX; k++){
fscanf(infile, "%lf", &rho);
grid[getindex(i,j,k)] = rho;
}
}
fprintf(stderr,"%dn", i);
}
fprintf(stderr,"Finished readingn");
#if !DEBUG
/*Write out grid contents in Row major order*/
fprintf(stderr,"Now writing vtk file");
for(i = 0; i < XPIX; i++){
for(j = 0; j < YPIX; j++){
for(k = 0; k < ZPIX; k++){
fprintf(outfile, "%lf ", grid[getindex(i,j,k)]);
}
fprintf(outfile,"n");
}
}
fprintf(stderr,"Finished Writing to outfilen");
#endif
通过这个例程运行网格数据列表之后,我在lookup_table中有XPIX*YPIX
行,每行都有ZPIX
个条目。这是不正确的格式吗?VisIt在读取输入文件时仍然失败。我知道structured_points
可能使用列主索引,但我的第一个目标当然是从VisIt获得某种结果。我想最终使用标量cell_density绘制一个轮廓。我的数据集是不是太大了?
您看到vtk数据格式错误问题的公认答案了吗?问题是用C++调试VTK编写器,但它与您的代码非常相似(当然应该会产生相同的结果)。
公认答案的关键点是,数据是按列主顺序编写的,而不是按行主顺序编写的(您似乎在问题中暗示了这一点:"我知道structured_points可能使用列主索引")。
此外,将您的代码与您知道有效的代码进行比较总是很有帮助的(如果可以的话)。例如,VisIt提供了一个小型C库,用于编写称为VisItWriterLib的传统VTK文件格式。比较代码和VisItWriterLib的输出,查看数据文件的不同之处。我建议您在VTK IO中使用VisItWriterLib,而不是编写自己的例程——无需重新发明轮子。
编辑:回答其他几个问题:
在通过这个例程运行网格数据列表之后,我已经lookup_table中的XPIX*YPIX行,每个行都有ZPIX条目。这是吗格式不正确?
这不是正确的格式。LOOKUP_TABLE
应该是XPIX*YPIX*ZPIX
行的列表,每行一个元素(或者,VisIt将接受一行XPIX*YPIX*ZPIX
元素)。请参阅VTK文件格式文档(www.VTK.org/VTK/img/File-Formats.pdf)中的数据集属性格式部分。
我的数据集是不是太大了?
我对此表示怀疑。VisIt旨在处理巨大的数据集,并且,AFAIK,可以渲染PB级的数据集。如果你的数据这么大,我会非常惊讶。
但是,如果您担心有大文件,可以将数据拆分为多个文件,并告诉VisIt并行读取这些文件。要做到这一点,请将数据写入单独的文件中,例如domain1.vtk
、domain2.vtk
。。。domainN.vtk
等。然后写一个.visit
主文件,该文件具有结构
!NBLOCKS N
domain1.vtk
domain2.vtk
...
domainN.vtk
例如,将其另存为mydata.visit
,然后在VisIt中打开此.visit
文件,而不是.vtk
文件。