###for blender 2.79
#!BPY
"""
Name: 'Binary Obj (.bobj)...'
Blender: 237
Group: 'Import'
Tooltip: 'Load a Binary OBJ File'
"""
__author__ = "Nils Thuerey, Campbell Barton"
__url__ = ["blender", "elysiun"]
__version__ = "0.9"
__bpydoc__ = """\
This script imports BOBJ files to Blender.
Usage:
Run this script from "File->Import" menu and then load the desired BOBJ file.
"""
# $Id: bobj_import.py,v 1.3 2005/07/15 11:37:06 sinithue Exp $
#
# --------------------------------------------------------------------------
# BOBJ Import v0.9 by Nils Thuerey, Campbell Barton (AKA Ideasman)
# --------------------------------------------------------------------------
# ***** 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 *****
# --------------------------------------------------------------------------
globDIR = ''
#==============================================#
# Return directory, where is file #
#==============================================#
def pathName(path,name):
length=len(path)
for CH in range(1, length):
if path[length-CH:] == name:
path = path[:length-CH]
break
return path
#==============================================#
# Strips the slashes from the back of a string #
#==============================================#
def stripPath(path):
for CH in range(len(path), 0, -1):
if path[CH-1] == "/" or path[CH-1] == "\\":
path = path[CH:]
break
return path
#====================================================#
# Strips the prefix off the name before writing #
#====================================================#
def stripName(name): # name is a string
prefixDelimiter = '.'
return name[ : name.find(prefixDelimiter) ]
#from Blender import *
import bpy,struct
import gzip
import re
import sys
import time
import bmesh
#======================================================================#
# Returns unique name of object (preserve overwriting existing meshes) #
#======================================================================#
def getUniqueName(name):
uniqueInt = 0
while 1:
try:
ob = Object.Get(name)
# Okay, this is working, so lets make a new name
name += '.' + str(uniqueInt)
uniqueInt +=1
except:
if NMesh.GetRaw(name) == None:
return name
else:
name += '.' + str(uniqueInt)
uniqueInt +=1
#==================================================================================#
# This loads data from .bobj file #
#==================================================================================#
def loadFile(filename):
stripFilename = stripName( stripPath(filename) )
meshname = "mesh_" + stripFilename
#meshname = getUniqueName(meshname)
globDIR = pathName(filename, stripPath(filename))
loadBobj(filename, meshname)
print ("bobj ",filename," from ",globDIR,"as",meshname)
#==================================================================================#
# Create object with given name from file
# warning - this is exported to elbeemworld.py!
#==================================================================================#
def loadBobj(filename,objname):
# Get the file name with no path or .obj
postfixDelimiter = '.'
postfix = filename[ filename.find(postfixDelimiter)+1 : ]
#postfix = stripPostfix(filename)
if re.match( r'.*\.bobj$', filename):
bfile = open(filename, 'rb')
elif re.match( r'.*\.bobj\.gz$', filename):
bfile = gzip.GzipFile( filename, "r" )
else:
print ("Error - invalid postfix '%s', filename '%s', aborting..." % (postfix,filename))
return;
verts = []
faces = []
mesh = bpy.data.meshes.new("mesh") # add a new mesh
obj = bpy.data.objects.new(objname, mesh) # add a new object using the mesh
vertNumBytes = bfile.read(4)
vertNum = struct.unpack("<l", vertNumBytes)[0]
print("VN:",vertNum)
for i in range(0,vertNum):
vxb = bfile.read(4)
vyb = bfile.read(4)
vzb = bfile.read(4)
vx = struct.unpack("f",vxb)[0]
vy = struct.unpack("f",vyb)[0]
vz = struct.unpack("f",vzb)[0]
v = (vx,vy,vz)
verts.append(v)
normNumBytes = bfile.read(4)
normNum = struct.unpack("<l", normNumBytes)[0]
print( "NN:",normNum)
for i in range(0,normNum):
nxb = bfile.read(4)
nyb = bfile.read(4)
nzb = bfile.read(4)
nx = struct.unpack("f",nxb)[0]
ny = struct.unpack("f",nyb)[0]
nz = struct.unpack("f",nzb)[0]
faceNumBytes = bfile.read(4)
faceNum = struct.unpack("<l", faceNumBytes)[0]
print( "FN:",faceNum)
for i in range(0,faceNum):
fxb = bfile.read(4)
fyb = bfile.read(4)
fzb = bfile.read(4)
fx = struct.unpack("<l",fxb)[0]
fy = struct.unpack("<l",fyb)[0]
fz = struct.unpack("<l",fzb)[0]
v = (fx,fy,fz)
faces.append(v)
print(faces[1])
mesh.from_pydata(verts, [], faces)
mesh.update()
obj.data = mesh
bpy.context.scene.objects.link(obj)
"""
# start creating mesh
mesh = NMesh.GetRaw(objname) # CHECK ??
if mesh == None:
mesh = NMesh.GetRaw() # CHECK ??
else:
mesh.verts = []
mesh.faces = []
vertNumBytes = bfile.read(4)
vertNum = struct.unpack("<l", vertNumBytes)[0]
print("VN:",vertNum)
for i in range(0,vertNum):
vxb = bfile.read(4)
vyb = bfile.read(4)
vzb = bfile.read(4)
vx = struct.unpack("f",vxb)[0]
vy = struct.unpack("f",vyb)[0]
vz = struct.unpack("f",vzb)[0]
vert = NMesh.Vert(vx,vy,vz)
vert.no[0] = 1
vert.no[1] = 0
vert.no[2] = 0
mesh.verts.append( vert )
#if i>(vertNum-10): print "V",i,":",vx,vy,vz
normNumBytes = bfile.read(4)
normNum = struct.unpack("<l", normNumBytes)[0]
print( "NN:",normNum)
for i in range(0,normNum):
nxb = bfile.read(4)
nyb = bfile.read(4)
nzb = bfile.read(4)
nx = struct.unpack("f",nxb)[0]
ny = struct.unpack("f",nyb)[0]
nz = struct.unpack("f",nzb)[0]
mesh.verts[i].no[0] = nx
mesh.verts[i].no[1] = ny
mesh.verts[i].no[2] = nz
#if i>(normNum-10): print "V",i,":",nx,ny,nz
faceNumBytes = bfile.read(4)
faceNum = struct.unpack("<l", faceNumBytes)[0]
print( "FN:",faceNum)
for i in range(0,faceNum):
fxb = bfile.read(4)
fyb = bfile.read(4)
fzb = bfile.read(4)
fx = struct.unpack("<l",fxb)[0]
fy = struct.unpack("<l",fyb)[0]
fz = struct.unpack("<l",fzb)[0]
meshface = NMesh.Face()
meshface.append(mesh.verts[fx])
meshface.append(mesh.verts[fy])
meshface.append(mesh.verts[fz])
meshface.smooth = 1
mesh.faces.append( meshface )
#if i>(faceNum-10): print "V",i,":",fx,fy,fz
obj = NMesh.PutRaw( mesh, objname, 0)
if obj != None:
obj.setName( objname )
"""
# TODO FIXME , reuse vertices from surface mesh!
bfile.close()
return;
# blender pbrt test call
#./blender_rtag2.36/blender -w -p 0 0 250 250 pbrtt1.blend -P exportPbrt.py ; pbrt expt.pbrt ; exrview expt.exr
#Window.FileSelector(loadFile, 'Import BOBJ')
def read_some_data(context, filepath, use_some_setting):
"""
print("running read_some_data...")
f = open(filepath, 'r', encoding='utf-8')
data = f.read()
f.close()
# would normally load the data here
print(data)
"""
loadFile(filepath)
return {'FINISHED'}
# ImportHelper is a helper class, defines filename and
# invoke() function which calls the file selector.
from bpy_extras.io_utils import ImportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
class ImportSomeData(Operator, ImportHelper):
"""This appears in the tooltip of the operator and in the generated docs"""
bl_idname = "import_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed
bl_label = "Import Some Data"
# ImportHelper mixin class uses this
filename_ext = ".bobj"
filter_glob = StringProperty(
default="*.bobj",
options={'HIDDEN'},
)
# List of operator properties, the attributes will be assigned
# to the class instance from the operator settings before calling.
use_setting = BoolProperty(
name="Example Boolean",
description="Example Tooltip",
default=True,
)
type = EnumProperty(
name="Example Enum",
description="Choose between two items",
items=(('OPT_A', "First Option", "Description one"),
('OPT_B', "Second Option", "Description two")),
default='OPT_A',
)
def execute(self, context):
return read_some_data(context, self.filepath, self.use_setting)
# Only needed if you want to add into a dynamic menu
def menu_func_import(self, context):
self.layout.operator(ImportSomeData.bl_idname, text="Text Import Operator")
def register():
bpy.utils.register_class(ImportSomeData)
bpy.types.INFO_MT_file_import.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(ImportSomeData)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
if __name__ == "__main__":
register()
# test call
bpy.ops.import_test.some_data('INVOKE_DEFAULT')