5

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)?

David
  • 49,291
  • 38
  • 159
  • 317
bot4u
  • 323
  • 2
  • 9
  • 4
    Something like https://blenderartists.org/forum/showthread.php?210351-Mesh-to-script-helper ? – batFINGER Jul 01 '16 at 11:44
  • 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". – Mutant Bob Jul 01 '16 at 14:11
  • Why would you want it as a Python script? – doomslug Jul 01 '16 at 19:08
  • @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? – bot4u Jul 06 '16 at 02:12
  • @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. – bot4u Jul 06 '16 at 03:04
  • @VandanaIyer While exporting all the data to .py is impossible, you can still use a python file from outside Blender on many .blend files through the commandline arguments for Blender. Would that work? (I will make an answer if it would) – doomslug Jul 06 '16 at 03:13
  • @NathanCraddock, thank you, that would be helpful. After applying the changes, will we be able to combine the multiple .blend files into a single file? – bot4u Jul 06 '16 at 03:41
  • @VandanaIyer Okay. Just edit your question with more details about what exactly you are trying to do, and I will answer – doomslug Jul 06 '16 at 03:44
  • @NathanCraddock, thanks for the answer. I tried running python scripts externally on .blend files as mentioned in the answer and am afraid it does not seem to fit the current requirement of my project. Converting a .blend file to a .py is necessary as we intend to automate the entire process of applying different textures and materials on a mesh model based on a certain input from the user.
    Exporting the .blend to a .py file seems possible using the script shared by batFINGER
    – bot4u Jul 07 '16 at 20:29

3 Answers3

2

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
batFINGER
  • 84,216
  • 10
  • 108
  • 233
2

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.

doomslug
  • 1,809
  • 1
  • 18
  • 31
1

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.
bot4u
  • 323
  • 2
  • 9