The Cube.xxx is the name of the Cube Mesh (Mesh is a type of Blender Data Object which holds 3D data)
In the Python Interactive Console, access the Cube Object by indexing its name into bpy.data.objects
In the Console, change the name of Cube
Cube can no longer be accessed from bpy.data.objects, instead use Box
Manipulating Cube
mesh = bpy.data.objects['Box'].data or mesh = bpy.data.meshes['Cube.005']
mesh.vertices[0].co to get the coordinates of the 0th vertex
mesh.vertices[0].co = (5, 1, -1) to change the coordinate
Text Editor
Click New to create a new Python script
Can load existing script with Open
If you change the original script, loaded script will not update realtime
Instead Blender will prompt you to quick reload to sync with your original script
When you save the .blend file, Blender will save a copy of the script at the time
importbpybpy.ops.mesh.primitive_cube_add()
Run script
Errors and print statements from the Text Editor will be logged to the Console Window
Making a House
Every "action" in Blender is an operator call, and they poll to determine what mode they're in
Some only work in Edit Mode and others in Object Mode
Example: Extrude only works in Edit Mode and the API call will throw an exception if not in Edit mode
You need to have a new cube created and selected (this code turns a new cube into a house)
importbpy#Import Blender bpy moduleimportbmesh#Import Blender bmesh module for selecting verticies#Expects a cube created around the center (0,0,0) and selected#Scale body of the housebpy.ops.object.mode_set(mode="EDIT") #Change into edit modebpy.ops.transform.resize(value=(1,2,1)) #Scale up in the Y direction onlybpy.ops.mesh.select_all(action="DESELECT") #Deselect all vertices#Select the top vertices#In this case, the top vertices should have z coordinates greater than 0#Use bmesh, another Blender module, to assign the vertex selection to True#We select the face, and not the verticies because in the UI,# the face is autoselected all of its verticies are selectedmesh=bmesh.from_edit_mesh(bpy.context.object.data) #Need to load in context for bmeshmesh.faces.ensure_lookup_table() #Might be 2.74+ specificforfaceinmesh.faces:
vertices=face.vertsall_above_zero=True#Only select the face if all its vertices have z > 0forvertinvertices:
x,y,z=vert.coifz<=0:
all_above_zero=Falseifall_above_zero:
face.select=True#Extrude twice in the Z directionbpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0,0,0.3)})
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0,0,0.3)})
#Scale down roof top, the selected vertices, in the X directionbpy.ops.transform.resize(value=(0.3,1,1)) #Scale down only in Xbpy.ops.mesh.select_all(action="DESELECT") #Deselect all verticies#Select all the faces associated with the roof#Same as select roof top, except set a higher cutoff than 0mesh=bmesh.from_edit_mesh(bpy.context.object.data)
mesh.faces.ensure_lookup_table()
forfaceinmesh.faces:
vertices=face.vertsall_above=Trueforvertinvertices:
x,y,z=vert.coifz<=1.2:
all_above=Falseifall_above:
face.select=True#Scale up roofbpy.ops.transform.resize(value=(1.3,1.2,1)) #Scale up in the X and Y direction#Move roof downbpy.ops.transform.translate(value=(0,0,-0.3)) #Translate in the Z direction#Deselect and return to object modebpy.ops.mesh.select_all(action="DESELECT")
bpy.ops.object.mode_set(mode="OBJECT")
Run the above script will turn a cube into a house
Final Code
Refactored so it looks a bit nicer
You still need to have a new cube created and selected (this code turns a new cube into a house)
This follow is the above script turned into an Add-On
Still need to create a new cube and select it before running the Add-On
importbpyimportbmeshbl_info= {
"name": "Turn Cube into House",
"category": "OBJECT",
}
#Subclass Operator to create your own operator (bpy.ops....)#First comment inside the operator will be the tool tip description#bl_idname is determines how the operator is invokedclassTurnCubeIntoHouse(bpy.types.Operator):
"""Turn a Cube centered around (0,0,0) into a house"""bl_idname="object.turn_cube_into_house"bl_label="Turn Cube Into House"bl_options= {"REGISTER", "UNDO"}
#execute is what happens this operator is calleddefexecute(self, context):
#for simplicity, not going to pass context into the other methods#the other methods should act on the given context, instead of#fetching the context themselvesself.scale_body()
self.select_above(0)
self.extrude_twice()
self.scale_down_roof_top()
self.select_above(1.2)
self.scale_up_roof()
self.translate_roof()
self.deselect_and_cleanup()
#Need to return finishedreturn {"FINISHED"}
defscale_body(self):
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.transform.resize(value=(1,2,1))
bpy.ops.mesh.select_all(action="DESELECT")
defselect_above(self, value):
mesh=bmesh.from_edit_mesh(bpy.context.object.data)
mesh.faces.ensure_lookup_table()
forfaceinmesh.faces:
vertices=face.vertsall_above_value=Trueforvertinvertices:
x,y,z=vert.coifz<=value:
all_above_value=Falseifall_above_value:
face.select=Truedefextrude_twice(self):
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0,0,0.3)})
bpy.ops.mesh.extrude_region_move(TRANSFORM_OT_translate={"value":(0,0,0.3)})
defscale_down_roof_top(self):
bpy.ops.transform.resize(value=(0.3,1,1))
bpy.ops.mesh.select_all(action="DESELECT")
defscale_up_roof(self):
bpy.ops.transform.resize(value=(1.3,1.2,1))
deftranslate_roof(self):
bpy.ops.transform.translate(value=(0,0,-0.3))
defdeselect_and_cleanup(self):
bpy.ops.mesh.select_all(action="DESELECT")
bpy.ops.object.mode_set(mode="OBJECT")
defregister():
bpy.utils.register_class(TurnCubeIntoHouse)
defunregister():
bpy.utils.unregister_class(TurnCubeIntoHouse)
if__name__=="__main__":
register()
Execute the script from the Text Editor
Nothing visually will change
However, press Spacebar and type Turn Cube into House will find the newly registered Operator
Clicking on Turn Cube into House will turn cube into house
If you make changes to the Add-On, you need to unregister and then register again, in the same session