blender/release/scripts/off_import.py

178 lines
5.2 KiB
Python
Raw Normal View History

#!BPY
"""
Name: 'DEC Object File Format (.off)...'
Blender: 242
Group: 'Import'
Tooltip: 'Import DEC Object File Format (*.off)'
"""
__author__ = "Anthony D'Agostino (Scorpius), Campbell Barton (Ideasman)"
__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:<br>
Execute this script from the "File->Import" menu and choose an OFF file to
open.
Notes:<br>
UV Coordinate support has been added. - Scorpius
FGON support has been added. - Cam
New Mesh module now used. - Cam
"""
# $Id:
#
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
# | http://www.redrival.com/scorpius |
# | scorpius@netzero.com |
# | February 3, 2001 |
# | Read and write Object File Format (*.off) |
# +---------------------------------------------------------+
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
import Blender
# =============================
# ====== Read OFF Format ======
# =============================
def read(filename):
start = Blender.sys.time()
file = open(filename, "rb")
verts = [] # verts and uvs are aligned
uvs = []
faces = []
# === OFF Header ===
# Skip the comments
offheader= file.readline()
while offheader.startswith('#') or offheader.lower().startswith('off'):
offheader = file.readline()
numverts, numfaces, numedges= map(int, offheader.split())
if offheader.find('ST') >= 0:
has_uv = True
Vector= Mathutils.Vector
else:
has_uv = False
# === Vertex List ===
for i in xrange(numverts):
if has_uv:
x, y, z, u, v = map(float, file.readline().split())
uvs.append(Vector(u, v))
else:
x, y, z = map(float, file.readline().split())
verts.append((x, y, z))
# === Face List ===
def fan_face(face):
# 'Elp, Only fan fill- if were keen we could use our trusty BPyMesh.ngon function
# So far I havnt seen any big ngons in on off file - Cam
return [ (face[0], face[i-1], face[i]) for i in xrange(2,len(face))]
for i in xrange(numfaces):
line = file.readline().split() # ignore the first value, its just the face count but we can work that out anyway
# appends all the indicies in reverse order except 0
# xrange(len(line)-1, -1, -1) # normal reverse loop
# xrange(len(line)-1, 0, -1) # ignoring index 0 because its only a count
# face= [int(line[j]) for j in xrange(len(line)-1, 0, -1)]
# Some OFF files have floats on the end of the face. what are these for?
face= [int(line[j]) for j in xrange(int(line[0]), 0, -1)]
if len(face)>4:
faces.extend( fan_face(face) )
else:
faces.append(face)
scn= Blender.Scene.GetCurrent()
name= filename.split('/')[-1].split('\\')[-1].split('.')[0]
me= Blender.Mesh.New(name)
me.verts.extend(verts)
me.faces.extend(faces)
# Now edges if we have them, render fgon
if numedges:
FGON_FLAG= Blender.Mesh.EdgeFlags.FGON
edge_dict= {}
# Set all edges to be fgons by default
for ed in me.edges:
ed.flag |= FGON_FLAG
edge_dict[ed.key]= ed
# Now make known edges visible
has_edges = True
for i in xrange(numedges):
try:
i1,i2= file.readline().split()
except:
has_edges = False
break # some files dont define edges :/
i1= int(i1)
i2= int(i2)
if i1>i2:
i1,i2= i2,i1
# We know this edge is seen so unset the fgon flag
edge_dict[i1,i2].flag &= ~FGON_FLAG
if not has_edges:
# dang, we'v turned all the edges into fgons and then the file didnt define any edges.
# oh well, just enable them all
for ed in me.edges:
ed.flag &= ~FGON_FLAG
# Assign uvs from vert index
if has_uv:
for f in me.faces:
f_uv= f.uv
for i, v in enumerate(f): # same as f.v
f_uv[i]= uvs[v.index]
for ob in scn.objects:
ob.sel=0
scn.objects.active = scn.objects.new(me, name)
Blender.Window.RedrawAll()
print 'Off "%s" imported in %.4f seconds.' % (name, Blender.sys.time()-start)
if __name__=='__main__':
Blender.Window.FileSelector(read, 'Import OFF', '*.off')