soc-2008-mxcurioni: merged changes to revision 14798, compilation works for rendering...
[blender-staging.git] / release / scripts / off_import.py
1 #!BPY
2
3 """
4 Name: 'DEC Object File Format (.off)...'
5 Blender: 242
6 Group: 'Import'
7 Tooltip: 'Import DEC Object File Format (*.off)'
8 """
9
10 __author__ = "Anthony D'Agostino (Scorpius), Campbell Barton (Ideasman)"
11 __url__ = ("blender", "elysiun",
12 "Author's homepage, http://www.redrival.com/scorpius")
13 __version__ = "Part of IOSuite 0.5"
14
15 __bpydoc__ = """\
16 This script imports DEC Object File Format files to Blender.
17
18 The DEC (Digital Equipment Corporation) OFF format is very old and
19 almost identical to Wavefront's OBJ. I wrote this so I could get my huge
20 meshes into Moonlight Atelier. (DXF can also be used but the file size
21 is five times larger than OFF!) Blender/Moonlight users might find this
22 script to be very useful.
23
24 Usage:<br>
25         Execute this script from the "File->Import" menu and choose an OFF file to
26 open.
27
28 Notes:<br>
29         UV Coordinate support has been added. - Scorpius
30         FGON support has been added. - Cam
31         New Mesh module now used. - Cam
32 """
33
34 # $Id:
35 #
36 # +---------------------------------------------------------+
37 # | Copyright (c) 2002 Anthony D'Agostino                   |
38 # | http://www.redrival.com/scorpius                        |
39 # | scorpius@netzero.com                                    |
40 # | February 3, 2001                                        |
41 # | Read and write Object File Format (*.off)               |
42 # +---------------------------------------------------------+
43
44 # ***** BEGIN GPL LICENSE BLOCK *****
45 #
46 # This program is free software; you can redistribute it and/or
47 # modify it under the terms of the GNU General Public License
48 # as published by the Free Software Foundation; either version 2
49 # of the License, or (at your option) any later version.
50 #
51 # This program is distributed in the hope that it will be useful,
52 # but WITHOUT ANY WARRANTY; without even the implied warranty of
53 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54 # GNU General Public License for more details.
55 #
56 # You should have received a copy of the GNU General Public License
57 # along with this program; if not, write to the Free Software Foundation,
58 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
59 #
60 # ***** END GPL LICENCE BLOCK *****
61
62 import Blender
63
64
65 # =============================
66 # ====== Read OFF Format ======
67 # =============================
68 def read(filename):
69         start = Blender.sys.time()
70         file = open(filename, "rb")
71
72         verts = [] # verts and uvs are aligned
73         uvs = []
74         
75         faces = []
76         
77         # === OFF Header ===
78         # Skip the comments
79         offheader= file.readline()
80         while offheader.startswith('#') or offheader.lower().startswith('off'):
81                 offheader = file.readline()
82         
83         numverts, numfaces, numedges= map(int, offheader.split())
84         if offheader.find('ST') >= 0:
85                 has_uv = True
86                 Vector= Mathutils.Vector
87         else:
88                 has_uv = False
89
90         # === Vertex List ===
91         for i in xrange(numverts):
92                 if has_uv:
93                         x, y, z, u, v = map(float, file.readline().split())
94                         uvs.append(Vector(u, v))
95                 else:
96                         x, y, z = map(float, file.readline().split())
97                 verts.append((x, y, z))
98
99         # === Face List ===
100         def fan_face(face):
101                 # 'Elp, Only fan fill- if were keen we could use our trusty BPyMesh.ngon function
102                 # So far I havnt seen any big ngons in on off file - Cam
103                 return [ (face[0], face[i-1], face[i]) for i in xrange(2,len(face))]
104         
105         for i in xrange(numfaces):
106                 line = file.readline().split() # ignore the first value, its just the face count but we can work that out anyway
107                 
108                 # appends all the indicies in reverse order except 0
109                 # xrange(len(line)-1, -1, -1) # normal reverse loop
110                 # xrange(len(line)-1, 0, -1) # ignoring index 0 because its only a count
111                 # face= [int(line[j]) for j in xrange(len(line)-1, 0, -1)]
112                 
113                 # Some OFF files have floats on the end of the face. what are these for?
114                 face= [int(line[j]) for j in xrange(int(line[0]), 0, -1)]
115                 
116                 
117                 if len(face)>4:
118                         faces.extend( fan_face(face) )
119                 else:
120                         faces.append(face)
121                         
122         scn= Blender.Scene.GetCurrent()
123         name= filename.split('/')[-1].split('\\')[-1].split('.')[0]
124         me= Blender.Mesh.New(name)
125         me.verts.extend(verts)
126         me.faces.extend(faces)
127         
128         # Now edges if we have them, render fgon
129         if numedges:
130                 FGON_FLAG= Blender.Mesh.EdgeFlags.FGON
131                         
132                 edge_dict= {}
133                 # Set all edges to be fgons by default
134                 for ed in me.edges:
135                         ed.flag |= FGON_FLAG
136                         edge_dict[ed.key]= ed
137                 
138                 # Now make known edges visible
139                 has_edges = True
140                 for i in xrange(numedges):
141                         try:
142                                 i1,i2= file.readline().split()
143                         except:
144                                 has_edges = False
145                                 break # some files dont define edges :/
146                         
147                         i1= int(i1)
148                         i2= int(i2)             
149                         if i1>i2:
150                                 i1,i2= i2,i1
151                         
152                         # We know this edge is seen so unset the fgon flag
153                         edge_dict[i1,i2].flag &= ~FGON_FLAG
154                 
155                 if not has_edges:
156                         # dang, we'v turned all the edges into fgons and then the file didnt define any edges.
157                         # oh well, just enable them all
158                         for ed in me.edges:
159                                 ed.flag &= ~FGON_FLAG
160         
161         # Assign uvs from vert index
162         if has_uv:
163                 for f in me.faces:
164                         f_uv= f.uv
165                         for i, v in enumerate(f): # same as f.v
166                                 f_uv[i]= uvs[v.index]
167         
168         for ob in scn.objects:
169                 ob.sel=0
170         
171         scn.objects.active = scn.objects.new(me, name)
172         Blender.Window.RedrawAll()
173         print 'Off "%s" imported in %.4f seconds.' % (name, Blender.sys.time()-start)
174         
175
176 if __name__=='__main__':
177         Blender.Window.FileSelector(read, 'Import OFF', '*.off')