整体结构是一个 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
有谁知道如何实现这个?
听起来你要找的是连载。 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 字节。您需要考虑压缩时间/工作量和减少网络流量之间的权衡。