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