operator_mesh_add.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import bpy
  2. import bmesh
  3. from bpy_extras.object_utils import AddObjectHelper
  4. def add_box(width, height, depth):
  5. """
  6. This function takes inputs and returns vertex and face arrays.
  7. no actual mesh data creation is done here.
  8. """
  9. verts = [
  10. (+1.0, +1.0, -1.0),
  11. (+1.0, -1.0, -1.0),
  12. (-1.0, -1.0, -1.0),
  13. (-1.0, +1.0, -1.0),
  14. (+1.0, +1.0, +1.0),
  15. (+1.0, -1.0, +1.0),
  16. (-1.0, -1.0, +1.0),
  17. (-1.0, +1.0, +1.0),
  18. ]
  19. faces = [
  20. (0, 1, 2, 3),
  21. (4, 7, 6, 5),
  22. (0, 4, 5, 1),
  23. (1, 5, 6, 2),
  24. (2, 6, 7, 3),
  25. (4, 0, 3, 7),
  26. ]
  27. # apply size
  28. for i, v in enumerate(verts):
  29. verts[i] = v[0] * width, v[1] * depth, v[2] * height
  30. return verts, faces
  31. from bpy.props import (
  32. BoolProperty,
  33. BoolVectorProperty,
  34. EnumProperty,
  35. FloatProperty,
  36. FloatVectorProperty,
  37. )
  38. class AddBox(bpy.types.Operator):
  39. """Add a simple box mesh"""
  40. bl_idname = "mesh.primitive_box_add"
  41. bl_label = "Add Box"
  42. bl_options = {'REGISTER', 'UNDO'}
  43. width: FloatProperty(
  44. name="Width",
  45. description="Box Width",
  46. min=0.01, max=100.0,
  47. default=1.0,
  48. )
  49. height: FloatProperty(
  50. name="Height",
  51. description="Box Height",
  52. min=0.01, max=100.0,
  53. default=1.0,
  54. )
  55. depth: FloatProperty(
  56. name="Depth",
  57. description="Box Depth",
  58. min=0.01, max=100.0,
  59. default=1.0,
  60. )
  61. layers: BoolVectorProperty(
  62. name="Layers",
  63. description="Object Layers",
  64. size=20,
  65. options={'HIDDEN', 'SKIP_SAVE'},
  66. )
  67. # generic transform props
  68. align_items = (
  69. ('WORLD', "World", "Align the new object to the world"),
  70. ('VIEW', "View", "Align the new object to the view"),
  71. ('CURSOR', "3D Cursor", "Use the 3D cursor orientation for the new object")
  72. )
  73. align: EnumProperty(
  74. name="Align",
  75. items=align_items,
  76. default='WORLD',
  77. update=AddObjectHelper.align_update_callback,
  78. )
  79. location: FloatVectorProperty(
  80. name="Location",
  81. subtype='TRANSLATION',
  82. )
  83. rotation: FloatVectorProperty(
  84. name="Rotation",
  85. subtype='EULER',
  86. )
  87. def execute(self, context):
  88. verts_loc, faces = add_box(
  89. self.width,
  90. self.height,
  91. self.depth,
  92. )
  93. mesh = bpy.data.meshes.new("Box")
  94. bm = bmesh.new()
  95. for v_co in verts_loc:
  96. bm.verts.new(v_co)
  97. bm.verts.ensure_lookup_table()
  98. for f_idx in faces:
  99. bm.faces.new([bm.verts[i] for i in f_idx])
  100. bm.to_mesh(mesh)
  101. mesh.update()
  102. # add the mesh as an object into the scene with this utility module
  103. from bpy_extras import object_utils
  104. object_utils.object_data_add(context, mesh, operator=self)
  105. return {'FINISHED'}
  106. def menu_func(self, context):
  107. self.layout.operator(AddBox.bl_idname, icon='MESH_CUBE')
  108. def register():
  109. bpy.utils.register_class(AddBox)
  110. bpy.types.VIEW3D_MT_mesh_add.append(menu_func)
  111. def unregister():
  112. bpy.utils.unregister_class(AddBox)
  113. bpy.types.VIEW3D_MT_mesh_add.remove(menu_func)
  114. if __name__ == "__main__":
  115. register()
  116. # test call
  117. bpy.ops.mesh.primitive_box_add()