How to write a pyvista PolyData to stream or in-memory Buffer?

问题描述 投票:0回答:2

整体结构是一个 FastAPI Web 服务器,一个 GemPy 模型被发送到该服务器。然后将其绘制为 3D 模型。从这里我可以将图层提取为 PyVista/VTK PolyData 对象。在此之前工作正常,但是这些对象最好作为可用文件发送回客户端,这不仅仅是 PYthon 中的实用文件(例如 .glb/.vtk/.ply)。我在技术上知道如何做到这一点,但是对于服务器端我试图将文件保存到缓冲区中,这似乎无法用 pyvista.PolyData.save() 或 vtk.vtkWriter 实现。

我的代码看起来像这样

# this just creates an object from which the layers can be extracted as polydata
gpv = gp.plot_3d(geo_model)

# here an examples how to get polydata or an unstructuredgrid
poly = gpv.surface_poly['Sandstone_2']

grid = pv.UnstructuredGrid(poly)

从这里我想用 pyvista 保存它

poly.save("filename.ply")

或者使用 vtk

替代
def write_grid_to_vtk(grid, filename):

    writer = vtk.vtkUnstructuredGridWriter()
    writer.SetFileName(filename)
    writer.SetInputData(grid)
    #writer.SetFileTypeToBinary()
    writer.Write()

buf = io.BytesIO()
write_grid_to_vtk(grid, buf)
buf.close()

在 vtk 示例中你可以看到,我是如何尝试实现缓冲区的。这引发了

TypeError: SetFileName argument %Id: %V 

有谁知道如何实现这个?

python buffer vtk pyvista
2个回答
1
投票

听起来你要找的是连载。 PyVista 网格已经支持通过 pickle 协议进行序列化,这将像

pickle.dumps(poly)
一样简单,而另一方面
pickle.loads(b)
。但众所周知,
pickle
对恶意 pickle 文件是不安全的,因此您可能希望避免让您的用户接触到该机制。

相反,您可以 看看 PyVista 如何实现用于酸洗的

__getstate__()
__setstate__()
方法
(特别是较新的
'xml'
代码路径)。

这是一个针对

PolyData
的精简示例:

import pyvista as pv
from vtkmodules.vtkIOXML import vtkXMLPolyDataReader, vtkXMLPolyDataWriter

def poly_to_bytes(mesh):
    """Serialize a PolyData to bytes."""
    writer = vtkXMLPolyDataWriter()
    writer.SetInputDataObject(mesh)
    writer.SetWriteToOutputString(True)
    writer.SetDataModeToBinary()
    writer.SetCompressorTypeToNone()
    # or perhaps SetCompressorTypeToZLib() etc.
    writer.Write()
    return writer.GetOutputString()

def bytes_to_poly(bs):
    """Unserialize a bytes to pyvista.PolyData."""
    reader = vtkXMLPolyDataReader()
    reader.ReadFromInputStringOn()
    reader.SetInputString(bs)
    reader.Update()
    return pv.wrap(reader.GetOutput())

# example polydata
poly = pv.Dodecahedron()

# serialize
bs = poly_to_bytes(poly)
# ... imagine sending this to the client

# unserialize
poly_after = bytes_to_poly(bs)

print(poly == poly_after)  # True

您还可以从一些压缩器中进行选择,这些选项可以在

vtkXMLWriterBase
的文档中找到。我在上面的代码片段中尝试了
None
ZLib
的情况,并且压缩将字节串从 3376 字节减少到 2699 字节。您需要考虑压缩时间/工作量和减少网络流量之间的权衡。


0
投票

我在使用gempy的过程中遇到了一些问题,我把它放在图片里了,你能帮我看看我应该怎么处理吗?期待你的回复 enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.