bmesh.ops.1.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # This script uses bmesh operators to make 2 links of a chain.
  2. import bpy
  3. import bmesh
  4. import math
  5. import mathutils
  6. # Make a new BMesh
  7. bm = bmesh.new()
  8. # Add a circle XXX, should return all geometry created, not just verts.
  9. bmesh.ops.create_circle(
  10. bm,
  11. cap_ends=False,
  12. radius=0.2,
  13. segments=8)
  14. # Spin and deal with geometry on side 'a'
  15. edges_start_a = bm.edges[:]
  16. geom_start_a = bm.verts[:] + edges_start_a
  17. ret = bmesh.ops.spin(
  18. bm,
  19. geom=geom_start_a,
  20. angle=math.radians(180.0),
  21. steps=8,
  22. axis=(1.0, 0.0, 0.0),
  23. cent=(0.0, 1.0, 0.0))
  24. edges_end_a = [ele for ele in ret["geom_last"]
  25. if isinstance(ele, bmesh.types.BMEdge)]
  26. del ret
  27. # Extrude and create geometry on side 'b'
  28. ret = bmesh.ops.extrude_edge_only(
  29. bm,
  30. edges=edges_start_a)
  31. geom_extrude_mid = ret["geom"]
  32. del ret
  33. # Collect the edges to spin XXX, 'extrude_edge_only' could return this.
  34. verts_extrude_b = [ele for ele in geom_extrude_mid
  35. if isinstance(ele, bmesh.types.BMVert)]
  36. edges_extrude_b = [ele for ele in geom_extrude_mid
  37. if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary]
  38. bmesh.ops.translate(
  39. bm,
  40. verts=verts_extrude_b,
  41. vec=(0.0, 0.0, 1.0))
  42. # Create the circle on side 'b'
  43. ret = bmesh.ops.spin(
  44. bm,
  45. geom=verts_extrude_b + edges_extrude_b,
  46. angle=-math.radians(180.0),
  47. steps=8,
  48. axis=(1.0, 0.0, 0.0),
  49. cent=(0.0, 1.0, 1.0))
  50. edges_end_b = [ele for ele in ret["geom_last"]
  51. if isinstance(ele, bmesh.types.BMEdge)]
  52. del ret
  53. # Bridge the resulting edge loops of both spins 'a & b'
  54. bmesh.ops.bridge_loops(
  55. bm,
  56. edges=edges_end_a + edges_end_b)
  57. # Now we have made a links of the chain, make a copy and rotate it
  58. # (so this looks something like a chain)
  59. ret = bmesh.ops.duplicate(
  60. bm,
  61. geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
  62. geom_dupe = ret["geom"]
  63. verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)]
  64. del ret
  65. # position the new link
  66. bmesh.ops.translate(
  67. bm,
  68. verts=verts_dupe,
  69. vec=(0.0, 0.0, 2.0))
  70. bmesh.ops.rotate(
  71. bm,
  72. verts=verts_dupe,
  73. cent=(0.0, 1.0, 0.0),
  74. matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
  75. # Done with creating the mesh, simply link it into the scene so we can see it
  76. # Finish up, write the bmesh into a new mesh
  77. me = bpy.data.meshes.new("Mesh")
  78. bm.to_mesh(me)
  79. bm.free()
  80. # Add the mesh to the scene
  81. obj = bpy.data.objects.new("Object", me)
  82. bpy.context.collection.objects.link(obj)
  83. # Select and make active
  84. bpy.context.view_layer.objects.active = obj
  85. obj.select_set(True)