version for blender 2.55
authorStefan Huber <shuber2@gmail.com>
Fri, 11 Feb 2011 15:21:55 +0000 (16:21 +0100)
committerStefan Huber <shuber2@gmail.com>
Fri, 11 Feb 2011 15:21:55 +0000 (16:21 +0100)
io_import_off.py [new file with mode: 0644]

diff --git a/io_import_off.py b/io_import_off.py
new file mode 100644 (file)
index 0000000..a1ab4b5
--- /dev/null
@@ -0,0 +1,230 @@
+# io_import_off.py Stefan Huber\r
+#\r
+# Import DEC Object File Format (*.off)\r
+\r
+\r
+bl_addon_info = {\r
+               "name": "Import DEC Object File Format (.off)",\r
+               "author": "Stefan Huber (shuber)",\r
+               "version": (0,7),\r
+               "blender": (2, 5, 3),\r
+               "api": 31667,\r
+               "location": "File > Import > Import DEC Object File Format (.off)",\r
+               "description": "Import DEC Object File Format (.off) files",\r
+               "warning": "",\r
+               "category": "Import/Export"\r
+               }\r
+\r
+\r
+\r
+__author__ = "Stefan Huber"\r
+#__url__ = ("blender", "blenderartists.org", "Author's homepage, http://www.redrival.com/scorpius")\r
+#__version__ = "Part of IOSuite 0.5"\r
+\r
+__bpydoc__ = """\\r
+This script imports DEC Object File Format files to Blender.\r
+\r
+The DEC (Digital Equipment Corporation) OFF format is very old and\r
+almost identical to Wavefront's OBJ. I wrote this so I could get my huge\r
+meshes into Moonlight Atelier. (DXF can also be used but the file size\r
+is five times larger than OFF!) Blender/Moonlight users might find this\r
+script to be very useful.\r
+\r
+Usage:<br>\r
+       Execute this script from the "File->Import" menu and choose an OFF file to\r
+open.\r
+\r
+Notes:<br>\r
+   Port to blender 2.5 beta 2. - shuber\r
+       UV Coordinate support has been added. - Scorpius\r
+       FGON support has been added. - Cam\r
+       New Mesh module now used. - Cam\r
+"""\r
+\r
+import bpy\r
+from bpy.props import *\r
+\r
+\r
+\r
+def isComment(line):\r
+       """Is this line a comment line?"""\r
+       line = line.strip()\r
+       if len(line) == 0:\r
+               return False\r
+       if line[0] == "#":\r
+               return True\r
+       return False\r
+\r
+\r
+def getNextLine(f):\r
+       """Read next line from file 'f' and ignore comments"""\r
+       line = f.readline().strip()\r
+       while isComment(line):\r
+               line = f.readline().strip()\r
+       return line\r
+\r
+\r
+\r
+def unpack_vertices( vertices ):\r
+       l = []\r
+       for t in vertices:\r
+               l.extend(t)\r
+       return l\r
+\r
+\r
+def unpack_faces(faces):\r
+\r
+       l = []\r
+       for face in faces:\r
+\r
+               # Build triangle fans\r
+               for k in range(1, len(face)-1):\r
+\r
+                       tri = [face[0], face[k], face[k+1]]\r
+\r
+                       # Rotate triangle, such that last index is not zero\r
+                       if tri[2] == 0:\r
+                               tri = [ tri[2], tri[0], tri[1] ]\r
+                       \r
+                       l.extend(tri)\r
+                       l.extend([0])\r
+\r
+       return l\r
+\r
+\r
+def importFile(filepath, context):\r
+\r
+       # List of vertices, a vertex is a 3-tuple (x,y,z)\r
+       vertices = [] \r
+       # List of faces, a face is a list of indices within vertices\r
+       faces = []\r
+\r
+       try:\r
+\r
+               f = open(filepath, "r")\r
+\r
+               # Get the header line\r
+               line = getNextLine(f)\r
+               if line != "OFF":\r
+                       print("Error: header line does not start with 'OFF'.")\r
+                       print(line)\r
+                       return False\r
+\r
+               #Get number of vertices, faces and edges\r
+               line = getNextLine(f).split()\r
+               if len(line) < 2:\r
+                       print("Error: Line of number of vertices, faces and edges is invalid.")\r
+                       return False\r
+               [numVertices, numFaces] = map(int, line[0:2])\r
+\r
+               if numVertices < 0:\r
+                       print("Error: Number of vertices is negative!")\r
+                       return False\r
+               if numFaces < 0:\r
+                       print("Error: Number of faces is negative!")\r
+                       return False\r
+\r
+               # Get all vertices\r
+               for n in range(numVertices):\r
+                       line = getNextLine(f).split()\r
+                       if len(line) < 3:\r
+                               print("Error: to few coordinates for vertex", n)\r
+\r
+                       # Add the vertex\r
+                       vertices += [ list(map(float, line[0:3])) ]\r
+\r
+               # Get all faces\r
+               for n in range(numFaces):\r
+                       line = getNextLine(f).split()\r
+                       \r
+                       # Get number of vertices\r
+                       lenFace = int(line[0])\r
+                       line = line[1:]\r
+                       if len(line) < lenFace:\r
+                               print("Error: to few vertices for face", n)\r
+\r
+                       # Add the face\r
+                       faces += [ list(map(int, line[0:lenFace])) ]\r
+\r
+               print("Finish reading file. Got %d vertices, %d faces." % \\r
+                               (len(vertices), len(faces)) )\r
+\r
+               # Add a mesh\r
+               me = bpy.data.meshes.new("Mesh")\r
+\r
+               vertexdata = unpack_vertices(vertices)\r
+               facedata = unpack_faces(faces)\r
+\r
+               # Add given number of vertices and faces\r
+               me.vertices.add( len(vertexdata)//3 )\r
+               me.faces.add( len(facedata)//4 )\r
+               me.vertices.foreach_set("co", vertexdata)\r
+               me.faces.foreach_set("vertices_raw", facedata)\r
+               me.update()\r
+\r
+               ob = bpy.data.objects.new("Mesh", me)\r
+               ob.data = me\r
+               scene = context.scene\r
+\r
+               scene.objects.link(ob)\r
+               scene.objects.active = ob\r
+\r
+       except Exception as e:\r
+               print("Error reading .off file")\r
+               print(e)\r
+               return False\r
+       \r
+\r
+\r
+class ImportOffFile(bpy.types.Operator):\r
+       '''Import DEC object file format (.off) files as specified by\r
+http://shape.cs.princeton.edu/benchmark/documentation/off_format.html'''\r
+\r
+       bl_idname = "import.off_files"\r
+       bl_label = "Import DEC Object File Format (.off)"\r
+       bl_description = "Imports DEC object file format (.off)"\r
+       bl_options = {'REGISTER'}\r
+\r
+       filepath = StringProperty(name="File Path",\r
+                       description="Filepath used for importing the file",\r
+                       maxlen=1024,\r
+                       default="" )\r
+\r
+       extEnum = [\r
+                       ('*', 'All image formats', 'Import all know image (or movie) formats.'),\r
+                       ('off', 'OFF (.off)', 'Object File Format') ]\r
+\r
+       extension = EnumProperty(name="Extension",\r
+                       description="Only import files of this type.",\r
+                       items=extEnum )\r
+\r
+       def execute(self, context):\r
+\r
+               # File Path\r
+               filepath = self.properties.filepath\r
+               # Call Main Function\r
+               importFile(filepath, context)\r
+\r
+               return {'FINISHED'}\r
+\r
+       def invoke(self, context, event):\r
+               wm = bpy.context.window_manager\r
+               wm.add_fileselect(self)\r
+\r
+               return {'RUNNING_MODAL'}\r
+\r
+\r
+# Registering / Unregister\r
+def menu_func(self, context):\r
+       self.layout.operator(ImportOffFile.bl_idname, \\r
+                       text="DEC Object File Format (.off)", icon='PLUGIN')\r
+\r
+def register():\r
+       bpy.types.INFO_MT_file_import.append(menu_func)\r
+\r
+def unregister():\r
+       bpy.types.INFO_MT_file_import.remove(menu_func)\r
+\r
+\r
+if __name__ == "__main__":\r
+       register()\r