0
$\begingroup$

I have a blender simulation which uses Blender Render and Blender Game Engine. I execute the following script(Renderer.py) from a python file(simulation.py) using "./blender -b compress.blend --python Renderer.py" to run a simulation on my machine.

import bpy
import math as m
import random as rand
import divider as d
import COM
import vol

def del_existing():
    del_obj = [item.name for item in bpy.data.objects if item.type == "MESH" or "LAMP"]
    for obj in del_obj:
        bpy.data.objects[obj].select = True
    bpy.ops.object.delete()

def makeMaterial(name, diffuse, specular, alpha):
    mat = bpy.data.materials.new(name)
    mat.diffuse_color = diffuse
    mat.diffuse_shader = 'LAMBERT' 
    mat.diffuse_intensity = 1.0 
    mat.specular_color = specular
    mat.specular_shader = 'PHONG'
    mat.specular_intensity = 0.5
    mat.alpha = alpha
    mat.ambient = 1
    return mat

def setMaterial(ob, mat):
    me = ob.data
    me.materials.append(mat)

def add_lamp(lname,srctype,location):
    scene = bpy.context.scene
    newl = bpy.data.lamps.new(name=lname,type=srctype)
    objl = bpy.data.objects.new(name=lname, object_data = newl)
    scene.objects.link(objl)
    objl.location=location
    #print(list(bpy.data.objects))
    bpy.data.objects[lname].select = True
    bpy.data.objects["hemi"].data.energy = 0.9

def add_camera():
    cam = bpy.ops.object.camera_add(view_align=True, location=(0.0,34,8.0),rotation=(m.radians(80), 0.0, m.radians(180)))

def my_handler(scene):
    bpy.data.objects["Cube.001"].location.x += 0.2
    bpy.data.objects["Cube.002"].location.x += -0.2
    print(scene.objects.get("Cube.002").location)
    print(scene.objects["Cube.001"].location)

def create_some_object(ii,y_co,mass):
    if ii % 5 == 0:
        x_co = 8.1
        name =  "obj_torus"+str(ii)
        bpy.ops.mesh.primitive_torus_add(location = (x_co,y_co,2))
        selobj = bpy.context.active_object
        selobj.name = name
        selobj.game.mass = mass
        selobj.scale = (1.5,1.5,1.5)
    if ii % 5 == 1:
        x_co = 3.5
        name =  "obj_cube"+str(ii)
        bpy.ops.mesh.primitive_cube_add(location = (x_co,y_co,2))
        selobj = bpy.context.active_object
        selobj.name = name
        selobj.game.mass = mass
        selobj.scale = (2,2,2)
    if ii % 5 == 2:
        x_co =-1
        name =  "obj_cone"+str(ii)
        bpy.ops.mesh.primitive_cone_add(location = (x_co,y_co,2))
        selobj = bpy.context.active_object
        selobj.name = name
        selobj.game.mass = mass
        selobj.scale = (2,2,2)
    if ii % 5 == 3:
        x_co = -5.4
        name =  "obj_sphere"+str(ii)
        bpy.ops.mesh.primitive_uv_sphere_add(location = (x_co,y_co,2))
        selobj = bpy.context.active_object
        selobj.name = name
        selobj.game.mass = mass
        selobj.scale = (2,2,2)
    if ii % 5 == 4:
        x_co = -9.0
        name =  "obj_monkey"+str(ii)
        bpy.ops.mesh.primitive_monkey_add(location = (x_co,y_co,2))
        selobj = bpy.context.active_object
        selobj.name = name
        selobj.game.mass = mass
        selobj.scale = (1.2,1.2,1.2)

def create_logic_bricks():
    sensors = bpy.context.scene.objects['Cylinder'].game.sensors
    controllers = bpy.context.scene.objects['Cylinder'].game.controllers
    actuators = bpy.context.scene.objects['Cylinder'].game.actuators
    bpy.ops.logic.sensor_add(type='ALWAYS', object="Cylinder",name="sensor1")
    sensors['sensor1'].use_pulse_true_level = True
    bpy.ops.logic.controller_add(type='PYTHON',object="Cylinder",name="controller1")
    controllers['controller1'].text = bpy.data.texts['pistonMover.py']
    sensors['sensor1'].link(controllers['controller1'])
    bpy.ops.logic.actuator_add(type="GAME",object="Cylinder",name="actuator1")
    actuators['actuator1'].mode = "QUIT"
    controllers['controller1'].link(actuator = actuators['actuator1'])
    bpy.context.scene.game_settings.logic_step_max = 50
    bpy.context.scene.game_settings.physics_step_max = 50
    bpy.context.scene.game_settings.physics_step_sub = 5

def get_volume_params():
    positions = {}
    for item in bpy.data.objects:         
        if item.name == "Cube":
            positions['h1'] = item.location.z
        if item.name == "Cube.003":
            positions['h2'] = item.location.z
        if item.name == "Cube.002":
            positions['b1'] = item.location.x
        if item.name == "Cube.001":
            positions['b2'] = item.location.x
        if item.name == "Cube.004":
            positions['l1'] = item.location.y
        if item.name == "Cylinder":
            positions['l2'] = item.location.y
    return positions

if __name__ == "__main__":
    del_existing()
    plane_mat = makeMaterial('planemat', (0.7,0.7,0.7), (0.5,0.5,0), 1)
    plane_mat2 = makeMaterial('planemat2', (0.6,0.1,0.1), (0.5,0.5,0), 1)
    plane_mat3 = makeMaterial('planemat3', (0.0,0.5,0.0), (0.5,0.5,0), 1)
    plane_mat4 = makeMaterial('planemat4', (0.0,0.0,0.5), (0.5,0.5,0), 1)
    ''' Make a box for compression '''
    #BASE CUBE
    bpy.ops.mesh.primitive_cube_add(location = (0,18,-0.5))
    bpy.data.objects["Cube"].select = True
    selobj = bpy.context.active_object
    selobj.scale = (50,50,1)
    setMaterial(bpy.context.object, plane_mat)
    #COMPRESSION CHAMBER 1
    bpy.ops.mesh.primitive_cube_add(location = (-11.4,-18,0))
    bpy.data.objects["Cube.001"].select = True
    bpy.ops.transform.rotate(value=m.radians(90),axis=(0,1,0))
    bpy.ops.transform.resize(value=(0.5,28,5))
    bpy.ops.transform.translate(value=(0,28,5))
    setMaterial(bpy.context.object, plane_mat3)
    #COMPRESSION CHAMBER 2
    bpy.ops.mesh.primitive_cube_add(location = (11,-18,0))
    bpy.data.objects["Cube.002"].select = True
    bpy.ops.transform.rotate(value=m.radians(90),axis=(0,1,0))
    bpy.ops.transform.resize(value=(0.5,28,5))
    bpy.ops.transform.translate(value=(0,28,5))
    setMaterial(bpy.context.object, plane_mat4)
    #PLANE ON THE TOP
    bpy.ops.mesh.primitive_cube_add(location = (0,11,11.01))
    selobj = bpy.context.active_object
    selobj.scale = (11.5,28.5,0.5)
    blue = makeMaterial('transcube', (0.16,0.05,0.8), (0.5,0.5,0), 2)
    #setMaterial(bpy.context.object, blue)
    bpy.data.materials["transcube"].use_transparency = True
    bpy.data.materials["transcube"].transparency_method = 'RAYTRACE'
    #bpy.data.materials["transcube"].raytrace_transparency.ior = 1.5
    bpy.data.materials["transcube"].alpha = 0.2
    #Piston Frame
    bpy.ops.mesh.primitive_cube_add(location = (0,37.2,5))
    bpy.data.objects["Cube.004"].select = True
    bpy.ops.transform.rotate(value=m.radians(90),axis=(1,0,0))
    bpy.ops.transform.resize(value=(10.3,0.5,5))
    setMaterial(bpy.context.object, blue)
    #Piston Handle
    bpy.ops.mesh.primitive_cylinder_add(location = (0,47.7,5))
    bpy.data.objects['Cylinder'].select = True
    bpy.ops.transform.rotate(value=m.radians(90),axis=(1,0,0))
    bpy.ops.transform.resize(value=(1,9.8,1))
    #MAke the handle and plate one object i.e. Piston
    bpy.data.objects['Cube.004'].select = True
    bpy.data.objects['Cylinder'].select = True
    bpy.ops.object.join()
    #PLANE ON THE BACK
    bpy.ops.mesh.primitive_cube_add(location = (-18,-18,0))
    bpy.data.objects["Cube.004"].select = True
    bpy.ops.transform.rotate(value=m.radians(90),axis=(1,0,0))
    bpy.ops.transform.resize(value=(-11,4,5))
    bpy.ops.transform.translate(value=(18,-4,5))
    setMaterial(bpy.context.object, plane_mat2)
    bpy.data.objects["Cube.004"].select = False
    box_dim = []
    obj_list = []
    for item in bpy.data.objects:         
        if item.name.startswith('Cube') and item.name != 'Cube.004':
            temp_dict = {}
            temp_dict['x'] = item.location.x
            temp_dict['y'] = item.location.y
            temp_dict['z'] = item.location.z                        
            temp_dict['mass'] = item.game.mass
            temp_dict['name'] = item.name
            box_dim.append(temp_dict)
            obj_list.append(temp_dict)
    com = (COM.COM(box_dim))
    print("COM_before::"+str(com))
    obj_masses = d.divider(d.create_random_list(51))
    pos1 = 0
    pos2 = 0
    y_co1 = com['y'] - 4.3
    y_co2 = com['y'] + 4.3
    for ii in range(0,51):
        if ii % 2 == 0:
            try:
                create_some_object(ii,y_co1,obj_masses['list1'][pos1])
            except IndexError:
                pass
            pos1 += 1
        else:
            create_some_object(ii,y_co2,obj_masses['list2'][pos2])
            pos2 += 1
        if ii % 10 == 0 and ii!=0:
            y_co1 -= 4.3
            y_co2 += 4.3
    #bpy.ops.mesh.primitive_cube_add(location = (com['x'],com['y'],com['z']))
    add_lamp("hemi","HEMI", (0,0,6.9))
    add_camera()
    bpy.context.scene.use_gravity = False
    bpy.context.scene.frame_end = 150
    bpy.context.scene.render.engine ='BLENDER_GAME'
    itemtypes = ['Cube.001','Cube.002','Cube.003','Cube', 'Plane.001','Cube.004']
    for item in bpy.data.objects:
        if item.type == 'MESH' and item.name not in itemtypes:
            item.select = True
            bpy.data.objects[item.name].game.physics_type = 'RIGID_BODY'
            bpy.data.objects[item.name].game.use_actor = True
            bpy.data.objects[item.name].game.use_collision_bounds = True
            if (item.name).find("cone") >= 0:
                bpy.data.objects[item.name].game.collision_bounds_type = 'CONE'
            elif (item.name).find("cube") >= 0:
                bpy.data.objects[item.name].game.collision_bounds_type = 'BOX'
            elif (item.name).find("sphere") >= 0:
                bpy.data.objects[item.name].game.collision_bounds_type = 'SPHERE'
            else:
                bpy.data.objects[item.name].game.collision_bounds_type = 'CONVEX_HULL'
        item.select = False
        if item.name.startswith('obj_'):
            temp_dict = {}
            temp_dict['x'] = item.location.x
            temp_dict['y'] = item.location.y
            temp_dict['z'] = item.location.z                        
            temp_dict['mass'] = item.game.mass
            temp_dict['name'] = item.name
            obj_list.append(temp_dict)  
    bpy.data.objects['Cube.004'].select = True
    bpy.data.objects['Cube.004'].game.mass = 500
    bpy.data.objects['Cube.004'].select = False
    bpy.data.objects['Cylinder'].select = True
    bpy.data.objects['Cylinder'].game.mass = 150
    bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')
    com_with_obj = (COM.COM(obj_list))
    positions = get_volume_params()
    print(positions)
    print("VOL_before "+str(vol.volume(positions)))
    #print("COM_before "+str(com_with_obj))
    create_logic_bricks()
    bpy.context.scene.render.engine = 'BLENDER_GAME'
    bpy.ops.wm.blenderplayer_start()

This works fine on my machine and it gives me results correctly. I tried to run the same script over ssh on another machine and it works fine except the last line "bpy.ops.wm.blenderplayer_start()". The blender player is not starting and I do not get the results from this part of simulation.

I have looked at the answer for the question Blender via ssh? but it did not help to answer my question.
My question is, why does my script stop only at the last line. Does is have to anything with X11 or the way I am invoking the blender player?

I have also checked whether service X is running on remote machine and configured the /etc/ssh/sshd_config to forwardx11trusted yes. All I want to do is to run blender animation of remote machine and capture the text results given by my script( just the way I am doing on my local machine). I am planning to do this to see if there will be any improvement in the performance of the simulation when I run on a machine with multiple cores. Can someone throw some light on this please. Thanks in advance.

$\endgroup$
  • $\begingroup$ This is less an BGE more a Blender thing. I can only guess that the blenderplayer needs a canvas to render to. A text terminal does not sound sufficient. $\endgroup$ – Monster Oct 13 '15 at 5:23
  • 1
    $\begingroup$ Don't think this as a blender problem. Check that you can start any gui app remotely, even start blender remotely without the script. With ssh you need to enable X11Forwarding, ssh -X the forwardX11trusted -Y option then allows X11 forwarding to bypassing security controls. Search for general X11 forwarding over ssh how-to's. $\endgroup$ – sambler Oct 13 '15 at 16:27
  • $\begingroup$ Thank you sambler. Using -X in my case helped resolving the issue. $\endgroup$ – St1id3r Oct 13 '15 at 18:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.