2
$\begingroup$

I am using Blender 2.77. When we select File > Export from the menu, the default export options Blender gives are .3ds, .fbx, .bvh, .ply, .obj, .x3d/.wrl, .stl, .svg formats. Is there any add-on or any way that would help us export our model as a python file(.py)?

$\endgroup$
  • 4
    $\begingroup$ Something like blenderartists.org/forum/… ? $\endgroup$ – batFINGER Jul 1 '16 at 11:44
  • $\begingroup$ My first instinct is "no", but depending on how much detail you want, it wouldn't be terribly difficult. The main problem is "how much of the model do you want to export?" because mesh geometry is one thing. Being able to reconstruct all the modifiers and constraints and materials starts getting messy. When people want to share complicated blender things (spaghetti node materials) they often just share the blend and say "link/append this". $\endgroup$ – Mutant Bob Jul 1 '16 at 14:11
  • $\begingroup$ Why would you want it as a Python script? $\endgroup$ – Nathan Craddock Jul 1 '16 at 19:08
  • $\begingroup$ @batFINGER, thanks for the link. The script shared helps in generating a .py script from any given blend file. Since the data we feed is in the form of vertices and faces, if there are multiple mesh objects in the same blend file, how would we handle applying the transformations? $\endgroup$ – bot4u Jul 6 '16 at 2:12
  • $\begingroup$ @NathanCraddock, I want it as a python script because, I want to automate the process of combining different mesh objects, apply transformations, change colours/textures etc., given one/many blend files as input. I was hoping it would be easy to do this programatically if blender provided an option to export our 3D model as a python script that included step-by-step construction of the model in python. $\endgroup$ – bot4u Jul 6 '16 at 3:04
1
$\begingroup$

Update for 2.8

An update of Mesh to Script Helper

import bpy

ob = bpy.context.object
if ob and ob.type == "MESH":
    mesh = ob.data
    me = ob.data
    txt = bpy.data.texts.new("make_primitive.py")

    faces = ",\n         ".join(f'{p.vertices[:]}' for p in me.polygons)     
    verts = ",\n         ".join(f"{v.co[:]}"  for v in me.vertices)

    txt.write(f"""import bpy

verts = ({verts})

faces = ({faces})

scene = bpy.context.scene
me = bpy.data.meshes.new("{me.name}")
me.from_pydata(verts, [], faces)
ob = bpy.data.objects.new("{ob.name}", me)
scene.collection.objects.link(ob)
scene.view_layer.objects.active = ob""")

Result after running on default cube. Creates make_primitive.py in the textblock. Running the file recreates the primitive object.

import bpy

verts = ((-1.0, -1.0, -1.0),
         (-1.0, -1.0, 1.0),
         (-1.0, 1.0, -1.0),
         (-1.0, 1.0, 1.0),
         (1.0, -1.0, -1.0),
         (1.0, -1.0, 1.0),
         (1.0, 1.0, -1.0),
         (1.0, 1.0, 1.0))

faces = ((0, 1, 3, 2),
         (2, 3, 7, 6),
         (6, 7, 5, 4),
         (4, 5, 1, 0),
         (2, 6, 4, 0),
         (7, 3, 1, 5))

scene = bpy.context.scene
me = bpy.data.meshes.new("Cube")
me.from_pydata(verts, [], faces)
ob = bpy.data.objects.new("Cube", me)
scene.collection.objects.link(ob)
scene.view_layer.objects.active = ob
$\endgroup$
2
$\begingroup$

So exporting the .blend to a .py file is impossible (see here), but instead of exporting, you can run a python script on a .blend file externally through the command line.

For this example, lets assume we have a directory that contains a folder of 100 .blend files that each have an object located at the origin. For our needs, we would like to raise each object by one unit on the Z axis, and change it's name to the name of the .blend file. We will use a python script to modify these files.

project_files
|   edit_blends.py
|   modify.py
|
|___blend_files
    |   lid.blend
    |   cup.blend
    |   pencil.blend
    |   ...

In the edit_blends.py file, we have code that utilizes the Python library to iterate over each of the .blend files. (edit_blends.py) For each of the files, we use the subprocess module of Python to call Blender from the command line with certain arguments that will run our script (modify.py).

Here is edit_blends.py

import os
import subprocess

blend_files_path = 'blend_files'

for blend_file in os.listdir(blend_files_path):
    if blend_file.endswith('.blend'): # Exclude .blend1 .blend2 files
        file = os.path.join(blend_files_path, blend_file)
        # Run Blender in the background
        subprocess.run(['blender', '-b', file, '-P', 'modify.py'])

Here is modify.py. This file is what is run in the Blender process that is called.

import bpy

blend_file = bpy.data.filepath

for object in bpy.data.objects:
    object.location.z += 1

    object.name = bpy.path.display_name_from_filepath(blend_file)

# SAVE THE FILE
bpy.ops.wm.save_as_mainfile()

It is very important to save the file, otherwise all changes will be lost.

The line that calls Blender subprocess.run(['blender', '-b', file, '-P', 'modify.py']) runs Blender, with the arguments given in a list.

  • -b <.blend>: run the file in the background
  • -P <.py>: run the given Python file

For more information on the command line, read this. Of course, you can do almost anything to the .blend file externally through Python (some things are restricted like OpenGL renders because they require the GUI to be open)

If you are on Windows, you need to add Blender to the PATH or run the command with the path to Blender.

$\endgroup$
1
$\begingroup$

There are multiple answers to this thread. Collating them all.

Based on @batFINGER 's answer, this thread answers my question.

Since the intention was to have complete access to a .blend file and run custom scripts on it, the answer suggested by @Nathan Craddock works too. However, for the current use-case, we are not using Blender from commandline, since the operations performed using that is slower. So as a workaround, this is what was done:

  • Install blender as a python module. (This link has more details)
  • Write a python script to access the .blend file. This API call should do bpy.ops.wm.open_mainfile(filepath=path_to_blend_file) This call will give access to the entire data of the blend file and further manipulations on the data can be done in the python script. It is faster this way.
$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.