0
$\begingroup$

I am totally a newbie to Blender and python scripting in Blender.

What I am trying to do is write a script for one of my models in the Crate.blend file in the scene to extract its vertices and face information and printing it to the console

I use the Blender text editor to write a simple script like below and run the script. This runs fine on the console

import bpy
for item in bpy.data.objects:  

    if item.name == 'Crate':
        if item.type == 'MESH':
            for face in item.data.polygons:
                verts_in_face = face.vertices[:]
                print("face index ", face.index)
                print("normal ", face.normal)
                for vert in verts_in_face:
                    print("vertex coords ", item.data.vertices[vert].co)

What I want is to execute this script when I type the following line in the console

blender --background crate.blend --python export-model.py -- Crate

How do I go about achieving this? I think I might need to create an exporter script for the same? I found a promising post for creating an exporter script here

I will paste the script just in case

# Required Blender information.
bl_info = {
           "name": "My Exporter",
           "author": "",
           "version": (1, 0),
           "blender": (2, 65, 0),
           "location": "File > Export > Test (.tst)",
           "description": "",
           "warning": "",
           "wiki_url": "",
           "tracker_url": "",
           "category": "Import-Export"
          }

# Import the Blender required namespaces.
import sys, getopt

import bpy
from bpy_extras.io_utils import ExportHelper



# The main exporter class.
class MyExporter(bpy.types.Operator, ExportHelper):
   bl_idname       = "export_scene.my_exporter";
   bl_label        = "My Exporter";
   bl_options      = {'PRESET'};

   filename_ext    = ".tst";

   object_count    = 0;

   def __init__(self):
      pass

   def execute(self, context):
      print("Execute was called.");

      self.parse_command_line_options();

      if (self.filepath == ""):
         print("No sutable filename was provided to save to.");
         return {'FINISHED'};

      # Get all the mesh objects in the scene.
      objList = [object for object in bpy.context.scene.objects if object.type == 'MESH'];

      # Now process all the objects that we found.
      for gameObject in objList:
         self.export_object(gameObject);

      # Parse all the objects in the scene.
      return {'FINISHED'};


   def export_object(self, gameObject):
      if (gameObject.type != "MESH"):
         print("Object was not of type mesh.");
      else:
         self.object_count += 1;

      return;


   def parse_command_line_options(self):
      modelFile = "";
      myArgs = [];
      argsStartPos = 0;

      if (("--" in sys.argv) == False):
         return;

      argsStartPos = sys.argv.index("--");
      argsStartPos += 1;
      myArgs = sys.argv[argsStartPos:];

      try:
         opts, args = getopt.getopt(myArgs, 'hm:', ["help", "model-file="]);
      except getOpt.GetoptError:
         print("Opt Error.");
         return;

      for opt, arg in opts:
         if (opt in ("-h", "--help")):
            print("Run this as the following blender command.");
            print("\tblender <blend file> --background --python <script file> -- -m <output file>");
         elif (opt in ("-m", "--model-file")):
            modelFile = arg;

      if (modelFile != ""):
         self.filepath = modelFile;



# Define a function to create the menu option for exporting.
def create_menu(self, context):
   self.layout.operator(MyExporter.bl_idname,text="test (.tst)");

# Define the Blender required registration functions.
def register():
   """
   Handles the registration of the Blender Addon.
   """
   bpy.utils.register_module(__name__);
   bpy.types.INFO_MT_file_export.append(create_menu);

def unregister():
   """
   Handles the unregistering of this Blender Addon.
   """
   bpy.utils.unregister_module(__name__);
   bpy.types.INFO_MT_file_export.remove(create_menu);


# Handle running the script from Blender's text editor.
if (__name__ == "__main__"):
   print("Registering.");
   register();

   print("Executing.");
   bpy.ops.export_scene.my_exporter();

I run this script inside Blender text editor and it compiles

Now when I try to run it on the command line with the below command

blender model.blend --background --python myexporter.py

it thrown exception on model.blend as "invalid syntax"

I am completely new to Blender and scripting with python so spare me if I am missing something here.

Thanks


After changing my script as suggested in the second post, I get the following error

enter image description here

My blender file name is "model.blend" and it throws the error as invalid syntax. What am I missing?

$\endgroup$
  • 1
    $\begingroup$ both scripts run fine, how are executing the command line ? do you have the script file with the blend file in the same directory ? and for how you implement your exporter change the exporter function body with your code and modify parse func $\endgroup$ – Chebhou Feb 23 '15 at 18:14
  • $\begingroup$ Yes I have them in the same directory. Does it have to be a specific directory or any directory is fine? I just created a directory under my documents and pasted all the files in there $\endgroup$ – Htlcs Feb 24 '15 at 4:24
  • $\begingroup$ Does it have to do something with running the right version of Blender and python? I am using Blender v2.72 $\endgroup$ – Htlcs Feb 24 '15 at 4:28
  • $\begingroup$ The console inside blender is a Python console - instead run blender model.blend --back... from your system console/terminal. $\endgroup$ – Greg Zaal Feb 24 '15 at 9:05
  • $\begingroup$ @Htlcs you have to add blender path to the 'PATH' system variable to be able to execute the command in any folder or use the method in the answer $\endgroup$ – Chebhou Feb 24 '15 at 12:24
1
$\begingroup$

this would work for a command line :

blender myfile.blend --background --python myexporter.py -- -m myobject

where :

blender <blender file>  --background  --python <script file> -- -m <object name>

i have removed 'Crate' you can set the name of the object in the command line ^ ,and removed the the file output since you are only printing to the console .

UPDATE:

as sambler noted you should be running this in a terminal, here is the steps "for windows":

  • copy the script in a new text file then rename it to exporter.py "be sure to change the extension from .txt to .py"
  • go to your blender installation folder "C:\Program Files\Blender Foundation\Blender"
  • put your .blend file and exporter.py in this folder
  • hit shift + right click to open a CMD in this folder
  • type the command as follows :

    blender model.blend --background --python exporter.py -- -m Crate

Note : you don't need to open blender for any of these steps 'nothing is done inside blender'

This is the script :

# Required Blender information.
bl_info = {
           "name": "My Exporter",
           "author": "",
           "version": (1, 0),
           "blender": (2, 65, 0),
           "location": "File > Export > Test (.tst)",
           "description": "",
           "warning": "",
           "wiki_url": "",
           "tracker_url": "",
           "category": "Import-Export"
          }

# Import the Blender required namespaces.
import sys, getopt

import bpy
from bpy_extras.io_utils import ExportHelper

# The main exporter class.
class MyExporter(bpy.types.Operator, ExportHelper):
   bl_idname       = "export_scene.my_exporter";
   bl_label        = "My Exporter";
   bl_options      = {'PRESET'};

   obj_name        = "";

   def __init__(self):
      pass

   def execute(self, context):
      print("Execute was called.");

      self.parse_command_line_options();

      if (self.obj_name == ""):
         print("No suitable object name was provided .");
         return {'FINISHED'};
      print("Executing......");
      # Now start exporting the target object.
      self.export_object(self.obj_name);
      # Parse all the objects in the scene.
      print("Finished");
      return {'FINISHED'};


   def export_object(self, obj_name):
       for item in bpy.data.objects:
           if item.name == obj_name and item.type == 'MESH' :
              for face in item.data.polygons:
                  verts_in_face = face.vertices[:]
                  print("face index ", face.index)
                  print("normal ", face.normal)
                  for vert in verts_in_face:
                  print("vertex coords ", item.data.vertices[vert].co)


   def parse_command_line_options(self):
      obj_name = "";
      myArgs = [];
      argsStartPos = 0;

      if (("--" in sys.argv) == False):
         return;

      argsStartPos = sys.argv.index("--");
      argsStartPos += 1;
      myArgs = sys.argv[argsStartPos:];

      try:
         opts, args = getopt.getopt(myArgs, 'hm:', ["help", "model-file="]);
      except getOpt.GetoptError:
         print("Opt Error.");
         return;

      for opt, arg in opts:
         if (opt in ("-h", "--help")):
            print("Run this as the following blender command.");
            print("\tblender <blend file> --background --python <script file> -- -m <Object name>");
         elif (opt == "-m"):
            obj_name = arg;

      if (obj_name != ""):
         self.obj_name = obj_name;
         print(obj_name);

# Define a function to create the menu option for exporting.
def create_menu(self, context):
   self.layout.operator(MyExporter.bl_idname,text="test (.tst)");

# Define the Blender required registration functions.
def register():
   """
   Handles the registration of the Blender Addon.
   """
   bpy.utils.register_module(__name__);
   bpy.types.INFO_MT_file_export.append(create_menu);

def unregister():
   """
   Handles the unregistering of this Blender Addon.
   """
   bpy.utils.unregister_module(__name__);
   bpy.types.INFO_MT_file_export.remove(create_menu);


# Handle running the script from Blender's text editor.
if (__name__ == "__main__"):
   print("Registering.");
   register();

   print("Executing.");
   bpy.ops.export_scene.my_exporter();
$\endgroup$
  • $\begingroup$ thanks a lot. I tried what you said. Pasted your script as it is, but I get the error in the image that I have attached in my first post. My blender file name is model.blend so I don't understand what the error means :( $\endgroup$ – Htlcs Feb 24 '15 at 4:21
  • $\begingroup$ @Htlcs you're welcome, are you using windows ? if so you should add the blender path to system variables so you can work on any folder $\endgroup$ – Chebhou Feb 24 '15 at 15:15
  • $\begingroup$ Yes I am running it on Windows 8. I would definitely do what you suggested. Thanks a lot mate! $\endgroup$ – Htlcs Feb 24 '15 at 15:50
  • $\begingroup$ I had a question. What do the register() modules do? Do I write it because I do not have blender path to system variables defined? I understand how the rest of the code works except the registration part. $\endgroup$ – Htlcs Feb 24 '15 at 16:02
  • $\begingroup$ @Htlcs the register adds the exporter to blender UI "File->Export->myExporter" and add it to the operators "bpy.ops.export_scene.my_exporter" so you don't need to run the script each time to use it you either use the menu or from python console type "bpy.ops.export_scene.my_exporter" $\endgroup$ – Chebhou Feb 24 '15 at 16:56
0
$\begingroup$

The final image shows you entering the command in blender's python console, which only understands python. The command you are typing is a shell command and it needs to be typed into a terminal emulator, sometimes called the CLI or Command Line Interface.

How to start the terminal emulator will depend on what OS you are using, this wikipedia page lists some terminal emulators for different platforms. Most systems will have one of them installed by default.

$\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.