Class: Mesh I¶
Objectives¶
In an object-oriented world, parts of the model are mapped into classes. This has many advantages and the most important rules are shown here. Here is a complex example of how to create a basic shape, which does not exist in Blender. It is a pyramid. |
Instructions¶
Tasks: |
---|
- Repeat the sub-steps shown here to create a class until you have a working version.
- Create a class of its own »primitive«, eg. a wedge or the base form of a hex key.
- Add a material to the class, which is given to the new object.
Design data for a mesh¶
We start with the ground of a pyramid. The first step is defining the vertices an there location in a 3D scene. After that, then for each area, the index values of each surface section summarizes (a face is defined). The latter determines whether an area is closed or remains open, if it is not defined.
def pyramid_values():
"""
This function takes inputs and returns vertex and face arrays.
no actual mesh data creation is done here.
"""
verts = [(-1, +1, 0),
(+1, +1, 0),
(+1, -1, 0),
(-1, -1, 0)]
faces = [(0, 1, 2, 3),]
return verts, faces
The coordinates of each point are given by the focus of our future pyramid. The whole thing still possible in a clockwise sense.
Todo
Picture with coordinats
Class: AddPyramid¶
After the keyword class follows a self-selected class name AddPyramid.
As in the example with the simple class, our class inherits from a class in Blender: bpy.types.Operator. We need tree variable, for the correkt integration of our new class into Blender, its menues or lists for selection.
class AddPyramid(bpy.types.Operator):
"""Add a simple pyramid mesh"""
bl_idname = "mesh.primitive_pyramid_add"
bl_label = "Add Pyramid"
bl_options = {'REGISTER', 'UNDO'}
Properties¶
Also tree parameters are nessesary to place a new pyramid in a 3D-World.
"""Add a simple pyramid mesh"""
bl_idname = "mesh.primitive_pyramid_add"
bl_label = "Add Pyramid"
bl_options = {'REGISTER', 'UNDO'}
Method: execute¶
The methode execute is using the coordintate given by the function pyramid_values(). The values are transfered to locale variables: verts_loc and faces.
Now two new objects are created mit the operator new().
- one Mesh for the coordinates
- one bmesh for ...
Todo
bmash description
def execute(self, context):
verts_loc, faces = pyramid_values()
mesh = bpy.data.meshes.new("Pyramid")
bm = bmesh.new()
Coordinates second part¶
With two for loops the coordintes are added to the new objects.
for v_co in verts_loc:
bm.verts.new(v_co)
for f_idx in faces:
bm.faces.new([bm.verts[i] for i in f_idx])
Create objects¶
Afte the preparation, a new object can be created and placed on a given location.
bm.to_mesh(mesh)
mesh.update()
self.location = (0, 0, 0)
Display the object¶
With object_utils the object gets visible in a szene. If all works fine, the return value {‘FINISHED’} is given back.
# set the new object into the szene
from bpy_extras import object_utils
object_utils.object_data_add(context, mesh, operator=self)
return {'FINISHED'}
Register/Unregister¶
Blender needs a registration and unregristreation command for the new class.
def register():
bpy.utils.register_class(AddPyramid)
def unregister():
bpy.utils.unregister_class(AddPyramid)
Test run¶
Lets test the creation of a new pyramid, so far we only have the base.
if __name__ == "__main__":
register()
# create a instanz of a pyramid
bpy.ops.mesh.primitive_pyramid_add()
With the next step, we will finish the pyramid.
The code for the class¶
import bpy
import bmesh
from bpy.props import BoolProperty, FloatVectorProperty
def pyramid_values():
"""
This function takes inputs and returns vertex and face arrays.
no actual mesh data creation is done here.
"""
verts = [(-1, +1, 0),
(+1, +1, 0),
(+1, -1, 0),
(-1, -1, 0)]
faces = [(0, 1, 2, 3), ]
return verts, faces
class AddPyramid(bpy.types.Operator):
"""Add a simple pyramid mesh"""
bl_idname = "mesh.primitive_pyramid_add"
bl_label = "Add Pyramid"
bl_options = {'REGISTER', 'UNDO'}
# generic transform props
view_align = BoolProperty(name="Align to View",
default=False)
location = FloatVectorProperty(name="Location",
subtype='TRANSLATION')
rotation = FloatVectorProperty(name="Rotation",
subtype='EULER')
def execute(self, context):
verts_loc, faces = pyramid_values()
mesh = bpy.data.meshes.new("Pyramid")
bm = bmesh.new()
for v_co in verts_loc:
bm.verts.new(v_co)
for f_idx in faces:
bm.faces.new([bm.verts[i] for i in f_idx])
bm.to_mesh(mesh)
mesh.update()
self.location = (0, 0, 0)
# set the new object into the szene
from bpy_extras import object_utils
object_utils.object_data_add(context, mesh, operator=self)
return {'FINISHED'}
def register():
bpy.utils.register_class(AddPyramid)
def unregister():
bpy.utils.unregister_class(AddPyramid)
if __name__ == "__main__":
register()
# create a instanz of a pyramid
bpy.ops.mesh.primitive_pyramid_add()