forked from bartvdbraak/blender
- ran 2to3 on export_3ds.py, import_3ds.py and export_x3d.py
- added operators and menu items for ^
This commit is contained in:
parent
d1f22f6ce3
commit
675936b42c
@ -46,14 +46,17 @@ from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode.
|
||||
# Importing modules
|
||||
######################################################
|
||||
|
||||
import Blender
|
||||
import struct
|
||||
|
||||
import bpy
|
||||
from BPyMesh import getMeshFromObject
|
||||
from BPyObject import getDerivedObjects
|
||||
try:
|
||||
import struct
|
||||
except:
|
||||
struct = None
|
||||
|
||||
# import Blender
|
||||
# from BPyMesh import getMeshFromObject
|
||||
# from BPyObject import getDerivedObjects
|
||||
# try:
|
||||
# import struct
|
||||
# except:
|
||||
# struct = None
|
||||
|
||||
# So 3ds max can open files, limit names to 12 in length
|
||||
# this is verry annoying for filenames!
|
||||
@ -85,58 +88,58 @@ def sane_name(name):
|
||||
|
||||
#Some of the chunks that we will export
|
||||
#----- Primary Chunk, at the beginning of each file
|
||||
PRIMARY= long("0x4D4D",16)
|
||||
PRIMARY= int("0x4D4D",16)
|
||||
|
||||
#------ Main Chunks
|
||||
OBJECTINFO = long("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = long("0x0002",16); #This gives the version of the .3ds file
|
||||
KFDATA = long("0xB000",16); #This is the header for all of the key frame info
|
||||
OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = int("0x0002",16); #This gives the version of the .3ds file
|
||||
KFDATA = int("0xB000",16); #This is the header for all of the key frame info
|
||||
|
||||
#------ sub defines of OBJECTINFO
|
||||
MATERIAL=45055 #0xAFFF // This stored the texture info
|
||||
OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
|
||||
|
||||
#>------ sub defines of MATERIAL
|
||||
MATNAME = long("0xA000",16); # This holds the material name
|
||||
MATAMBIENT = long("0xA010",16); # Ambient color of the object/material
|
||||
MATDIFFUSE = long("0xA020",16); # This holds the color of the object/material
|
||||
MATSPECULAR = long("0xA030",16); # SPecular color of the object/material
|
||||
MATSHINESS = long("0xA040",16); # ??
|
||||
MATMAP = long("0xA200",16); # This is a header for a new material
|
||||
MATMAPFILE = long("0xA300",16); # This holds the file name of the texture
|
||||
MATNAME = int("0xA000",16); # This holds the material name
|
||||
MATAMBIENT = int("0xA010",16); # Ambient color of the object/material
|
||||
MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material
|
||||
MATSPECULAR = int("0xA030",16); # SPecular color of the object/material
|
||||
MATSHINESS = int("0xA040",16); # ??
|
||||
MATMAP = int("0xA200",16); # This is a header for a new material
|
||||
MATMAPFILE = int("0xA300",16); # This holds the file name of the texture
|
||||
|
||||
RGB1= long("0x0011",16)
|
||||
RGB2= long("0x0012",16)
|
||||
RGB1= int("0x0011",16)
|
||||
RGB2= int("0x0012",16)
|
||||
|
||||
#>------ sub defines of OBJECT
|
||||
OBJECT_MESH = long("0x4100",16); # This lets us know that we are reading a new object
|
||||
OBJECT_LIGHT = long("0x4600",16); # This lets un know we are reading a light object
|
||||
OBJECT_CAMERA= long("0x4700",16); # This lets un know we are reading a camera object
|
||||
OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object
|
||||
OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object
|
||||
OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object
|
||||
|
||||
#>------ sub defines of CAMERA
|
||||
OBJECT_CAM_RANGES= long("0x4720",16); # The camera range values
|
||||
OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values
|
||||
|
||||
#>------ sub defines of OBJECT_MESH
|
||||
OBJECT_VERTICES = long("0x4110",16); # The objects vertices
|
||||
OBJECT_FACES = long("0x4120",16); # The objects faces
|
||||
OBJECT_MATERIAL = long("0x4130",16); # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = long("0x4140",16); # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = long("0x4160",16); # The Object Matrix
|
||||
OBJECT_VERTICES = int("0x4110",16); # The objects vertices
|
||||
OBJECT_FACES = int("0x4120",16); # The objects faces
|
||||
OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = int("0x4140",16); # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix
|
||||
|
||||
#>------ sub defines of KFDATA
|
||||
KFDATA_KFHDR = long("0xB00A",16);
|
||||
KFDATA_KFSEG = long("0xB008",16);
|
||||
KFDATA_KFCURTIME = long("0xB009",16);
|
||||
KFDATA_OBJECT_NODE_TAG = long("0xB002",16);
|
||||
KFDATA_KFHDR = int("0xB00A",16);
|
||||
KFDATA_KFSEG = int("0xB008",16);
|
||||
KFDATA_KFCURTIME = int("0xB009",16);
|
||||
KFDATA_OBJECT_NODE_TAG = int("0xB002",16);
|
||||
|
||||
#>------ sub defines of OBJECT_NODE_TAG
|
||||
OBJECT_NODE_ID = long("0xB030",16);
|
||||
OBJECT_NODE_HDR = long("0xB010",16);
|
||||
OBJECT_PIVOT = long("0xB013",16);
|
||||
OBJECT_INSTANCE_NAME = long("0xB011",16);
|
||||
POS_TRACK_TAG = long("0xB020",16);
|
||||
ROT_TRACK_TAG = long("0xB021",16);
|
||||
SCL_TRACK_TAG = long("0xB022",16);
|
||||
OBJECT_NODE_ID = int("0xB030",16);
|
||||
OBJECT_NODE_HDR = int("0xB010",16);
|
||||
OBJECT_PIVOT = int("0xB013",16);
|
||||
OBJECT_INSTANCE_NAME = int("0xB011",16);
|
||||
POS_TRACK_TAG = int("0xB020",16);
|
||||
ROT_TRACK_TAG = int("0xB021",16);
|
||||
SCL_TRACK_TAG = int("0xB022",16);
|
||||
|
||||
def uv_key(uv):
|
||||
return round(uv.x, 6), round(uv.y, 6)
|
||||
@ -343,12 +346,12 @@ class _3ds_named_variable(object):
|
||||
def dump(self,indent):
|
||||
if (self.value!=None):
|
||||
spaces=""
|
||||
for i in xrange(indent):
|
||||
for i in range(indent):
|
||||
spaces+=" ";
|
||||
if (self.name!=""):
|
||||
print spaces, self.name, " = ", self.value
|
||||
print(spaces, self.name, " = ", self.value)
|
||||
else:
|
||||
print spaces, "[unnamed]", " = ", self.value
|
||||
print(spaces, "[unnamed]", " = ", self.value)
|
||||
|
||||
|
||||
#the chunk class
|
||||
@ -408,9 +411,9 @@ class _3ds_chunk(object):
|
||||
Dump is used for debugging purposes, to dump the contents of a chunk to the standard output.
|
||||
Uses the dump function of the named variables and the subchunks to do the actual work.'''
|
||||
spaces=""
|
||||
for i in xrange(indent):
|
||||
for i in range(indent):
|
||||
spaces+=" ";
|
||||
print spaces, "ID=", hex(self.ID.value), "size=", self.get_size()
|
||||
print(spaces, "ID=", hex(self.ID.value), "size=", self.get_size())
|
||||
for variable in self.variables:
|
||||
variable.dump(indent+1)
|
||||
for subchunk in self.subchunks:
|
||||
@ -555,11 +558,11 @@ def remove_face_uv(verts, tri_list):
|
||||
|
||||
# initialize a list of UniqueLists, one per vertex:
|
||||
#uv_list = [UniqueList() for i in xrange(len(verts))]
|
||||
unique_uvs= [{} for i in xrange(len(verts))]
|
||||
unique_uvs= [{} for i in range(len(verts))]
|
||||
|
||||
# for each face uv coordinate, add it to the UniqueList of the vertex
|
||||
for tri in tri_list:
|
||||
for i in xrange(3):
|
||||
for i in range(3):
|
||||
# store the index into the UniqueList for future reference:
|
||||
# offset.append(uv_list[tri.vertex_index[i]].add(_3ds_point_uv(tri.faceuvs[i])))
|
||||
|
||||
@ -589,7 +592,7 @@ def remove_face_uv(verts, tri_list):
|
||||
|
||||
pt = _3ds_point_3d(vert.co) # reuse, should be ok
|
||||
uvmap = [None] * len(unique_uvs[i])
|
||||
for ii, uv_3ds in unique_uvs[i].itervalues():
|
||||
for ii, uv_3ds in unique_uvs[i].values():
|
||||
# add a vertex duplicate to the vertex_array for every uv associated with this vertex:
|
||||
vert_array.add(pt)
|
||||
# add the uv coordinate to the uv array:
|
||||
@ -607,7 +610,7 @@ def remove_face_uv(verts, tri_list):
|
||||
|
||||
# Make sure the triangle vertex indices now refer to the new vertex list:
|
||||
for tri in tri_list:
|
||||
for i in xrange(3):
|
||||
for i in range(3):
|
||||
tri.offset[i]+=index_list[tri.vertex_index[i]]
|
||||
tri.vertex_index= tri.offset
|
||||
|
||||
@ -655,7 +658,7 @@ def make_faces_chunk(tri_list, mesh, materialDict):
|
||||
# obj_material_faces[tri.mat].add(_3ds_short(i))
|
||||
|
||||
face_chunk.add_variable("faces", face_list)
|
||||
for mat_name, mat_faces in unique_mats.itervalues():
|
||||
for mat_name, mat_faces in unique_mats.values():
|
||||
obj_material_chunk=_3ds_chunk(OBJECT_MATERIAL)
|
||||
obj_material_chunk.add_variable("name", mat_name)
|
||||
obj_material_chunk.add_variable("face_list", mat_faces)
|
||||
@ -677,7 +680,7 @@ def make_faces_chunk(tri_list, mesh, materialDict):
|
||||
obj_material_faces[tri.mat].add(_3ds_short(i))
|
||||
|
||||
face_chunk.add_variable("faces", face_list)
|
||||
for i in xrange(n_materials):
|
||||
for i in range(n_materials):
|
||||
obj_material_chunk=_3ds_chunk(OBJECT_MATERIAL)
|
||||
obj_material_chunk.add_variable("name", obj_material_names[i])
|
||||
obj_material_chunk.add_variable("face_list", obj_material_faces[i])
|
||||
@ -862,7 +865,7 @@ def make_kf_obj_node(obj, name_to_id):
|
||||
return kf_obj_node
|
||||
"""
|
||||
|
||||
import BPyMessages
|
||||
# import BPyMessages
|
||||
def save_3ds(filename, context):
|
||||
'''Save the Blender scene to a 3ds file.'''
|
||||
# Time the export
|
||||
@ -871,16 +874,16 @@ def save_3ds(filename, context):
|
||||
filename += '.3ds'
|
||||
|
||||
# XXX
|
||||
# if not BPyMessages.Warning_SaveOver(filename):
|
||||
# return
|
||||
# if not BPyMessages.Warning_SaveOver(filename):
|
||||
# return
|
||||
|
||||
# XXX
|
||||
time1 = bpy.sys.time()
|
||||
# time1= Blender.sys.time()
|
||||
# Blender.Window.WaitCursor(1)
|
||||
time1 = bpy.sys.time()
|
||||
# time1= Blender.sys.time()
|
||||
# Blender.Window.WaitCursor(1)
|
||||
|
||||
sce = context.scene
|
||||
# sce= bpy.data.scenes.active
|
||||
# sce= bpy.data.scenes.active
|
||||
|
||||
# Initialize the main chunk (primary):
|
||||
primary = _3ds_chunk(PRIMARY)
|
||||
@ -948,7 +951,7 @@ def save_3ds(filename, context):
|
||||
f.mat = 0
|
||||
|
||||
# Make material chunks for all materials used in the meshes:
|
||||
for mat_and_image in materialDict.itervalues():
|
||||
for mat_and_image in materialDict.values():
|
||||
object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1]))
|
||||
|
||||
# Give all objects a unique ID and build a dictionary from object name to object id:
|
||||
@ -1011,15 +1014,44 @@ def save_3ds(filename, context):
|
||||
|
||||
# Debugging only: report the exporting time:
|
||||
Blender.Window.WaitCursor(0)
|
||||
print "3ds export time: %.2f" % (Blender.sys.time() - time1)
|
||||
print("3ds export time: %.2f" % (Blender.sys.time() - time1))
|
||||
|
||||
# Debugging only: dump the chunk hierarchy:
|
||||
#primary.dump()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
if struct:
|
||||
Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds'))
|
||||
else:
|
||||
Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
|
||||
# save_3ds('/test_b.3ds')
|
||||
# if __name__=='__main__':
|
||||
# if struct:
|
||||
# Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds'))
|
||||
# else:
|
||||
# Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
|
||||
# # save_3ds('/test_b.3ds')
|
||||
|
||||
class EXPORT_OT_3ds(bpy.types.Operator):
|
||||
'''
|
||||
3DS Exporter
|
||||
'''
|
||||
__idname__ = "export.3ds"
|
||||
__label__ = 'Export 3DS'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the 3DS file", maxlen= 1024, default= ""),
|
||||
]
|
||||
|
||||
def execute(self, context):
|
||||
raise Exception("Not doing anything yet.")
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
def poll(self, context): # Poll isnt working yet
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(EXPORT_OT_3ds)
|
||||
|
@ -913,7 +913,7 @@ class EXPORT_OT_obj(bpy.types.Operator):
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""),
|
||||
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the OBJ file", maxlen= 1024, default= ""),
|
||||
|
||||
# context group
|
||||
bpy.props.BoolProperty(attr="use_selection", name="Selection Only", description="", default= False),
|
||||
|
@ -53,22 +53,27 @@ Known issues:<br>
|
||||
# Library dependancies
|
||||
####################################
|
||||
|
||||
import Blender
|
||||
from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
|
||||
from Blender.Scene import Render
|
||||
import math
|
||||
import BPyObject
|
||||
import BPyMesh
|
||||
|
||||
import bpy
|
||||
import Mathutils
|
||||
|
||||
# import Blender
|
||||
# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
|
||||
# from Blender.Scene import Render
|
||||
# import BPyObject
|
||||
# import BPyMesh
|
||||
|
||||
#
|
||||
DEG2RAD=0.017453292519943295
|
||||
MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
|
||||
MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x')
|
||||
|
||||
####################################
|
||||
# Global Variables
|
||||
####################################
|
||||
|
||||
filename = Blender.Get('filename')
|
||||
filename = ""
|
||||
# filename = Blender.Get('filename')
|
||||
_safeOverwrite = True
|
||||
|
||||
extension = ''
|
||||
@ -109,7 +114,7 @@ class x3d_class:
|
||||
import gzip
|
||||
self.file = gzip.open(filename, "w")
|
||||
except:
|
||||
print "failed to import compression modules, exporting uncompressed"
|
||||
print("failed to import compression modules, exporting uncompressed")
|
||||
self.filename = filename[:-1] # remove trailing z
|
||||
|
||||
if self.file == None:
|
||||
@ -383,7 +388,7 @@ class x3d_class:
|
||||
if nIFSCnt > 1:
|
||||
self.writeIndented("<Group DEF=\"%s%s\">\n" % ("G_", meshName),1)
|
||||
|
||||
if sided.has_key('two') and sided['two'] > 0:
|
||||
if 'two' in sided and sided['two'] > 0:
|
||||
bTwoSided=1
|
||||
else:
|
||||
bTwoSided=0
|
||||
@ -414,8 +419,8 @@ class x3d_class:
|
||||
if not matFlags & Blender.Material.Modes['TEXFACE']:
|
||||
self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world)
|
||||
if len(maters) > 1:
|
||||
print "Warning: mesh named %s has multiple materials" % meshName
|
||||
print "Warning: only one material per object handled"
|
||||
print("Warning: mesh named %s has multiple materials" % meshName)
|
||||
print("Warning: only one material per object handled")
|
||||
|
||||
#-- textures
|
||||
if mesh.faceUV:
|
||||
@ -433,7 +438,7 @@ class x3d_class:
|
||||
# user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
|
||||
ifStyle="IndexedFaceSet"
|
||||
# look up mesh name, use it if available
|
||||
if self.meshNames.has_key(meshME):
|
||||
if meshME in self.meshNames:
|
||||
self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1)
|
||||
self.meshNames[meshME]+=1
|
||||
else:
|
||||
@ -547,7 +552,7 @@ class x3d_class:
|
||||
if self.writingtexture == 0:
|
||||
self.file.write("\n\t\t\ttexCoordIndex=\"")
|
||||
texIndxStr=""
|
||||
for i in xrange(len(texIndexList)):
|
||||
for i in range(len(texIndexList)):
|
||||
texIndxStr = texIndxStr + "%d, " % texIndexList[i]
|
||||
if texIndexList[i]==-1:
|
||||
self.file.write(texIndxStr)
|
||||
@ -555,7 +560,7 @@ class x3d_class:
|
||||
self.file.write("\"\n\t\t\t")
|
||||
else:
|
||||
self.writeIndented("<TextureCoordinate point=\"", 1)
|
||||
for i in xrange(len(texCoordList)):
|
||||
for i in range(len(texCoordList)):
|
||||
self.file.write("%s %s, " % (round(texCoordList[i][0],self.tp), round(texCoordList[i][1],self.tp)))
|
||||
self.file.write("\" />")
|
||||
self.writeIndented("\n", -1)
|
||||
@ -569,7 +574,7 @@ class x3d_class:
|
||||
if face.col:
|
||||
c=face.col[0]
|
||||
if self.verbose > 2:
|
||||
print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)
|
||||
print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b))
|
||||
aColor = self.rgbToFS(c)
|
||||
self.file.write("%s, " % aColor)
|
||||
self.file.write("\" />")
|
||||
@ -577,7 +582,7 @@ class x3d_class:
|
||||
|
||||
def writeMaterial(self, mat, matName, world):
|
||||
# look up material name, use it if available
|
||||
if self.matNames.has_key(matName):
|
||||
if matName in self.matNames:
|
||||
self.writeIndented("<Material USE=\"MA_%s\" />\n" % matName)
|
||||
self.matNames[matName]+=1
|
||||
return;
|
||||
@ -617,7 +622,7 @@ class x3d_class:
|
||||
def writeImageTexture(self, image):
|
||||
name = image.name
|
||||
filename = image.filename.split('/')[-1].split('\\')[-1]
|
||||
if self.texNames.has_key(name):
|
||||
if name in self.texNames:
|
||||
self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
|
||||
self.texNames[name] += 1
|
||||
return
|
||||
@ -671,7 +676,7 @@ class x3d_class:
|
||||
self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
|
||||
self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
|
||||
alltexture = len(alltextures)
|
||||
for i in xrange(alltexture):
|
||||
for i in range(alltexture):
|
||||
namemat = alltextures[i].name
|
||||
pic = alltextures[i].getImage()
|
||||
if (namemat == "back") and (pic != None):
|
||||
@ -697,7 +702,7 @@ class x3d_class:
|
||||
EXPORT_TRI= False,\
|
||||
):
|
||||
|
||||
print "Info: starting X3D export to " + self.filename + "..."
|
||||
print("Info: starting X3D export to " + self.filename + "...")
|
||||
self.writeHeader()
|
||||
# self.writeScript()
|
||||
self.writeNavigationInfo(scene)
|
||||
@ -771,7 +776,7 @@ class x3d_class:
|
||||
self.texNames={}
|
||||
self.matNames={}
|
||||
self.indentLevel=0
|
||||
print "Info: finished X3D export to %s\n" % self.filename
|
||||
print("Info: finished X3D export to %s\n" % self.filename)
|
||||
|
||||
def cleanStr(self, name, prefix='rsvd_'):
|
||||
"""cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
|
||||
@ -815,7 +820,7 @@ class x3d_class:
|
||||
else:
|
||||
sidename='one'
|
||||
|
||||
if sided.has_key(sidename):
|
||||
if sidename in sided:
|
||||
sided[sidename]+=1
|
||||
else:
|
||||
sided[sidename]=1
|
||||
@ -829,30 +834,30 @@ class x3d_class:
|
||||
imageMap[faceName]=[face.image.name,sidename,face]
|
||||
|
||||
if self.verbose > 2:
|
||||
for faceName in imageMap.iterkeys():
|
||||
for faceName in imageMap.keys():
|
||||
ifs=imageMap[faceName]
|
||||
print "Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
|
||||
(faceName, ifs[0], ifs[1], len(ifs)-2)
|
||||
print("Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
|
||||
(faceName, ifs[0], ifs[1], len(ifs)-2))
|
||||
|
||||
return len(imageMap)
|
||||
|
||||
def faceToString(self,face):
|
||||
|
||||
print "Debug: face.flag=0x%x (bitflags)" % face.flag
|
||||
print("Debug: face.flag=0x%x (bitflags)" % face.flag)
|
||||
if face.sel:
|
||||
print "Debug: face.sel=true"
|
||||
print("Debug: face.sel=true")
|
||||
|
||||
print "Debug: face.mode=0x%x (bitflags)" % face.mode
|
||||
print("Debug: face.mode=0x%x (bitflags)" % face.mode)
|
||||
if face.mode & Mesh.FaceModes.TWOSIDE:
|
||||
print "Debug: face.mode twosided"
|
||||
print("Debug: face.mode twosided")
|
||||
|
||||
print "Debug: face.transp=0x%x (enum)" % face.transp
|
||||
print("Debug: face.transp=0x%x (enum)" % face.transp)
|
||||
if face.transp == Mesh.FaceTranspModes.SOLID:
|
||||
print "Debug: face.transp.SOLID"
|
||||
print("Debug: face.transp.SOLID")
|
||||
|
||||
if face.image:
|
||||
print "Debug: face.image=%s" % face.image.name
|
||||
print "Debug: face.materialIndex=%d" % face.materialIndex
|
||||
print("Debug: face.image=%s" % face.image.name)
|
||||
print("Debug: face.materialIndex=%d" % face.materialIndex)
|
||||
|
||||
def getVertexColorByIndx(self, mesh, indx):
|
||||
c = None
|
||||
@ -867,12 +872,12 @@ class x3d_class:
|
||||
return c
|
||||
|
||||
def meshToString(self,mesh):
|
||||
print "Debug: mesh.hasVertexUV=%d" % mesh.vertexColors
|
||||
print "Debug: mesh.faceUV=%d" % mesh.faceUV
|
||||
print "Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()
|
||||
print "Debug: mesh.verts=%d" % len(mesh.verts)
|
||||
print "Debug: mesh.faces=%d" % len(mesh.faces)
|
||||
print "Debug: mesh.materials=%d" % len(mesh.materials)
|
||||
print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors)
|
||||
print("Debug: mesh.faceUV=%d" % mesh.faceUV)
|
||||
print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours())
|
||||
print("Debug: mesh.verts=%d" % len(mesh.verts))
|
||||
print("Debug: mesh.faces=%d" % len(mesh.faces))
|
||||
print("Debug: mesh.materials=%d" % len(mesh.materials))
|
||||
|
||||
def rgbToFS(self, c):
|
||||
s="%s %s %s" % (
|
||||
@ -924,7 +929,7 @@ class x3d_class:
|
||||
self.indentLevel = self.indentLevel + inc
|
||||
|
||||
spaces=""
|
||||
for x in xrange(self.indentLevel):
|
||||
for x in range(self.indentLevel):
|
||||
spaces = spaces + "\t"
|
||||
self.file.write(spaces + s)
|
||||
|
||||
@ -1045,7 +1050,34 @@ def x3d_export_ui(filename):
|
||||
#########################################################
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
|
||||
# if __name__ == '__main__':
|
||||
# Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
|
||||
|
||||
class EXPORT_OT_x3d(bpy.types.Operator):
|
||||
'''
|
||||
X3D Exporter
|
||||
'''
|
||||
__idname__ = "export.x3d"
|
||||
__label__ = 'Export X3D'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen= 1024, default= ""),
|
||||
]
|
||||
|
||||
def execute(self, context):
|
||||
raise Exception("Not doing anything yet.")
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
def poll(self, context): # Poll isnt working yet
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(EXPORT_OT_x3d)
|
||||
|
@ -125,26 +125,29 @@ Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen).
|
||||
|
||||
# Importing modules
|
||||
|
||||
import Blender
|
||||
from struct import calcsize, unpack
|
||||
|
||||
import bpy
|
||||
from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils
|
||||
from Blender.Mathutils import Vector
|
||||
import BPyImage
|
||||
|
||||
import BPyMessages
|
||||
# import Blender
|
||||
# from Blender import Mesh, Object, Material, Image, Texture, Lamp, Mathutils
|
||||
# from Blender.Mathutils import Vector
|
||||
# import BPyImage
|
||||
|
||||
try:
|
||||
from struct import calcsize, unpack
|
||||
except:
|
||||
calcsize= unpack= None
|
||||
# import BPyMessages
|
||||
|
||||
# try:
|
||||
# from struct import calcsize, unpack
|
||||
# except:
|
||||
# calcsize= unpack= None
|
||||
|
||||
|
||||
|
||||
# If python version is less than 2.4, try to get set stuff from module
|
||||
try:
|
||||
set
|
||||
except:
|
||||
from sets import Set as set
|
||||
# # If python version is less than 2.4, try to get set stuff from module
|
||||
# try:
|
||||
# set
|
||||
# except:
|
||||
# from sets import Set as set
|
||||
|
||||
BOUNDS_3DS= []
|
||||
|
||||
@ -167,12 +170,12 @@ def createBlenderTexture(material, name, image):
|
||||
|
||||
#Some of the chunks that we will see
|
||||
#----- Primary Chunk, at the beginning of each file
|
||||
PRIMARY= long('0x4D4D',16)
|
||||
PRIMARY= int('0x4D4D',16)
|
||||
|
||||
#------ Main Chunks
|
||||
OBJECTINFO = long('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = long('0x0002',16); #This gives the version of the .3ds file
|
||||
EDITKEYFRAME= long('0xB000',16); #This is the header for all of the key frame info
|
||||
OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = int('0x0002',16); #This gives the version of the .3ds file
|
||||
EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info
|
||||
|
||||
#------ sub defines of OBJECTINFO
|
||||
MATERIAL=45055 #0xAFFF // This stored the texture info
|
||||
@ -180,62 +183,62 @@ OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
|
||||
|
||||
#>------ sub defines of MATERIAL
|
||||
#------ sub defines of MATERIAL_BLOCK
|
||||
MAT_NAME = long('0xA000',16) # This holds the material name
|
||||
MAT_AMBIENT = long('0xA010',16) # Ambient color of the object/material
|
||||
MAT_DIFFUSE = long('0xA020',16) # This holds the color of the object/material
|
||||
MAT_SPECULAR = long('0xA030',16) # SPecular color of the object/material
|
||||
MAT_SHINESS = long('0xA040',16) # ??
|
||||
MAT_TRANSPARENCY= long('0xA050',16) # Transparency value of material
|
||||
MAT_SELF_ILLUM = long('0xA080',16) # Self Illumination value of material
|
||||
MAT_WIRE = long('0xA085',16) # Only render's wireframe
|
||||
MAT_NAME = int('0xA000',16) # This holds the material name
|
||||
MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material
|
||||
MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material
|
||||
MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material
|
||||
MAT_SHINESS = int('0xA040',16) # ??
|
||||
MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material
|
||||
MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material
|
||||
MAT_WIRE = int('0xA085',16) # Only render's wireframe
|
||||
|
||||
MAT_TEXTURE_MAP = long('0xA200',16) # This is a header for a new texture map
|
||||
MAT_SPECULAR_MAP= long('0xA204',16) # This is a header for a new specular map
|
||||
MAT_OPACITY_MAP = long('0xA210',16) # This is a header for a new opacity map
|
||||
MAT_REFLECTION_MAP= long('0xA220',16) # This is a header for a new reflection map
|
||||
MAT_BUMP_MAP = long('0xA230',16) # This is a header for a new bump map
|
||||
MAT_MAP_FILENAME = long('0xA300',16) # This holds the file name of the texture
|
||||
MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map
|
||||
MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map
|
||||
MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map
|
||||
MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map
|
||||
MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map
|
||||
MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture
|
||||
|
||||
MAT_FLOAT_COLOR = long ('0x0010', 16) #color defined as 3 floats
|
||||
MAT_24BIT_COLOR = long ('0x0011', 16) #color defined as 3 bytes
|
||||
MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats
|
||||
MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes
|
||||
|
||||
#>------ sub defines of OBJECT
|
||||
OBJECT_MESH = long('0x4100',16); # This lets us know that we are reading a new object
|
||||
OBJECT_LAMP = long('0x4600',16); # This lets un know we are reading a light object
|
||||
OBJECT_LAMP_SPOT = long('0x4610',16); # The light is a spotloght.
|
||||
OBJECT_LAMP_OFF = long('0x4620',16); # The light off.
|
||||
OBJECT_LAMP_ATTENUATE = long('0x4625',16);
|
||||
OBJECT_LAMP_RAYSHADE = long('0x4627',16);
|
||||
OBJECT_LAMP_SHADOWED = long('0x4630',16);
|
||||
OBJECT_LAMP_LOCAL_SHADOW = long('0x4640',16);
|
||||
OBJECT_LAMP_LOCAL_SHADOW2 = long('0x4641',16);
|
||||
OBJECT_LAMP_SEE_CONE = long('0x4650',16);
|
||||
OBJECT_LAMP_SPOT_RECTANGULAR= long('0x4651',16);
|
||||
OBJECT_LAMP_SPOT_OVERSHOOT= long('0x4652',16);
|
||||
OBJECT_LAMP_SPOT_PROJECTOR= long('0x4653',16);
|
||||
OBJECT_LAMP_EXCLUDE= long('0x4654',16);
|
||||
OBJECT_LAMP_RANGE= long('0x4655',16);
|
||||
OBJECT_LAMP_ROLL= long('0x4656',16);
|
||||
OBJECT_LAMP_SPOT_ASPECT= long('0x4657',16);
|
||||
OBJECT_LAMP_RAY_BIAS= long('0x4658',16);
|
||||
OBJECT_LAMP_INNER_RANGE= long('0x4659',16);
|
||||
OBJECT_LAMP_OUTER_RANGE= long('0x465A',16);
|
||||
OBJECT_LAMP_MULTIPLIER = long('0x465B',16);
|
||||
OBJECT_LAMP_AMBIENT_LIGHT = long('0x4680',16);
|
||||
OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object
|
||||
OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object
|
||||
OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght.
|
||||
OBJECT_LAMP_OFF = int('0x4620',16); # The light off.
|
||||
OBJECT_LAMP_ATTENUATE = int('0x4625',16);
|
||||
OBJECT_LAMP_RAYSHADE = int('0x4627',16);
|
||||
OBJECT_LAMP_SHADOWED = int('0x4630',16);
|
||||
OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16);
|
||||
OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16);
|
||||
OBJECT_LAMP_SEE_CONE = int('0x4650',16);
|
||||
OBJECT_LAMP_SPOT_RECTANGULAR= int('0x4651',16);
|
||||
OBJECT_LAMP_SPOT_OVERSHOOT= int('0x4652',16);
|
||||
OBJECT_LAMP_SPOT_PROJECTOR= int('0x4653',16);
|
||||
OBJECT_LAMP_EXCLUDE= int('0x4654',16);
|
||||
OBJECT_LAMP_RANGE= int('0x4655',16);
|
||||
OBJECT_LAMP_ROLL= int('0x4656',16);
|
||||
OBJECT_LAMP_SPOT_ASPECT= int('0x4657',16);
|
||||
OBJECT_LAMP_RAY_BIAS= int('0x4658',16);
|
||||
OBJECT_LAMP_INNER_RANGE= int('0x4659',16);
|
||||
OBJECT_LAMP_OUTER_RANGE= int('0x465A',16);
|
||||
OBJECT_LAMP_MULTIPLIER = int('0x465B',16);
|
||||
OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16);
|
||||
|
||||
|
||||
|
||||
OBJECT_CAMERA= long('0x4700',16); # This lets un know we are reading a camera object
|
||||
OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object
|
||||
|
||||
#>------ sub defines of CAMERA
|
||||
OBJECT_CAM_RANGES= long('0x4720',16); # The camera range values
|
||||
OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values
|
||||
|
||||
#>------ sub defines of OBJECT_MESH
|
||||
OBJECT_VERTICES = long('0x4110',16); # The objects vertices
|
||||
OBJECT_FACES = long('0x4120',16); # The objects faces
|
||||
OBJECT_MATERIAL = long('0x4130',16); # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = long('0x4140',16); # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = long('0x4160',16); # The Object Matrix
|
||||
OBJECT_VERTICES = int('0x4110',16); # The objects vertices
|
||||
OBJECT_FACES = int('0x4120',16); # The objects faces
|
||||
OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = int('0x4140',16); # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix
|
||||
|
||||
global scn
|
||||
scn= None
|
||||
@ -255,10 +258,10 @@ class chunk:
|
||||
self.bytes_read=0
|
||||
|
||||
def dump(self):
|
||||
print 'ID: ', self.ID
|
||||
print 'ID in hex: ', hex(self.ID)
|
||||
print 'length: ', self.length
|
||||
print 'bytes_read: ', self.bytes_read
|
||||
print('ID: ', self.ID)
|
||||
print('ID in hex: ', hex(self.ID))
|
||||
print('length: ', self.length)
|
||||
print('bytes_read: ', self.bytes_read)
|
||||
|
||||
def read_chunk(file, chunk):
|
||||
temp_data=file.read(calcsize(chunk.binary_format))
|
||||
@ -309,13 +312,13 @@ def add_texture_to_material(image, texture, material, mapto):
|
||||
elif mapto=='BUMP':
|
||||
map=Texture.MapTo.NOR
|
||||
else:
|
||||
print '/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name)
|
||||
print('/tError: Cannot map to "%s"\n\tassuming diffuse color. modify material "%s" later.' % (mapto, material.name))
|
||||
map=Texture.MapTo.COL
|
||||
|
||||
if image: texture.setImage(image) # double check its an image.
|
||||
free_tex_slots= [i for i, tex in enumerate( material.getTextures() ) if tex==None]
|
||||
if not free_tex_slots:
|
||||
print '/tError: Cannot add "%s" map. 10 Texture slots alredy used.' % mapto
|
||||
print('/tError: Cannot add "%s" map. 10 Texture slots alredy used.' % mapto)
|
||||
else:
|
||||
material.setTexture(free_tex_slots[0],texture,Texture.TexCo.UV,map)
|
||||
|
||||
@ -374,7 +377,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
myVertMapping = {}
|
||||
vertMappingIndex = 0
|
||||
|
||||
vertsToUse = [i for i in xrange(len(myContextMesh_vertls)) if faceVertUsers[i]]
|
||||
vertsToUse = [i for i in range(len(myContextMesh_vertls)) if faceVertUsers[i]]
|
||||
myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
|
||||
|
||||
tempName= '%s_%s' % (contextObName, matName) # matName may be None.
|
||||
@ -423,7 +426,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
importedObjects.append(ob)
|
||||
bmesh.calcNormals()
|
||||
|
||||
for matName, faces in myContextMeshMaterials.iteritems():
|
||||
for matName, faces in myContextMeshMaterials.items():
|
||||
makeMeshMaterialCopy(matName, faces)
|
||||
|
||||
if len(materialFaces)!=len(myContextMesh_facels):
|
||||
@ -455,7 +458,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
new_chunk.bytes_read+= 4 #read the 4 bytes for the version number
|
||||
#this loader works with version 3 and below, but may not with 4 and above
|
||||
if (version>3):
|
||||
print '\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version
|
||||
print('\tNon-Fatal Error: Version greater than 3, may not load correctly: ', version)
|
||||
|
||||
#is it an object info chunk?
|
||||
elif (new_chunk.ID==OBJECTINFO):
|
||||
@ -684,7 +687,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
return temp_data
|
||||
|
||||
#contextMesh.verts.extend( [Vector(),] ) # DUMMYVERT! - remove when blenders internals are fixed.
|
||||
contextMesh_vertls= [getvert() for i in xrange(num_verts)]
|
||||
contextMesh_vertls= [getvert() for i in range(num_verts)]
|
||||
|
||||
#print 'object verts: bytes read: ', new_chunk.bytes_read
|
||||
|
||||
@ -702,7 +705,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
v1,v2,v3,dummy= unpack('<4H', temp_data)
|
||||
return v1, v2, v3
|
||||
|
||||
contextMesh_facels= [ getface() for i in xrange(num_faces) ]
|
||||
contextMesh_facels= [ getface() for i in range(num_faces) ]
|
||||
|
||||
|
||||
elif (new_chunk.ID==OBJECT_MATERIAL):
|
||||
@ -719,7 +722,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
new_chunk.bytes_read+= STRUCT_SIZE_UNSIGNED_SHORT
|
||||
return unpack('<H', temp_data)[0]
|
||||
|
||||
contextMeshMaterials[material_name]= [ getmat() for i in xrange(num_faces_using_mat) ]
|
||||
contextMeshMaterials[material_name]= [ getmat() for i in range(num_faces_using_mat) ]
|
||||
|
||||
#look up the material in all the materials
|
||||
|
||||
@ -733,7 +736,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
new_chunk.bytes_read += STRUCT_SIZE_2FLOAT #2 float x 4 bytes each
|
||||
return Vector( unpack('<2f', temp_data) )
|
||||
|
||||
contextMeshUV= [ getuv() for i in xrange(num_uv) ]
|
||||
contextMeshUV= [ getuv() for i in range(num_uv) ]
|
||||
|
||||
elif (new_chunk.ID== OBJECT_TRANS_MATRIX):
|
||||
# How do we know the matrix size? 54 == 4x4 48 == 4x3
|
||||
@ -825,7 +828,7 @@ def load_3ds(filename, PREF_UI= True):
|
||||
if BPyMessages.Error_NoFile(filename):
|
||||
return
|
||||
|
||||
print '\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename))
|
||||
print('\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename)))
|
||||
|
||||
time1= Blender.sys.time()
|
||||
|
||||
@ -838,7 +841,7 @@ def load_3ds(filename, PREF_UI= True):
|
||||
# print 'reading the first chunk'
|
||||
read_chunk(file, current_chunk)
|
||||
if (current_chunk.ID!=PRIMARY):
|
||||
print '\tFatal Error: Not a valid 3ds file: ', filename
|
||||
print('\tFatal Error: Not a valid 3ds file: ', filename)
|
||||
file.close()
|
||||
return
|
||||
|
||||
@ -953,17 +956,17 @@ def load_3ds(filename, PREF_UI= True):
|
||||
# Done constraining to bounds.
|
||||
|
||||
# Select all new objects.
|
||||
print 'finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1))
|
||||
print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)))
|
||||
file.close()
|
||||
Blender.Window.WaitCursor(0)
|
||||
|
||||
|
||||
DEBUG= False
|
||||
if __name__=='__main__' and not DEBUG:
|
||||
if calcsize==None:
|
||||
Blender.Draw.PupMenu('Error%t|a full python installation not found')
|
||||
else:
|
||||
Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds')
|
||||
# if __name__=='__main__' and not DEBUG:
|
||||
# if calcsize==None:
|
||||
# Blender.Draw.PupMenu('Error%t|a full python installation not found')
|
||||
# else:
|
||||
# Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds')
|
||||
|
||||
# For testing compatibility
|
||||
#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False)
|
||||
@ -1005,3 +1008,32 @@ else:
|
||||
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
|
||||
|
||||
'''
|
||||
|
||||
class IMPORT_OT_3ds(bpy.types.Operator):
|
||||
'''
|
||||
3DS Importer
|
||||
'''
|
||||
__idname__ = "import.3ds"
|
||||
__label__ = 'Import 3DS'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for importing the 3DS file", maxlen= 1024, default= ""),
|
||||
]
|
||||
|
||||
def execute(self, context):
|
||||
raise Exception("Not doing anything yet.")
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
def poll(self, context): # Poll isnt working yet
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(IMPORT_OT_3ds)
|
||||
|
@ -74,6 +74,7 @@ class INFO_MT_file_import(bpy.types.Menu):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.itemO("import.3ds", text="3DS")
|
||||
layout.itemO("import.obj", text="OBJ")
|
||||
|
||||
class INFO_MT_file_export(bpy.types.Menu):
|
||||
@ -83,9 +84,11 @@ class INFO_MT_file_export(bpy.types.Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.itemO("export.3ds", text="3DS")
|
||||
layout.itemO("export.fbx", text="FBX")
|
||||
layout.itemO("export.obj", text="OBJ")
|
||||
layout.itemO("export.ply", text="PLY")
|
||||
layout.itemO("export.x3d", text="X3D")
|
||||
|
||||
class INFO_MT_file_external_data(bpy.types.Menu):
|
||||
__space_type__ = "USER_PREFERENCES"
|
||||
|
Loading…
Reference in New Issue
Block a user