: 2.5x.

, " ". , A.B B A. , . , ,

__init__.py. , , , , , string, , . , __init__.py , . __init__.py , .

, . , , , addons addons-contrib, . . , . F8 .

. : , , . , . (__name__ == "__main__") , .

mycube.py

#----------------------------------------------------------
# File mycube.py
#----------------------------------------------------------
import bpy
def makeMesh(z):
bpy.ops.mesh.primitive_cube_add(location=(0,0,z))
return bpy.context.object
if __name__ == "__main__":
ob = makeMesh(1)
print(ob, "created")

mycylinder.py

#----------------------------------------------------------
# File mycylinder.py
#----------------------------------------------------------
import bpy
def makeMesh(z):
bpy.ops.mesh.primitive_cylinder_add(location=(0,0,z))
return bpy.context.object
if __name__ == "__main__":
ob = makeMesh(5)
print(ob, "created")

mysphere.py

#----------------------------------------------------------
# File mysphere.py
#----------------------------------------------------------
import bpy
def makeMesh(z):
bpy.ops.mesh.primitive_ico_sphere_add(location=(0,0,z))
return bpy.context.object
if __name__ == "__main__":
ob = makeMesh(3)
print(ob, "created")

__init__.py

bl_info , . .

# ,
# , ,
if "bpy" in locals():
import imp imp.reload(mycube)
imp.reload(mysphere)
imp.reload(mycylinder)
print("Reloaded multifiles")
else:
from . import mycube, mysphere, mycylinder
print("Imported multifiles")

.

__init__.py() , .. default.blend, "bpy" in locals() . "Imported multifiles".

__init__.py() default.blend, , "bpy" in locals() . "Imported multifiles".

, , F8, , "bpy" in locals() . , "Reloaded multifiles".

#----------------------------------------------------------
# File __init__.py
#----------------------------------------------------------
# Addon info
bl_info = {
"name": "Multifile",
'author': 'Thomas Larsson',
"location": "View3D > UI panel > Add meshes",
"category": "3D View"
}
# ,
# , ,
if "bpy" in locals():
import imp imp.reload(mycube)
imp.reload(mysphere)
imp.reload(mycylinder)
print("Reloaded multifiles")
else:
from . import mycube, mysphere, mycylinder
print("Imported multifiles")
import bpy
from bpy.props import *
#
# class AddMeshPanel(bpy.types.Panel):
#
class AddMeshPanel(bpy.types.Panel):
bl_label = "Add meshes"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
self.layout.operator("multifile.add",
text="Add cube").mesh = "cube"
self.layout.operator("multifile.add",
text="Add cylinder").mesh = "cylinder"
self.layout.operator("multifile.add",
text="Add sphere").mesh = "sphere"
#
# class OBJECT_OT_AddButton(bpy.types.Operator):
#
class OBJECT_OT_AddButton(bpy.types.Operator):
bl_idname = "multifile.add"
bl_label = "Add"
mesh = bpy.props.StringProperty()
def execute(self, context):
if self.mesh == "cube":
mycube.makeMesh(-8)
elif self.mesh == "cylinder":
mycylinder.makeMesh(-5)
elif self.mesh == "sphere":
mysphere.makeMesh(-2)
return{'FINISHED'}
#
#
#
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()

obj-

OBJ . Wavefront Maya, . ASCII-, :

v x y z

(x, y, z)

vt u v

(u, v)

f v1 v2 ... vn

n , v1, v2, ... vn. UV.

f v1/vt1 v2/vt2 ... vn/vtn

n . v1, v2, ... vn 3D- vt1, vt2, ... vtn .

, , , - OBJ-.

, . -, ( , , ) , Y , Z . -, 1, 0. , v1-1, v2-1, ... vn-1 3D- vt1-1, vt2-1, ... vtn-1 .

- OBJ- , : , /, __init__.py, .

OBJ-

OBJ-.

#----------------------------------------------------------
# File export_simple_obj.py
# OBJ-, ,
#----------------------------------------------------------
import bpy, os
def export_simple_obj(filepath, ob, rot90, scale):
name = os.path.basename(filepath)
realpath = os.path.realpath(os.path.expanduser(filepath))
fp = open(realpath, 'w')
print('Exporting%s' % realpath)
if not ob or ob.type != 'MESH':
raise NameError('Cannot export: active object%s is not a mesh.' % ob)
me = ob.data
for v in me.vertices:
x = scale*v.co
if rot90:
fp.write("v%.5f%.5f%.5fn" % (x[0], x[2], -x[1]))
else:
fp.write("v%.5f%.5f%.5fn" % (x[0], x[1], x[2]))
if len(me.uv_textures) > 0:
uvtex = me.uv_textures[0]
for f in me.faces:
data = uvtex.data[f.index]
fp.write("vt%.5f%.5fn" % (data.uv1[0], data.uv1[1]))
fp.write("vt%.5f%.5fn" % (data.uv2[0], data.uv2[1]))
fp.write("vt%.5f%.5fn" % (data.uv3[0], data.uv3[1]))
if len(f.vertices) == 4:
fp.write("vt%.5f%.5fn" % (data.uv4[0], data.uv4[1]))
vt = 1
for f in me.faces:
vs = f.vertices
fp.write("f%d/%d%d/%d%d/%d" % (vs[0]+1, vt, vs[1]+1, vt+1, vs[2]+1, vt+2))
vt += 3
if len(f.vertices) == 4:
fp.write("%d/%dn" % (vs[3]+1, vt))
vt += 1
else:
fp.write("n")
else:
for f in me.faces:
vs = f.vertices
fp.write("f%d%d%d" % (vs[0]+1, vs[1]+1, vs[2]+1))
if len(f.vertices) == 4:
fp.write("%dn" % (vs[3]+1))
else:
fp.write("n")
print('%s successfully exported' % realpath)
fp.close()
return

OBJ-

. , , OBJ- .

#----------------------------------------------------------
# File import_simple_obj.py
# OBJ-, ,
#----------------------------------------------------------
import bpy, os
def import_simple_obj(filepath, rot90, scale):
name = os.path.basename(filepath)
realpath = os.path.realpath(os.path.expanduser(filepath))
fp = open(realpath, 'rU') # Universal read
print('Importing%s' % realpath)
verts = []
faces = []
texverts = []
texfaces = []
for line in fp:
words = line.split()
if len(words) == 0:
pass
elif words[0] == 'v':
(x,y,z) = (float(words[1]), float(words[2]), float(words[3]))
if rot90:
verts.append( (scale*x, -scale*z, scale*y) )
else:
verts.append( (scale*x, scale*y, scale*z) )
elif words[0] == 'vt':
texverts.append( (float(words[1]), float(words[2])) )
elif words[0] == 'f':
(f,tf) = parseFace(words)
faces.append(f)
if tf:
texfaces.append(tf)
else:
pass
print('%s successfully imported' % realpath)
fp.close()
me = bpy.data.meshes.new(name)
me.from_pydata(verts, [], faces)
me.update()
if texverts:
uvtex = me.uv_textures.new()
uvtex.name = name
data = uvtex.data
for n in range(len(texfaces)):
tf = texfaces[n]
data[n].uv1 = texverts[tf[0]]
data[n].uv2 = texverts[tf[1]]
data[n].uv3 = texverts[tf[2]]
if len(tf) == 4:
data[n].uv4 = texverts[tf[3]]
scn = bpy.context.scene
ob = bpy.data.objects.new(name, me)
scn.objects.link(ob)
scn.objects.active = ob
return
def parseFace(words):
face = []
texface = []
for n in range(1, len(words)):
li = words[n].split('/')
face.append( int(li[0])-1 )
try:
texface.append( int(li[1])-1 )
except:
pass
return (face, texface)

__init__.py

, , . File Export. : , 90 ( Y Z ), . File Import. : , 90 ( Z ), .

__init__.py bl_info , , , / .

#----------------------------------------------------------
# File __init__.py
#----------------------------------------------------------
#
bl_info = {
"name": "Simple OBJ format",
"author": "Thomas Larsson",
"location": "File > Import-Export",
"description": "Simple Wavefront obj import/export. Does meshes and UV coordinates",
"category": "Import-Export"}
# ,
# , ,
if "bpy" in locals():
import imp
if 'simple_obj_import' in locals():
imp.reload(simple_obj_import)
if 'simple_obj_export' in locals():
imp.reload(simple_obj_export)
import bpy
from bpy.props import *
from io_utils import ExportHelper, ImportHelper
#
# Import
#
class IMPORT_OT_simple_obj(bpy.types.Operator, ImportHelper):
bl_idname = "io_import_scene.simple_obj"
bl_description = 'Import from simple OBJ file format (.obj)'
bl_label = "Import simple OBJ" bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
filename_ext = ".obj"
filter_glob = StringProperty(default="*.obj;*.mtl", options={'HIDDEN'})
filepath = bpy.props.StringProperty(
name="File Path",
description="File path used for importing the simple OBJ file",
maxlen= 1024, default= "")
rot90 = bpy.props.BoolProperty(
name = "Rotate 90 degrees",
description="Rotate mesh to Z up",
default = True)
scale = bpy.props.FloatProperty(
name = "Scale",
description="Scale mesh",
default = 0.1, min = 0.001, max = 1000.0)
def execute(self, context):
from . import simple_obj_import
print("Load", self.properties.filepath)
simple_obj_import.import_simple_obj(
self.properties.filepath,
self.rot90,
self.scale)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
#
# Export
#
class EXPORT_OT_simple_obj(bpy.types.Operator, ExportHelper):
bl_idname = "io_export_scene.simple_obj"
bl_description = 'Export from simple OBJ file format (.obj)'
bl_label = "Export simple OBJ"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
# ExportHelper. .
filename_ext = ".obj"
filter_glob = StringProperty(default="*.obj", options={'HIDDEN'})
filepath = bpy.props.StringProperty(
name="File Path",
description="File path used for exporting the simple OBJ file",
maxlen= 1024, default= "")
rot90 = bpy.props.BoolProperty(
name = "Rotate 90 degrees",
description="Rotate mesh to Y up",
default = True)
scale = bpy.props.FloatProperty(
name = "Scale",
description="Scale mesh",
default = 0.1, min = 0.001, max = 1000.0)
def execute(self, context):
print("Load", self.properties.filepath)
from . import simple_obj_export
simple_obj_export.export_simple_obj(
self.properties.filepath,
context.object,
self.rot90,
1.0/self.scale)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
#
#
#
def menu_func_import(self, context):
self.layout.operator(IMPORT_OT_simple_obj.bl_idname, text="Simple OBJ (.obj)...")
def menu_func_export(self, context):
self.layout.operator(EXPORT_OT_simple_obj.bl_idname, text="Simple OBJ (.obj)...")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func_import)
bpy.types.INFO_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()


: 1.202. /Cache: 3 / 1