Featured post

new redirect for blender.org bpy docs.

http://www.blender.org/api/blender_python_api_current/ As of 10/11 november 2015 we can now link to the current api docs and not be worr...

March 20, 2012

importing .obj

The separator used here is '\\', but this varies from OS to OS. Python has a module called os to take some of the headache away. The above code allows you to do this stuff manually, research and experiment with the os module, it's great to understand how it works.

You could write a plugin using the directory selector built into Blender, so that you can navigate to a directory and obtain the string full_path_to_directory that way, but that's a different topic.

Blog reader pmpfx wondered how this syntax was glued together, so I think the above should clarify the path issues. The following snippet uses the os module to list the content of a directory. It will gather all files that are .obj and import them. No error checking is done, the path has to be valid. Conveniently the os module provides ways to check if a path is valid, read the docs. Here's a description of how to sanitize a blend

15 comments:

  1. Wow! Who would have thought that you needed double backslashes to accomplish this. Besides you, of course. Thanks! I've been scratching my head over this for days. Why the 'unique' coding? I do a little bit of programming and I have this is a first for me. Again, thanks for your (extremely prompt) insight. - pmpfx

    ReplyDelete
    Replies
    1. My pleasure, it's a mistake you won't likely make again :)

      Delete
    2. But just to clarify, they aren't double slashes to the OS. The first slash is an escape code.

      Delete
  2. After playing with it a bit I realize that it needs the escape code to properly format the file path with the embedded backslashes. I'm not an accomplished enough programmer to have caught this going in, but in hindsight it makes a bit of sense now that you have explained it. And there are so many new mistakes to make, I'm glad to have this one behind me. Thanks again:)

    ReplyDelete
  3. Thanks again for your insight into importing obj files. The resulting script is working well except for one small caveat, which I am hoping you have a solution/workaround for.

    The task is this: 1) generate a series of 10000 obj files. 2) import the first obj into an existing blender scene. 3) transform obj mesh and render said scene. 4) delete imported obj mesh 5) import next obj. 6) goto #3

    It works great, except for one small thing. The obj file is imported, scaled, positioned, rendered and deleted all with no issues whatsoever. The problem is that there seems to be an increasing memory overhead which ultimately leads to the script, and Blender, failing. A restart solves the problem and I can resume where the last one ended/failed. It seems like it may be the escalating overhead of multiple undo's. Or it is not really deleting the mesh created by the obj import but just moving it to another part of memory?!?

    Is there a way to remove the imported obj mesh completely with no system overhead that ultimately leads to failure?

    Thanks :)

    ReplyDelete
    Replies
    1. 10K objects isn't an entirely trivial thing to manage, especially if you consider the sum of the combined vertex/polygon count per object. Without seeing the script i'll take a stab in the dark. Experiment!

      1)
      Use the user preference tab to see if dropping down the undo levels to some low number makes a difference. If it does, find the corresponding bpy interface to push that to the app (ie. find current level and restore to that level when the script is finished)

      2)
      Failing that, write a modified version of the script that does the import/transforms etc, including the undo level stuff (it probably won't hurt to use that idea anyway) - Now apply your current 'delete' code, and check in the outliner for evidence that they aren't removed.

      Delete
    2. I'll write a short post about 'sanitizing' a blend file, so i can use decent syntax highlighting. http://blenderscripting.blogspot.com/2012/03/deleting-objects-from-scene.html

      Delete
  4. Thanks for the post, it was useful to me.

    For the record, using os.path is pointless if you're starting your path with 'c:\\' :-)

    In modern OSes, it's safe to just always use / in python; when operating in Windows (the only supported OS that uses \), python will automatically do the translation. I'm not sure that applies in this case; though; it does if the importer uses python library functions to open the file, but not if it passes the path unmodified to native code. I'm pretty sure it uses python, though.

    ReplyDelete
    Replies
    1. I'm not sure I follow what you mean. Perhaps respond with a link to a short gist or pastebin with how you think the code can be structured more correctly. But i agree doing a join onto c:\\ looks a little silly.

      Delete
  5. Thank you very much for this post.

    I spent quite some time googling and finally found your post. A working answer at last - all the other stuff I found was quite outdated or used some custom written OBJ importers.

    Cheers,
    Chris

    ReplyDelete
    Replies
    1. You're welcome, it was fun to figure out.

      Delete
  6. Hello,

    Thanks a lot for all your tutorials, I've been reading through a lot of them since some time. I would now like to import a 3D model into a scene via Python scripting. i can use blend or obj files, whatever.
    Using bpy.ops.import_scene.obj(filepath=full_path_to_file) actually puts the object into the scene, for which I cannot modify the name or location. I would like to put several objects from a same mesh into the scene (several ojbects with the same geometry), so I would like to be able to set their names, locations and so on. The ideal thing for me would be to be able to extract the mesh from the imported ".obj" file to then use the line object = bpy.data.objects.new(box_name, primitive_mesh), unfortunately I cannot access any of its properties (no suggestions from autocompletion). Do you have any idea on how to proceed ?

    Thaks in advance,

    Jonathan

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. '''
      import it once, then hide the object, then find the name of the mesh associated with the obj by doing
      '''
      objects = bpy.data.objects
      mesh_name = objects['your_object_name'].data.name

      # you can then use the mesh over and over in new objects
      mesh_reference = bpy.data.meshes[mesh_name]
      new_object = objects.new('some_new_object_name', mesh_reference)

      scene = bpy.context.scene
      scene.objects.link(new_object)

      Delete
    3. failing that, ask on BlenderStackexchange it's an awesome resource.

      Delete

Please use Blender.StackExchange.com for python scripting questions unrelated to this post.