Info on making a Python script for Blender run in Softimage

Discussions concerning programming of SOFTIMAGE©
User avatar
minilogoguy18
Posts: 110
Joined: 24 Dec 2012, 18:34

Info on making a Python script for Blender run in Softimage

Post by minilogoguy18 » 23 Apr 2013, 02:08

Hi, first off, I'm one of the biggest nubs when it comes to coding/scripting in Softimage. I have a Python script written for Blender to import/export the .md3 format and I'm looking to find out what it would take to use it in Softimage so that I could export to this file type.

Here's the scripts just in case anyone wants to take a quick glance at them...

Code: Select all

__author__ = ["Xembie","PhaethonH","Bob Holcomb","Damien McGinnes","Robert (Tr3B) Beckebans"]
__version__ = '1.4'
__url__ = ["www.blender.org","http://xreal.sourceforge.net","http://www.katsbits.com"]

import math,time,os
from . import md3_encode

def message(log,msg):
  if log:
    log.write(msg + "\n")
  else:
    print(msg)

class md3Settings:
  def __init__(self,
               savepath,
               name,
               logtype,
               dumpall=False,
               ignoreuvs=False,
               scale=1.0,
               offsetx=0.0,
               offsety=0.0,
               offsetz=0.0):
    self.savepath = savepath
    self.name = name
    self.logtype = logtype
    self.dumpall = dumpall
    self.ignoreuvs = ignoreuvs
    self.scale = scale
    self.offsetx = offsetx
    self.offsety = offsety
    self.offsetz = offsetz

def print_md3(log,md3,dumpall):
  message(log,"Header Information")
  message(log,"Ident: " + str(md3.ident))
  message(log,"Version: " + str(md3.version))
  message(log,"Name: " + md3.name)
  message(log,"Flags: " + str(md3.flags))
  message(log,"Number of Frames: " + str(md3.numFrames))
  message(log,"Number of Tags: " + str(md3.numTags))
  message(log,"Number of Surfaces: " + str(md3.numSurfaces))
  message(log,"Number of Skins: " + str(md3.numSkins))
  message(log,"Offset Frames: " + str(md3.ofsFrames))
  message(log,"Offset Tags: " + str(md3.ofsTags))
  message(log,"Offset Surfaces: " + str(md3.ofsSurfaces))
  message(log,"Offset end: " + str(md3.ofsEnd))
  
  if dumpall:
    message(log,"Frames:")
    for f in md3.frames:
      message(log," Mins: " + str(f.mins[0]) + " " + str(f.mins[1]) + " " + str(f.mins[2]))
      message(log," Maxs: " + str(f.maxs[0]) + " " + str(f.maxs[1]) + " " + str(f.maxs[2]))
      message(log," Origin(local): " + str(f.localOrigin[0]) + " " + str(f.localOrigin[1]) + " " + str(f.localOrigin[2]))
      message(log," Radius: " + str(f.radius))
      message(log," Name: " + f.name)

    message(log,"Tags:")
    for t in md3.tags:
      message(log," Name: " + t.name)
      message(log," Origin: " + str(t.origin[0]) + " " + str(t.origin[1]) + " " + str(t.origin[2]))
      message(log," Axis[0]: " + str(t.axis[0]) + " " + str(t.axis[1]) + " " + str(t.axis[2]))
      message(log," Axis[1]: " + str(t.axis[3]) + " " + str(t.axis[4]) + " " + str(t.axis[5]))
      message(log," Axis[2]: " + str(t.axis[6]) + " " + str(t.axis[7]) + " " + str(t.axis[8]))

    message(log,"Surfaces:")
    for s in md3.surfaces:
      message(log," Ident: " + s.ident)
      message(log," Name: " + s.name)
      message(log," Flags: " + str(s.flags))
      message(log," # of Frames: " + str(s.numFrames))
      message(log," # of Shaders: " + str(s.numShaders))
      message(log," # of Verts: " + str(s.numVerts))
      message(log," # of Triangles: " + str(s.numTriangles))
      message(log," Offset Triangles: " + str(s.ofsTriangles))
      message(log," Offset UVs: " + str(s.ofsUV))
      message(log," Offset Verts: " + str(s.ofsVerts))
      message(log," Offset End: " + str(s.ofsEnd))
      message(log," Shaders:")
      for shader in s.shaders:
        message(log,"  Name: " + shader.name)
        message(log,"  Index: " + str(shader.index))
      message(log," Triangles:")
      for tri in s.triangles:
        message(log,"  Indexes: " + str(tri.indexes[0]) + " " + str(tri.indexes[1]) + " " + str(tri.indexes[2]))
      message(log," UVs:")
      for uv in s.uv:
        message(log,"  U: " + str(uv.u))
        message(log,"  V: " + str(uv.v)) 
      message(log," Verts:")
      for vert in s.verts:
        message(log,"  XYZ: " + str(vert.xyz[0]) + " " + str(vert.xyz[1]) + " " + str(vert.xyz[2]))
        message(log,"  Normal: " + str(vert.normal))

  shader_count = 0
  vert_count = 0
  tri_count = 0
  for surface in md3.surfaces:
    shader_count += surface.numShaders
    tri_count += surface.numTriangles
    vert_count += surface.numVerts
    if surface.numShaders >= md3_encode.MD3_MAX_SHADERS:
      message(log,"!Warning: Shader limit (" + str(surface.numShaders) + "/" + str(md3_encode.MD3_MAX_SHADERS) + ") reached for surface " + surface.name)
    if surface.numVerts >= md3_encode.MD3_MAX_VERTICES:
      message(log,"!Warning: Vertex limit (" + str(surface.numVerts) + "/" + str(md3_encode.MD3_MAX_VERTICES) + ") reached for surface " + surface.name)
    if surface.numTriangles >= md3_encode.MD3_MAX_TRIANGLES:
      message(log,"!Warning: Triangle limit (" + str(surface.numTriangles) + "/" + str(md3_encode.MD3_MAX_TRIANGLES) + ") reached for surface " + surface.name)
  
  if md3.numTags >= md3_encode.MD3_MAX_TAGS:
    message(log,"!Warning: Tag limit (" + str(md3.numTags) + "/" + str(md3_encode.MD3_MAX_TAGS) + ") reached for md3!")
  if md3.numSurfaces >= md3_encode.MD3_MAX_SURFACES:
    message(log,"!Warning: Surface limit (" + str(md3.numSurfaces) + "/" + str(md3_encode.MD3_MAX_SURFACES) + ") reached for md3!")
  if md3.numFrames >= md3_encode.MD3_MAX_FRAMES:
    message(log,"!Warning: Frame limit (" + str(md3.numFrames) + "/" + str(md3_encode.MD3_MAX_FRAMES) + ") reached for md3!")
    
  message(log,"Total Shaders: " + str(shader_count))
  message(log,"Total Triangles: " + str(tri_count))
  message(log,"Total Vertices: " + str(vert_count))

def save_md3(settings):
  starttime = time.clock()#start timer
  newlogpath = os.path.splitext(settings.savepath)[0] + ".log"
  if settings.logtype == "append":
    log = open(newlogpath,"a")
  elif settings.logtype == "overwrite":
    log = open(newlogpath,"w")
  else:
    log = 0
  message(log,"######################BEGIN######################")
  message(log,"Exporting selected objects...")
  ##bpy.ops.object.mode_set(mode='OBJECT')
  md3 = md3_encode.md3Object()
  md3.ident = md3_encode.MD3_IDENT
  md3.version = md3_encode.MD3_VERSION
  md3.name = settings.name
  md3.numFrames = (bpy.context.scene.frame_end + 1) - bpy.context.scene.frame_start

  # matrix to apply offset & scale - just calculate once and cache
  import mathutils
  offset_scale_mat = mathutils.Matrix.Translation((settings.offsetx, settings.offsety, settings.offsetz)) * mathutils.Matrix.Scale(settings.scale, 4)
  
  # export all selected meshes, remember empties for later...
  empties = []
  for obj in bpy.context.selected_objects:
    # ...of type mesh
    if obj.type == 'MESH':
      bpy.context.scene.frame_set(bpy.context.scene.frame_start)
      nobj = obj.to_mesh(bpy.context.scene,True,'PREVIEW')
      
      nsurface = md3_encode.md3Surface()
      nsurface.name = obj.name
      nsurface.ident = md3_encode.MD3_IDENT
      
      ignoreuvs = False
      nshader = md3_encode.md3Shader()
      #Add only 1 shader per surface/object
      try:
        #Using custom properties allows a longer string
        nshader.name = obj["md3shader"]
      except:#we should add a blank as a placeholder
        ignoreuvs = True
        nshader.name = "NULL"
      nsurface.shaders.append(nshader)
      nsurface.numShaders = 1
 
      vertlist = []

      for f,face in enumerate(nobj.faces):
        ntri = md3_encode.md3Triangle()
        if len(face.vertices) != 3:
          message(log,"Found a nontriangle face in object " + obj.name)
          continue

        for v,vert_index in enumerate(face.vertices):
          if settings.ignoreuvs or ignoreuvs:
            uv_u = 0
            uv_v = 0
          else:
            uv_u = round(obj.data.uv_textures.active.data[f].uv[v][0],5)
            uv_v = round(obj.data.uv_textures.active.data[f].uv[v][1],5)

          match = 0
          match_index = 0
          for i,vi in enumerate(vertlist):
            if vi == vert_index:
              if settings.ignoreuvs or ignoreuvs:
                match = 1
                match_index = i
              else:
                if nsurface.uv[i].u == uv_u and nsurface.uv[i].v == uv_v:
                  match = 1
                  match_index = i

          if match == 0:
            vertlist.append(vert_index)
            ntri.indexes[v] = nsurface.numVerts
            ntex = md3_encode.md3TexCoord()
            ntex.u = uv_u
            ntex.v = uv_v
            nsurface.uv.append(ntex)
            nsurface.numVerts += 1
          else:
            ntri.indexes[v] = match_index
        nsurface.triangles.append(ntri)
        nsurface.numTriangles += 1

      for frame in range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1):
        bpy.context.scene.frame_set(frame)
        fobj = obj.to_mesh(bpy.context.scene,True,'PREVIEW')
        #fobj.calc_normals()
        # only add new frames once
        if len(md3.frames) <= frame - bpy.context.scene.frame_start:
            nframe = md3_encode.md3Frame()
            nframe.name = str(frame)
        else:
            nframe = md3.frames[frame - bpy.context.scene.frame_start]
        for vi in vertlist:
          vert = fobj.vertices[vi]
          nvert = md3_encode.md3Vert()
          nvert.normal = nvert.Encode(vert.normal)
          nvert.xyz = offset_scale_mat * obj.matrix_world * vert.co
          for i in range(0,3):
            nvert.xyz[i] = round(nvert.xyz[i], 5)
            nframe.mins[i] = min(nframe.mins[i],nvert.xyz[i])
            nframe.maxs[i] = max(nframe.maxs[i],nvert.xyz[i])
          minlength = math.sqrt(math.pow(nframe.mins[0],2) + math.pow(nframe.mins[1],2) + math.pow(nframe.mins[2],2))
          maxlength = math.sqrt(math.pow(nframe.maxs[0],2) + math.pow(nframe.maxs[1],2) + math.pow(nframe.maxs[2],2))
          nframe.radius = round(max(minlength,maxlength),5)
          nsurface.verts.append(nvert) 
        # only add if not already there
        if len(md3.frames) <= frame - bpy.context.scene.frame_start:
            md3.frames.append(nframe)
        nsurface.numFrames += 1
        bpy.data.meshes.remove(fobj)
      print(len(md3.frames), "==", md3.numFrames)
      assert(len(md3.frames) == md3.numFrames)
      md3.surfaces.append(nsurface)
      md3.numSurfaces += 1
      bpy.data.meshes.remove(nobj)

    elif obj.type == 'EMPTY':
      empties.append(obj)
  
  #write empties(=tags) in correct order - tag1frame1, tag2frame1, ..., tag1frame2, tag2frame2, ...
  md3.numTags = len(empties)
  for frame in range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1):
    bpy.context.scene.frame_set(frame)
    for obj in empties:
      ntag = md3_encode.md3Tag()
      ntag.name = obj.name
      ntag.origin[0] = round((obj.matrix_world[0][3] * settings.scale) + settings.offsetx,5)
      ntag.origin[1] = round((obj.matrix_world[1][3] * settings.scale) + settings.offsety,5)
      ntag.origin[2] = round((obj.matrix_world[2][3] * settings.scale) + settings.offsetz,5)
      ntag.axis[0] = obj.matrix_world[0][0]
      ntag.axis[1] = obj.matrix_world[1][0]
      ntag.axis[2] = obj.matrix_world[2][0]
      ntag.axis[3] = obj.matrix_world[0][1]
      ntag.axis[4] = obj.matrix_world[1][1]
      ntag.axis[5] = obj.matrix_world[2][1]
      ntag.axis[6] = obj.matrix_world[0][2]
      ntag.axis[7] = obj.matrix_world[1][2]
      ntag.axis[8] = obj.matrix_world[2][2]
      md3.tags.append(ntag)
  
  if bpy.context.selected_objects:
    file = open(settings.savepath, "wb")
    md3.Save(file)
    print_md3(log,md3,settings.dumpall)
    file.close()
    message(log,"MD3 saved to " + settings.savepath)
    elapsedtime = round(time.clock() - starttime,5)
    message(log,"Elapsed " + str(elapsedtime) + " seconds")
  else:
    message(log,"Select an object to export!")
    
  if log:
    print("Logged to",newlogpath)
    log.close()
    
    


from bpy.props import *
import bpy

class ExportMD3(bpy.types.Operator):
  bl_idname = "export.md3"
  bl_label = "Export MD3"

  logenum = [("console","Console","log to console"),
             ("append","Append","append to log file"),
             ("overwrite","Overwrite","overwrite log file")]

  filepath = StringProperty(subtype = 'FILE_PATH',name="File Path", description="Filepath for exporting", maxlen= 1024, default= "")
  md3name = StringProperty(name="MD3 Name", description="MD3 header name / skin path (64 bytes)",maxlen=64,default="")
  md3logtype = EnumProperty(name="Save log", items=logenum, description="File logging options",default = 'console')
  md3dumpall = BoolProperty(name="Dump all", description="Dump all data for md3 to log",default=False)
  md3ignoreuvs = BoolProperty(name="Ignore UVs", description="Ignores uv influence on mesh generation. Use if uv map not made.",default=False)
  md3scale = FloatProperty(name="Scale", description="Scale all objects from world origin (0,0,0)",default=1.0,precision=5)
  md3offsetx = FloatProperty(name="Offset X", description="Transition scene along x axis",default=0.0,precision=5)
  md3offsety = FloatProperty(name="Offset Y", description="Transition scene along y axis",default=0.0,precision=5)
  md3offsetz = FloatProperty(name="Offset Z", description="Transition scene along z axis",default=0.0,precision=5)

  def execute(self, context):
    settings = md3Settings(savepath = self.properties.filepath,
                           name = self.properties.md3name,
                           logtype = self.properties.md3logtype,
                           dumpall = self.properties.md3dumpall,
                           ignoreuvs = self.properties.md3ignoreuvs,
                           scale = self.properties.md3scale,
                           offsetx = self.properties.md3offsetx,
                           offsety = self.properties.md3offsety,
                           offsetz = self.properties.md3offsetz)
    save_md3(settings)
    return {'FINISHED'}

  def invoke(self, context, event):
    wm = context.window_manager
    wm.fileselect_add(self)
    return {'RUNNING_MODAL'}

Code: Select all

import math,struct
MAX_QPATH = 64

MD3_IDENT = "IDP3"
MD3_VERSION = 15
MD3_MAX_TAGS = 16
MD3_MAX_SURFACES = 32
MD3_MAX_FRAMES = 1024
MD3_MAX_SHADERS = 256
MD3_MAX_VERTICES = 4096
MD3_MAX_TRIANGLES = 8192
MD3_XYZ_SCALE = 64.0

class md3Vert:
	xyz = []
	normal = 0
	binaryFormat = "<3hH"
	
	def __init__(self):
		self.xyz = [0.0, 0.0, 0.0]
		self.normal = 0
		
	def GetSize(self):
		return struct.calcsize(self.binaryFormat)
	
	# copied from PhaethonH <phaethon@linux.ucla.edu> md3.py
	def Decode(self, latlng):
		lat = (latlng >> 8) & 0xFF;
		lng = (latlng) & 0xFF;
		lat *= math.pi / 128;
		lng *= math.pi / 128;
		x = math.cos(lat) * math.sin(lng)
		y = math.sin(lat) * math.sin(lng)
		z =                 math.cos(lng)
		retval = [ x, y, z ]
		return retval
	
	# copied from PhaethonH <phaethon@linux.ucla.edu> md3.py
	def Encode(self, normal):
		x = normal[0]
		y = normal[1]
		z = normal[2]
		# normalize
		l = math.sqrt((x*x) + (y*y) + (z*z))
		if l == 0:
			return 0
		x = x/l
		y = y/l
		z = z/l
		
		if (x == 0.0) & (y == 0.0) :
			if z > 0.0:
				return 0
			else:
				return (128 << 8)
		
		lng = math.acos(z) * 255 / (2 * math.pi)
		lat = math.atan2(y, x) * 255 / (2 * math.pi)
		retval = ((int(lat) & 0xFF) << 8) | (int(lng) & 0xFF)
		return retval
		
	def Save(self, file):
		tmpData = [0] * 4
		tmpData[0] = int(self.xyz[0] * MD3_XYZ_SCALE)
		tmpData[1] = int(self.xyz[1] * MD3_XYZ_SCALE)
		tmpData[2] = int(self.xyz[2] * MD3_XYZ_SCALE)
		tmpData[3] = self.normal
		data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1], tmpData[2], tmpData[3])
		file.write(data)
		
class md3TexCoord:
	u = 0.0
	v = 0.0

	binaryFormat = "<2f"

	def __init__(self):
		self.u = 0.0
		self.v = 0.0
		
	def GetSize(self):
		return struct.calcsize(self.binaryFormat)

	def Save(self, file):
		tmpData = [0] * 2
		tmpData[0] = self.u
		tmpData[1] = 1.0 - self.v
		data = struct.pack(self.binaryFormat, tmpData[0], tmpData[1])
		file.write(data)

class md3Triangle:
	indexes = []

	binaryFormat = "<3i"

	def __init__(self):
		self.indexes = [ 0, 0, 0 ]
		
	def GetSize(self):
		return struct.calcsize(self.binaryFormat)

	def Save(self, file):
		tmpData = [0] * 3
		tmpData[0] = self.indexes[0]
		tmpData[1] = self.indexes[2] # reverse
		tmpData[2] = self.indexes[1] # reverse
		data = struct.pack(self.binaryFormat,tmpData[0], tmpData[1], tmpData[2])
		file.write(data)

class md3Shader:
	name = ""
	index = 0
	
	binaryFormat = "<%dsi" % MAX_QPATH

	def __init__(self):
		self.name = ""
		self.index = 0
		
	def GetSize(self):
		return struct.calcsize(self.binaryFormat)

	def Save(self, file):
		tmpData = [0] * 2
		tmpData[0] = self.name
		tmpData[1] = self.index
		data = struct.pack(self.binaryFormat, tmpData[0].encode('utf-8'), tmpData[1])
		file.write(data)

class md3Surface:
	ident = ""
	name = ""
	flags = 0
	numFrames = 0
	numShaders = 0
	numVerts = 0
	numTriangles = 0
	ofsTriangles = 0
	ofsShaders = 0
	ofsUV = 0
	ofsVerts = 0
	ofsEnd = 0
	shaders = []
	triangles = []
	uv = []
	verts = []
	
	binaryFormat = "<4s%ds10i" % MAX_QPATH  # 1 int, name, then 10 ints
	
	def __init__(self):
		self.ident = ""
		self.name = ""
		self.flags = 0
		self.numFrames = 0
		self.numShaders = 0
		self.numVerts = 0
		self.numTriangles = 0
		self.ofsTriangles = 0
		self.ofsShaders = 0
		self.ofsUV = 0
		self.ofsVerts = 0
		self.ofsEnd
		self.shaders = []
		self.triangles = []
		self.uv = []
		self.verts = []
		
	def GetSize(self):
		sz = struct.calcsize(self.binaryFormat)
		self.ofsShaders = sz
		for s in self.shaders:
			sz += s.GetSize()
		self.ofsTriangles = sz
		for t in self.triangles:
			sz += t.GetSize()
		self.ofsUV = sz
		for u in self.uv:
			sz += u.GetSize()
		self.ofsVerts = sz
		for v in self.verts:
			sz += v.GetSize()
		self.ofsEnd = sz
		return self.ofsEnd
	
	def Save(self, file):
		self.GetSize()
		tmpData = [0] * 12
		tmpData[0] = self.ident
		tmpData[1] = self.name
		tmpData[2] = self.flags
		tmpData[3] = self.numFrames
		tmpData[4] = self.numShaders
		tmpData[5] = self.numVerts
		tmpData[6] = self.numTriangles
		tmpData[7] = self.ofsTriangles
		tmpData[8] = self.ofsShaders
		tmpData[9] = self.ofsUV
		tmpData[10] = self.ofsVerts
		tmpData[11] = self.ofsEnd
		data = struct.pack(self.binaryFormat, tmpData[0].encode('utf-8'),tmpData[1].encode('utf-8'),tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7],tmpData[8],tmpData[9],tmpData[10],tmpData[11])
		file.write(data)

		# save the shader coordinates
		for s in self.shaders:
			s.Save(file)

		# write the tri data
		for t in self.triangles:
			t.Save(file)

		# save the uv info
		for u in self.uv:
			u.Save(file)

		# save the verts
		for v in self.verts:
			v.Save(file)

class md3Tag:
	name = ""
	origin = []
	axis = []
	
	binaryFormat="<%ds3f9f" % MAX_QPATH
	
	def __init__(self):
		self.name = ""
		self.origin = [0, 0, 0]
		self.axis = [0, 0, 0, 0, 0, 0, 0, 0, 0]
		
	def GetSize(self):
		return struct.calcsize(self.binaryFormat)
		
	def Save(self, file):
		tmpData = [0] * 13
		tmpData[0] = self.name
		tmpData[1] = float(self.origin[0])
		tmpData[2] = float(self.origin[1])
		tmpData[3] = float(self.origin[2])
		tmpData[4] = float(self.axis[0])
		tmpData[5] = float(self.axis[1])
		tmpData[6] = float(self.axis[2])
		tmpData[7] = float(self.axis[3])
		tmpData[8] = float(self.axis[4])
		tmpData[9] = float(self.axis[5])
		tmpData[10] = float(self.axis[6])
		tmpData[11] = float(self.axis[7])
		tmpData[12] = float(self.axis[8])
		data = struct.pack(self.binaryFormat, tmpData[0].encode('utf-8'),tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6], tmpData[7], tmpData[8], tmpData[9], tmpData[10], tmpData[11], tmpData[12])
		file.write(data)
	
class md3Frame:
	mins = 0
	maxs = 0
	localOrigin = 0
	radius = 0.0
	name = ""
	
	binaryFormat="<3f3f3ff16s"
	
	def __init__(self):
		self.mins = [0, 0, 0]
		self.maxs = [0, 0, 0]
		self.localOrigin = [0, 0, 0]
		self.radius = 0.0
		self.name = ""
		
	def GetSize(self):
		return struct.calcsize(self.binaryFormat)

	def Save(self, file):
		tmpData = [0] * 11
		tmpData[0] = self.mins[0]
		tmpData[1] = self.mins[1]
		tmpData[2] = self.mins[2]
		tmpData[3] = self.maxs[0]
		tmpData[4] = self.maxs[1]
		tmpData[5] = self.maxs[2]
		tmpData[6] = self.localOrigin[0]
		tmpData[7] = self.localOrigin[1]
		tmpData[8] = self.localOrigin[2]
		tmpData[9] = self.radius
		tmpData[10] = self.name
		data = struct.pack(self.binaryFormat, tmpData[0],tmpData[1],tmpData[2],tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7], tmpData[8], tmpData[9], tmpData[10].encode('utf-8'))
		file.write(data)

class md3Object:
	# header structure
	ident = ""			# this is used to identify the file (must be IDP3)
	version = 0			# the version number of the file (Must be 15)
	name = ""
	flags = 0
	numFrames = 0
	numTags = 0
	numSurfaces = 0
	numSkins = 0
	ofsFrames = 0
	ofsTags = 0
	ofsSurfaces = 0
	ofsEnd = 0
	frames = []
	tags = []
	surfaces = []

	binaryFormat="<4si%ds9i" % MAX_QPATH  # little-endian (<), 4 bytes, 1 ints, 64 bytes, 9 ints

	def __init__(self):
		self.ident = 0
		self.version = 0
		self.name = ""
		self.flags = 0
		self.numFrames = 0
		self.numTags = 0
		self.numSurfaces = 0
		self.numSkins = 0
		self.ofsFrames = 0
		self.ofsTags = 0
		self.ofsSurfaces = 0
		self.ofsEnd = 0
		self.frames = []
		self.tags = []
		self.surfaces = []

	def GetSize(self):
        # frames start after header
		self.ofsFrames = struct.calcsize(self.binaryFormat)
        # tags start after frames
		self.ofsTags = self.ofsFrames
		for f in self.frames:
			self.ofsTags += f.GetSize()
        # surfaces start after tags
		self.ofsSurfaces = self.ofsTags
		for t in self.tags:
			self.ofsSurfaces += t.GetSize()
        # end starts after surfaces
		self.ofsEnd = self.ofsSurfaces
		for s in self.surfaces:
			self.ofsEnd += s.GetSize()
		return self.ofsEnd
		
	def Save(self, file):
		self.GetSize()
		tmpData = [0] * 12
		tmpData[0] = self.ident # 4 bytes
		tmpData[1] = self.version # 1 int
		tmpData[2] = self.name # 64 bytes
		tmpData[3] = self.flags # 9 ints
		tmpData[4] = self.numFrames
		tmpData[5] = self.numTags
		tmpData[6] = self.numSurfaces
        # always 0
		tmpData[7] = self.numSkins
        # calculated in self.GetSize()
		tmpData[8] = self.ofsFrames
		tmpData[9] = self.ofsTags
		tmpData[10] = self.ofsSurfaces
		tmpData[11] = self.ofsEnd

		data = struct.pack(self.binaryFormat, tmpData[0].encode('utf-8'),tmpData[1],tmpData[2].encode('utf-8'),tmpData[3],tmpData[4],tmpData[5],tmpData[6],tmpData[7], tmpData[8], tmpData[9], tmpData[10], tmpData[11])
		file.write(data)

		for f in self.frames:
			f.Save(file)
			
		for t in self.tags:
			t.Save(file)
			
		for s in self.surfaces:
			s.Save(file)

Code: Select all

bl_info = {
  "name": "Quake Model 3 (.md3)",
  "author": "Xembie, PhaethonH, Bob Holcomb, Damien McGinnes, Robert (Tr3B) Beckebans, Mr. Wonko",
  "version": (1, 5, 1),
  "blender": (2, 6, 2),
  "api": 36339,
  "location": "File > Import-Export",
  "description": "Export Quake Model 3",
  "warning": "",
  "wiki_url": "",
  "tracker_url": "http://projects.blender.org/tracker/?func=detail&aid=23160",
  "category": "Import-Export"}
    
if "bpy" in locals():
  import imp
  imp.reload(export_md3_15)
  imp.reload(md3_encode)
else:
  from . import export_md3_15
  from . import md3_encode
        
import bpy,os

def export(self, context):
  newpath = os.path.splitext(bpy.data.filepath)[0] + ".md3"
  self.layout.operator(export_md3_15.ExportMD3.bl_idname, text="Quake Model 3 (.md3)").filepath = newpath

def register():
  bpy.utils.register_module(__name__)
  bpy.types.INFO_MT_file_export.append(export)

def unregister():
  bpy.utils.unregister_module(__name__)
  bpy.types.INFO_MT_file_export.remove(export)

if __name__ == "__main__":
  register()
Any help even in the smallest would be greatly appreciated.

EricTRocks
Moderator
Posts: 754
Joined: 25 Nov 2009, 00:41

Re: Info on making a Python script for Blender run in Softimage

Post by EricTRocks » 24 Apr 2013, 13:42

Python scripts are generally not easily translated from one app to the other as they depend on the application's scripting SDK. A brief look over the code and it seems that this would not be easily translated over and would require a bit of work.
Eric Thivierge
Lead Kraken Developer, Fabric Engine
http://fabric-engine.github.io/Kraken

User avatar
minilogoguy18
Posts: 110
Joined: 24 Dec 2012, 18:34

Re: Info on making a Python script for Blender run in Softimage

Post by minilogoguy18 » 25 Apr 2013, 22:06

Thanks for the info although it isn't the best of news.

The source to this format is available so it could be done in the same fashion as most plugins (C++ I'm guessing) and made as a .dll packaged up in an addon but finding someone who is both interested in having this format for Softimage and knowing how to make it possible at the same time seems unlikely.

Guess I should try to learn how to build a plugin.