【问题标题】:Creating a blender mesh directly from numpy data?直接从 numpy 数据创建搅拌机网格?
【发布时间】:2021-09-18 15:45:29
【问题描述】:

是否可以直接从高效的 numpy 数组创建 Blender 网格,而无需通过(缓慢且浪费空间的)POD python 数据类型?这是一个说明我的意思的脚本。我需要在我的 numpy 数据上调用 .tolist() 以使脚本正常工作。还有其他更高效的 API 吗?

# Create a mesh from numpy arrays. Can you do this without tolist()?
import bpy
import numpy as np

verts = np.array([
  (1, 1, 1),
  (-1, 1, -1),
  (-1, -1, 1),
  (1, -1, -1),
], dtype=np.float32)

faces = np.array([[0, 1, 2], [0, 2, 3], [0, 3, 1], [2, 1, 3]],
                 dtype=int)

mesh = bpy.data.meshes.new('TetraMesh')   
obj = bpy.data.objects.new('Tetra', mesh) 

# Must call tolist() to pass to from_pydata()!
mesh.from_pydata(verts.tolist(),[],faces.tolist())   
mesh.update(calc_edges=True)              # Update mesh with new data
bpy.context.collection.objects.link(obj)  # Link to scene

【问题讨论】:

    标签: python blender


    【解决方案1】:

    这个使用 foreach_set 对我有用。 您不必将 numpy 数组转换为列表。 我评论了每一行,应该清楚它是如何工作的。

    import bpy
    import numpy
    
    # the numpy array must be in this form
    vertices = numpy.array([
                            1, 1, 1,       # vertex 0
                            -1, 1, -1,     # vertex 1
                            -1, -1, 1,     # vertex 2
                            1, -1, -1      # vertex 3
                            ], dtype=numpy.float32)
    
    # vertices for each polygon
    vertex_index = numpy.array([
                                0, 1, 2,   #  first polygon starting at 0
                                0, 2, 3,   # second polygon starting at 3
                                0, 3, 1,   #  third polygon starting at 6
                                2, 1, 3    #  forth polygon starting at 9
                                ], dtype=numpy.int32)
    
    
    # every polygon start at a specific index in vertex_index array
    loop_start = numpy.array([
                              0, # polygon start at 0 --> 0, 1, 2
                              3, # polygon start at 3 --> 0, 2, 3
                              6, # polygon start at 6 --> 0, 3, 1
                              9  # polygon start at 9 --> 2, 1, 3
                              ], dtype=numpy.int32)
                              
    # lenght of the loop
    num_loops = loop_start.shape[0]
    
    
    # Length of each polygon in number of vertices
    loop_total = numpy.array([3,3,3,3], dtype=numpy.int32)
    
    
    # Create mesh object based on the arrays above
    mesh = bpy.data.meshes.new(name='created mesh')
    
    # Number of vertices in vertices array (12 // 3)
    num_vertices = vertices.shape[0] // 3
    
    # add the amount of vertices, in this case 4.
    mesh.vertices.add(num_vertices)
    
    # use the vertices numpy array
    mesh.vertices.foreach_set("co", vertices)
    
    # total indexes in vertex_index
    num_vertex_indices = vertex_index.shape[0]
    
    # add the amount of the vertex_index array, in this case 12
    mesh.loops.add(num_vertex_indices)
    
    # set the vertx_index
    mesh.loops.foreach_set("vertex_index", vertex_index)
    
    # add the length of loop_start array
    mesh.polygons.add(num_loops)
    
    # generate the polygons
    mesh.polygons.foreach_set("loop_start", loop_start)
    mesh.polygons.foreach_set("loop_total", loop_total)
    
    # validate your mesh
    mesh.update()
    mesh.validate()
    
    # create the object with the mesh just created
    obj = bpy.data.objects.new('created object', mesh)
    
    # add the Oject to the scene
    scene = bpy.context.scene
    scene.collection.objects.link(obj)
    

    如果你想了解更多,还有另一个更一致的例子here

    【讨论】:

      【解决方案2】:

      Blender 最近在 master 分支中修复了这个问题 https://developer.blender.org/rBacf1374495c19d7b600ad12f12a01d6e8dfe7900

      当前的解决方法是使用覆盖 __bool__ 方法的类查看数组,这样当 Blender 检查数组的布尔值时,它实际上会执行 Blender 开发人员打算做的事情(检查数组的长度是否为 > 0)

      class ndarray_pydata(np.ndarray):
          def __bool__(self) -> bool:
              return len(self) > 0
      
      edges = edges_np.view(ndarray_pydata)
      faces = faces_np.view(ndarray_pydata)
      mesh.from_pydata(vertices, edges, faces)
      
      

      完整的工作示例: https://gist.github.com/iyadahmed/7c7c0fae03c40bd87e75dc7059e35377

      【讨论】:

        猜你喜欢
        • 2019-09-04
        • 2017-07-08
        • 2021-09-27
        • 2021-09-30
        • 2018-10-06
        • 2022-11-01
        • 2020-05-22
        • 2018-10-01
        • 2016-03-07
        相关资源
        最近更新 更多