dc-complex-piece

Übersicht: Python & Blender


Objectives

Creating new Objects is easy, afterwards we have to scale and move the pieces to a new location. How this can achieved is shown and explained in this station.

Instructions

Tasks:
  1. Move the pieces of the example to a different place.

  2. Join the pieces to a single one and name it »marsmobil«.

  3. Create the following object, shown in this picture:

    /blender-basics/d-composed-pieces/camera.png
  4. Create your own object.

Creating objects

The complete script, parts of the script are explained afterwards.

blender-basics/d-composed-pieces/mars-mobile.py (Source)

#!bpy
"""
Name: 'mars_mobile.py'
Blender: 2.7x
Group: 'Composition'
Tooltip: 'Rotate, locate and scale objects assembled to a futuristic car'
"""
import bpy


def create_objects():
    """Create objects from a list of attributes

    List values:

    object name   -- string
    object type   -- string
    location      -- tupel of integers
    """
    objectlist = [('cu1', 'cube', (-6, 1, 1)),
                  ('cu2', 'cube', (-3, 1, 1)),
                  ('cy1', 'cylinder', (0, 1, 1)),
                  ('cy2', 'cylinder', (3, 1, 1)),
                  ('uv1', 'uv_sphere', (6, 1, 1)),
                  ('uv2', 'uv_sphere', (9, 1, 1))]

    for element in objectlist:
        if element[1] == 'cube':
            bpy.ops.mesh.primitive_cube_add(location=element[2])
        if element[1] == 'cylinder':
            bpy.ops.mesh.primitive_cylinder_add(location=element[2])
        if element[1] == 'uv_sphere':
            bpy.ops.mesh.primitive_uv_sphere_add(location=element[2])
        # give it a name
        obj = bpy.context.object
        obj.name = element[0]


def select_cubes():
    """Sample: select two objects by name """

    bpy.ops.object.select_pattern(pattern="cu2")
    bpy.ops.object.select_pattern(pattern="cu1")


def activate_object():
    """Sample: activate an object by name"""

    bpy.context.scene.objects.active = bpy.data.objects["cu2"]


def scale_cu2():
    """Select, scale and move cube 2"""

    bpy.context.scene.objects.active = bpy.data.objects["cu2"]
    obj = bpy.context.scene.objects.active
    obj.scale = (1, 1, 3)
    obj.location = (-3, 1, 3)


def scale_cy():
    """Select cylinders, scale and move"""

    bpy.context.scene.objects.active = bpy.data.objects["cy1"]
    obj = bpy.context.scene.objects.active
    obj.scale = (1, 1, .2)
    obj.location = (0, 1, .2)

    bpy.context.scene.objects.active = bpy.data.objects["cy2"]
    obj = bpy.context.scene.objects.active
    obj.scale = (1, 1, .2)
    obj.location = (3, 1, .2)


def assemble_mars_mobile():
    """Create a composite piece """

    half_of_pi = 3.141592/2

    # body
    bpy.context.scene.objects.active = bpy.data.objects["cu2"]
    obj = bpy.context.scene.objects.active
    obj.location = (-3, 1, 1.5)
    # rotation
    obj.rotation_euler = [half_of_pi, 0, 0]

    # wheel (right)
    bpy.context.scene.objects.active = bpy.data.objects["cy1"]
    obj = bpy.context.scene.objects.active
    obj.location = (-4, 2, 1)
    obj.rotation_euler = [0, half_of_pi, 0]

    # wheel (left)
    bpy.context.scene.objects.active = bpy.data.objects["cy2"]
    obj = bpy.context.scene.objects.active
    obj.location = (-2, 2, 1)
    obj.rotation_euler = [0, half_of_pi, 0]

    # wheel (front)
    bpy.context.scene.objects.active = bpy.data.objects["uv1"]
    obj = bpy.context.scene.objects.active
    obj.location = (-3, -1, 1)

    # cabin
    bpy.context.scene.objects.active = bpy.data.objects["cu1"]
    obj = bpy.context.scene.objects.active
    obj.location = (-3, 2, 3)

    bpy.context.scene.objects.active = bpy.data.objects["uv2"]
    obj = bpy.context.scene.objects.active
    obj.location = (-3, 2, 4)


if __name__ == '__main__':
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')
    # delete all meshes from a szene
    bpy.ops.object.select_by_type(type='MESH')
    bpy.ops.object.delete()
    create_objects()
    ## comment and uncomment the lines as you like
    ## to call the functions...
    # select_cubes()
    # activate_object()
    # scale_cu2()
    # scale_cy()
    # assemble_mars_mobile()

How it works

Every function is solving a particular problem. You can test the different functions if you comment or uncomment the function calls at the end of the script.

The first step is creating all objects. It is important to name the objects.

/blender-basics/d-composed-pieces/all-pieces.png

You have to distinguish between selected objects an one active object. Many objects can be selected, but only one at the time can be the active one

/blender-basics/d-composed-pieces/active-object.png

How many objects are selected, is visible in the info window.

/blender-basics/d-composed-pieces/objectcount1.png

Select objects

blender-basics/d-composed-pieces/mars-mobile.py (Source)

def select_cubes():
    """Sample: select two objects by name """

    bpy.ops.object.select_pattern(pattern="cu2")
    bpy.ops.object.select_pattern(pattern="cu1")

Activate an object

Manipulations are only possible with the active object.

blender-basics/d-composed-pieces/mars-mobile.py (Source)

def activate_object():
    """Sample: activate an object by name"""

    bpy.context.scene.objects.active = bpy.data.objects["cu2"]

Scale objectes

Scaling an object is possible in tree dimensions. If no scaling should happened, the scaling factor is 1. In our example only the z-achs is scaled. Afterwards we move the center of the objects, therefore they are positioned on the ground again.

blender-basics/d-composed-pieces/mars-mobile.py (Source)

def scale_cu2():
    """Select, scale and move cube 2"""

    bpy.context.scene.objects.active = bpy.data.objects["cu2"]
    obj = bpy.context.scene.objects.active
    obj.scale = (1, 1, 3)
    obj.location = (-3, 1, 3)

Both cylinders are minimized.

blender-basics/d-composed-pieces/mars-mobile.py (Source)

def scale_cy():
    """Select cylinders, scale and move"""

    bpy.context.scene.objects.active = bpy.data.objects["cy1"]
    obj = bpy.context.scene.objects.active
    obj.scale = (1, 1, .2)
    obj.location = (0, 1, .2)

    bpy.context.scene.objects.active = bpy.data.objects["cy2"]
    obj = bpy.context.scene.objects.active
    obj.scale = (1, 1, .2)
    obj.location = (3, 1, .2)

Rotation with Euler

All objects are scaled and in the next step they can be assembled. Some parts have to be rotated. We calculate the value once:

half_of_pi = 3.141592/2

and use it as often as needed and half-of-pi. It is always a rotation of 90°.

obj.rotation_euler = [half_of_pi, 0, 0]

More about calculating a rotation is explained at Rotating an object

Now we have finished our prototype and the next car race at the mars can start :-)

/blender-basics/d-composed-pieces/mars-mobile.png

Comments