iPLEOMAX

[Blender Addon] LWO Exporter V1.1 | io_export_scene_lwo.py

May 12th, 2014
1,401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 17.99 KB | None | 0 0
  1.  
  2. # LightWave Object File exporter for Blender 2.69+
  3. # Copyright (C) 2014  Morshidul Chowdhury
  4.  
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9.  
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14.  
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  
  18. bl_info = {
  19.     "name": "Export LightWave Objects",
  20.     "author": "Morshidul Chowdhury (iPLEOMAX)",
  21.     "version": (1, 1),
  22.     "blender": (2, 6, 9),
  23.     "location": "File > Export > LightWave Object (.lwo)",
  24.     "description": "Exports selected objects to LightWave (.lwo) format",
  25.     "warning": "",
  26.     "category": "Import-Export"
  27. }
  28.  
  29. # http://pleo.code5gaming.com/
  30. # http://blenderartists.org/forum/member.php?220524-iPLEOMAX
  31.  
  32. # This is a complete remake of Anthony D'Agostino's LightWave plugin.
  33.  
  34. # Features in V1.1 (current):
  35. # - Added better material export data
  36. # - Added support for multi-vertex weigths
  37. # - Added support for multi-shape keys
  38. # - Added support for large meshes.
  39. # - Surfaces are exported as 'smooth' by default, you need to set flat ones by yourself.
  40. # - Fixed other bugs that would cause failed imports.
  41. #
  42. # Features in V1.0 (old):
  43. # - Creates an extra '.lwo' option in export menu.
  44. # - Links all image paths to the lightwave file.
  45. # - Supports multi-surfaces (although there are some incompatibility issues)
  46. # - Supports multi-meshes.
  47. # - Supports multi-uv layers.
  48. # - Supports multi-vertex colors.
  49.  
  50. import bpy
  51. import io
  52. import struct
  53. import time
  54. import operator
  55. from functools import reduce
  56.  
  57. LWO_VCOLOR_MATERIAL = "LWO.VColorMaterial"
  58. LWO_DEFAULT_MATERIAL = "LWO.DefaultMaterial"
  59. LWO_ACTIVE_UV = "LWO.ActiveUV"
  60. LWO_ACTIVE_VC = "LWO.ActiveVCol"
  61. LWO_ACTIVE_VG = "LWO.ActiveVGroup"
  62. LWO_ACTIVE_EM = "LWO.ActiveMorph"
  63.  
  64. # Function from Scorpius's Plugin (Terminates the string and keeps the length even)
  65. def lwopad(str):
  66.     if len(str) % 2: str += '\0' #odd
  67.     else: str += '\0\0' #even
  68.     return str
  69.  
  70. # Function from Scorpius's Plugin (Decides whether to occupy a 4byte or 2byte space in file)
  71. def generate_vx(index):
  72.     if index < 0xFF00:
  73.         value = struct.pack(">H", index)                 # 2-byte index
  74.     else:
  75.         value = struct.pack(">L", index | 0xFF000000)    # 4-byte index
  76.     return value
  77.    
  78. def get_materials(meshes):
  79.     print("\t- Collecting materials..")
  80.     materials = []
  81.     for mesh in meshes:
  82.         if mesh.materials:
  83.             for mat in mesh.materials:
  84.                 if mat:
  85.                     if not mat.name in materials:
  86.                         materials.append(mat.name)
  87.         elif mesh.vertex_colors:
  88.             if not LWO_VCOLOR_MATERIAL in materials:
  89.                 materials.append(LWO_VCOLOR_MATERIAL)
  90.         else:
  91.             if not LWO_DEFAULT_MATERIAL in materials:
  92.                 materials.append(LWO_DEFAULT_MATERIAL)
  93.     return materials
  94.    
  95. def get_tags(materials):
  96.     print("\t- Generating tags..")
  97.     data = io.BytesIO()
  98.     for mat in materials:
  99.         data.write(bytes(lwopad(mat), 'UTF-8'))
  100.     return data.getvalue()
  101.  
  102. def get_layr(mesh, index, pivot):
  103.     print("\t- Generating layer for mesh '" + mesh.name + "'")
  104.     data = io.BytesIO()
  105.     data.write(struct.pack(">h", index))
  106.     data.write(struct.pack(">h", 0))
  107.     data.write(struct.pack(">fff", pivot.x, pivot.z, pivot.y))
  108.     data.write(bytes(lwopad(mesh.name), 'UTF-8'))
  109.     return data.getvalue()
  110.    
  111. def get_pnts(mesh):
  112.     print("\t- Generating vertices for mesh '" + mesh.name + "'")
  113.     data = io.BytesIO()
  114.     for v in mesh.vertices:
  115.         x, y, z = v.co
  116.         data.write(struct.pack(">fff", x, z, y))
  117.     return data.getvalue()
  118.    
  119. def get_bbox(mesh):
  120.     print("\t- Generating bounding box for mesh '" + mesh.name + "'")
  121.     data = io.BytesIO()
  122.     if mesh.vertices:
  123.         nv = [v.co for v in mesh.vertices]
  124.         xx = [ co[0] for co in nv ]
  125.         yy = [ co[1] for co in nv ]
  126.         zz = [ co[2] for co in nv ]
  127.     else:
  128.         xx = yy = zz = [0.0,]
  129.    
  130.     data.write(struct.pack(">6f", min(xx), min(zz), min(yy), max(xx), max(zz), max(yy)))
  131.     return data.getvalue()
  132.    
  133. def get_vmad_uv(mesh, uvlayer, activelayername):
  134.     print("\t\tUV Layer: '" + uvlayer.name + "'")
  135.     data = io.BytesIO()
  136.     data.write(b"TXUV")
  137.     data.write(struct.pack(">H", 2))
  138.    
  139.     if uvlayer.name == activelayername:
  140.         uvname = lwopad(LWO_ACTIVE_UV)
  141.         data.write(bytes(uvname, 'UTF-8'))
  142.     else:
  143.         uvname = lwopad(uvlayer.name)
  144.         data.write(bytes(uvname, 'UTF-8'))
  145.        
  146.     for face in mesh.polygons:
  147.         for vert, loop in zip(face.vertices, face.loop_indices):
  148.             uv = uvlayer.data[loop].uv
  149.             #data.write(struct.pack(">H", vert))
  150.             #data.write(struct.pack(">H", face.index))
  151.             data.write(generate_vx(vert))
  152.             data.write(generate_vx(face.index))
  153.             data.write(struct.pack(">ff", uv.x, uv.y))
  154.     return data.getvalue()
  155.  
  156. def get_vmad_vc(mesh, vclayer, activevcname):
  157.     print("\t\tVCOL Layer: '" + vclayer.name + "'")
  158.     data = io.BytesIO()
  159.     data.write(b"RGB ")
  160.     data.write(struct.pack(">H", 3))
  161.    
  162.     if vclayer.name == activevcname:
  163.         vcname = lwopad(LWO_ACTIVE_VC)
  164.         data.write(bytes(vcname, 'UTF-8'))
  165.     else:
  166.         vcname = lwopad(vclayer.name)
  167.         data.write(bytes(vcname, 'UTF-8'))
  168.        
  169.     for face in mesh.polygons:
  170.         for vert, loop in zip(face.vertices, face.loop_indices):
  171.             color =  vclayer.data[loop].color
  172.             #data.write(struct.pack(">H", vert))
  173.             #data.write(struct.pack(">H", face.index))
  174.             data.write(generate_vx(vert))
  175.             data.write(generate_vx(face.index))
  176.             data.write(struct.pack(">fff", color.r, color.g, color.b))
  177.     return data.getvalue()
  178.  
  179. def get_vmap_vg(mesh, vglayer, activevgname):
  180.     print("\t\tVertex Group Layer: '" + vglayer.name + "'")
  181.     data = io.BytesIO()
  182.     data.write(b"WGHT")
  183.     data.write(struct.pack(">H", 1))
  184.    
  185.     if vglayer.name == activevgname:
  186.         vcname = lwopad(LWO_ACTIVE_VG)
  187.         data.write(bytes(vcname, 'UTF-8'))
  188.     else:
  189.         vgname = lwopad(vglayer.name)
  190.         data.write(bytes(vgname, 'UTF-8'))
  191.    
  192.     for v in mesh.vertices:
  193.         w = 0.0
  194.         try:
  195.             w =  vglayer.weight(v.index)
  196.         except:
  197.             pass
  198.         data.write(generate_vx(v.index))
  199.         data.write(struct.pack(">f", w))
  200.        
  201.     return data.getvalue()
  202.  
  203. def get_vmap_em(mesh, emlayer, activeemname):
  204.     print("\t\tShape Keys Layer: '" + emlayer.name + "'")
  205.     data = io.BytesIO()
  206.     data.write(b"MORF")
  207.     data.write(struct.pack(">H", 3))
  208.    
  209.     if emlayer.name == LWO_ACTIVE_EM:
  210.         emname = lwopad(LWO_ACTIVE_EM)
  211.         data.write(bytes(emname, 'UTF-8'))
  212.     else:
  213.         emname = lwopad(emlayer.name)
  214.         data.write(bytes(emname, 'UTF-8'))
  215.    
  216.     for v in mesh.vertices:
  217.         x, y, z = emlayer.data[v.index].co - v.co
  218.         data.write(generate_vx(v.index))
  219.         data.write(struct.pack(">fff", x, z, y))
  220.    
  221.     return data.getvalue()
  222.    
  223. def get_pols(mesh):
  224.     print("\t- Generating polygons for mesh '" + mesh.name + "'")
  225.     data = io.BytesIO()
  226.     data.write(b"FACE")
  227.     for face in mesh.polygons:
  228.         data.write(struct.pack(">H", face.loop_total))
  229.         for v in range(face.loop_total - 1, -1, -1):
  230.             data.write(generate_vx(face.vertices[v]))
  231.     return data.getvalue()
  232.    
  233. def get_ptag(mesh, materials):
  234.     print("\t- Generating per poly materials for mesh '" + mesh.name + "'")
  235.     data = io.BytesIO()
  236.     data.write(b"SURF")
  237.     for poly in mesh.polygons:
  238.         if mesh.materials:
  239.             matindex = poly.material_index
  240.             matname = mesh.materials[matindex].name
  241.             surfindex = materials.index(matname)
  242.            
  243.             data.write(generate_vx(poly.index))
  244.             data.write(struct.pack(">H", surfindex))
  245.         else:
  246.             data.write(generate_vx(poly.index))
  247.             data.write(struct.pack(">H", 0))
  248.     return data.getvalue()
  249.    
  250. def get_clip(image, clipid):
  251.     print("\t\tImage: '" + image.name + "'")
  252.     data = io.BytesIO()
  253.     path = image.filepath
  254.     path = path[0:2] + path.replace("\\", "/")[3:]
  255.     image = lwopad(path)
  256.     data.write(struct.pack(">L", clipid))
  257.     data.write(b"STIL")
  258.     data.write(struct.pack(">H", len(image)))
  259.     data.write(bytes(image, 'UTF-8'))
  260.     return data.getvalue()
  261.  
  262. def get_imap():
  263.     data = io.BytesIO()
  264.     data.write(struct.pack(">H", 0))
  265.     data.write(b"CHAN")
  266.     data.write(struct.pack(">H", 4))
  267.     data.write(b"COLR")
  268.     data.write(b"OPAC")
  269.     data.write(struct.pack(">H", 8))
  270.     data.write(struct.pack(">H", 0))
  271.     data.write(struct.pack(">f", 1.0))
  272.     data.write(struct.pack(">H", 0))
  273.     data.write(b"ENAB")
  274.     data.write(struct.pack(">HH", 2, 1))
  275.     data.write(b"NEGA")
  276.     data.write(struct.pack(">HH", 2, 0))
  277.     data.write(b"AXIS")
  278.     data.write(struct.pack(">HH", 2, 1))
  279.     return data.getvalue()
  280.  
  281. def create_custom_surf(mat):
  282.     print("\t\tCustom Surface: '" + mat.name + "'")
  283.     data = io.BytesIO()
  284.     data.write(bytes(lwopad(mat.name), 'UTF-8'))
  285.    
  286.     R = mat.diffuse_color.r
  287.     G = mat.diffuse_color.g
  288.     B = mat.diffuse_color.b
  289.     Diff = mat.diffuse_intensity
  290.     Lumi = mat.emit
  291.     Spec = mat.specular_intensity
  292.  
  293.     data.write(b"COLR")
  294.     data.write(struct.pack(">H", 0))
  295.    
  296.     data.write(b"COLR")
  297.     data.write(struct.pack(">H", 14))
  298.     data.write(struct.pack(">fffH", R, G, B, 0))
  299.  
  300.     data.write(b"DIFF")
  301.     data.write(struct.pack(">H", 6))
  302.     data.write(struct.pack(">fH", Diff, 0))
  303.  
  304.     data.write(b"LUMI")
  305.     data.write(struct.pack(">H", 6))
  306.     data.write(struct.pack(">fH", Lumi, 0))
  307.  
  308.     data.write(b"SPEC")
  309.     data.write(struct.pack(">H", 6))
  310.     data.write(struct.pack(">fH", Spec, 0))
  311.  
  312.     data.write(b"GLOS")
  313.     data.write(struct.pack(">H", 6))
  314.     gloss = 50 / (255/2.0)
  315.     gloss = round(gloss, 1)
  316.     data.write(struct.pack(">fH", gloss, 0))
  317.    
  318.     data.write(b"SMAN")
  319.     data.write(struct.pack(">H", 4))
  320.     data.write(struct.pack(">f", 1.5))
  321.    
  322.     if mat and mat.node_tree and mat.node_tree.nodes:
  323.         for node in mat.node_tree.nodes:
  324.             if node:
  325.                 if node.type == 'TEX_IMAGE':
  326.                     data.write(b"BLOK")
  327.                     data.write(struct.pack(">H", 104))
  328.                     imap = get_imap()
  329.                     data.write(b"IMAP")
  330.                     data.write(struct.pack(">H", len(imap)))
  331.                     data.write(imap)
  332.                    
  333.                     data.write(b"IMAG")
  334.                     data.write(struct.pack(">HH", 2, 1))
  335.                     data.write(b"PROJ")
  336.                     data.write(struct.pack(">HH", 2, 5))
  337.                     data.write(b"VMAP")
  338.                     uvname = lwopad(LWO_ACTIVE_UV)
  339.                     data.write(struct.pack(">H", len(uvname)))
  340.                     data.write(bytes(uvname, 'UTF-8'))
  341.    
  342.     data.write(b"VCOL")
  343.     data.write(struct.pack(">H", 34))
  344.     data.write(struct.pack(">fH4s", 1.0, 0, b"RGB "))
  345.     data.write(bytes(lwopad(LWO_ACTIVE_VC), 'UTF-8'))
  346.     return data.getvalue()
  347.  
  348. def create_vcolor_surf():
  349.     print("\t\Vertex Color Surface")
  350.     data = io.BytesIO()
  351.     data.write(bytes(lwopad(LWO_VCOLOR_MATERIAL), 'UTF-8'))
  352.    
  353.     R = 1.0
  354.     G = 1.0
  355.     B = 1.0
  356.    
  357.     data.write(b"COLR")
  358.     data.write(struct.pack(">H", 0))
  359.    
  360.     data.write(b"COLR")
  361.     data.write(struct.pack(">H", 14))
  362.     data.write(struct.pack(">fffH", R, G, B, 0))
  363.  
  364.     data.write(b"DIFF")
  365.     data.write(struct.pack(">H", 6))
  366.     data.write(struct.pack(">fH", 0.8, 0))
  367.  
  368.     data.write(b"LUMI")
  369.     data.write(struct.pack(">H", 6))
  370.     data.write(struct.pack(">fH", 0.0, 0))
  371.  
  372.     data.write(b"SPEC")
  373.     data.write(struct.pack(">H", 6))
  374.     data.write(struct.pack(">fH", 0.0, 0))
  375.  
  376.     data.write(b"SMAN")
  377.     data.write(struct.pack(">H", 4))
  378.     data.write(struct.pack(">f", 1.5))
  379.    
  380.     data.write(b"VCOL")
  381.     data.write(struct.pack(">H", 34))
  382.     data.write(struct.pack(">fH4s", 1.0, 0, b"RGB "))
  383.     data.write(bytes(lwopad(LWO_ACTIVE_VC), 'UTF-8'))
  384.    
  385.     return data.getvalue() 
  386.  
  387. def create_surf(matname):
  388.     print("\t\tDefault Surface: '" + matname + "'")
  389.     data = io.BytesIO()
  390.     data.write(bytes(lwopad(matname), 'UTF-8'))
  391.    
  392.     R = 0.9
  393.     G = 0.9
  394.     B = 0.9
  395.    
  396.     data.write(b"COLR")
  397.     data.write(struct.pack(">H", 0))
  398.    
  399.     data.write(b"COLR")
  400.     data.write(struct.pack(">H", 14))
  401.     data.write(struct.pack(">fffH", R, G, B, 0))
  402.  
  403.     data.write(b"DIFF")
  404.     data.write(struct.pack(">H", 6))
  405.     data.write(struct.pack(">fH", 0.8, 0))
  406.  
  407.     data.write(b"LUMI")
  408.     data.write(struct.pack(">H", 6))
  409.     data.write(struct.pack(">fH", 0.0, 0))
  410.  
  411.     data.write(b"SPEC")
  412.     data.write(struct.pack(">H", 6))
  413.     data.write(struct.pack(">fH", 0.4, 0))
  414.  
  415.     data.write(b"GLOS")
  416.     data.write(struct.pack(">H", 6))
  417.     gloss = 50 / (255/2.0)
  418.     gloss = round(gloss, 1)
  419.     data.write(struct.pack(">fH", gloss, 0))
  420.    
  421.     data.write(b"SMAN")
  422.     data.write(struct.pack(">H", 4))
  423.     data.write(struct.pack(">f", 1.5))
  424.    
  425.     return data.getvalue()
  426.    
  427. def get_surf(matname):
  428.     matid = bpy.data.materials.find(matname)
  429.     if matid != -1:
  430.         return create_custom_surf(bpy.data.materials[matid])
  431.     else:
  432.         if matname == LWO_VCOLOR_MATERIAL:
  433.             return create_vcolor_surf()
  434.     return create_surf(matname)
  435.    
  436. def get_header(chunks):
  437.     print("\t- Generating headers..")
  438.     data = io.BytesIO()
  439.     chunk_sizes = map(len, chunks)
  440.     chunk_sizes = reduce(operator.add, chunk_sizes)
  441.     form_size = chunk_sizes + len(chunks)*8 + len("FORM")
  442.     data.write(b"FORM")
  443.     data.write(struct.pack(">L", form_size))
  444.     data.write(b"LWO2")
  445.     return data.getvalue()
  446.    
  447. def write_lwo(filepath):
  448.    
  449.     print("LWO exporter started..")
  450.     start = time.time()
  451.    
  452.     try:
  453.         bpy.ops.object.mode_set()
  454.     except:
  455.         pass
  456.    
  457.     if not bpy.context.selected_objects:
  458.         print("Please select an object before exporting.")
  459.         return
  460.    
  461.     meshes = []
  462.     pivots = {}
  463.     vgroups = {}
  464.     activeshapekey = {}
  465.     shapekeys = {}
  466.    
  467.     print("\t- Collecting meshes..")
  468.     for obj in bpy.context.selected_objects:
  469.         if obj.type == 'MESH':
  470.             mesh = obj.to_mesh(bpy.context.scene, True, 'PREVIEW')
  471.             mesh.transform(obj.matrix_world)
  472.             mesh.calc_normals()
  473.             meshes.append(mesh)
  474.             pivots[mesh] = obj.location
  475.             if obj.vertex_groups:
  476.                 vgroups[mesh] = obj.vertex_groups
  477.             if not obj.modifiers and obj.active_shape_key:
  478.                 activeshapekey[mesh] = obj.active_shape_key.name
  479.                 shapekeys[mesh] = obj.data.shape_keys
  480.             print("\t\tMesh: " + mesh.name)
  481.     del obj
  482.  
  483.     if not meshes:
  484.         print("\tThere are no meshes in your selection.")
  485.         return
  486.    
  487.     materials = get_materials(meshes)
  488.     tags = get_tags(materials)
  489.    
  490.     chunks = [tags]
  491.     meshdata = io.BytesIO()
  492.     meshindex = 0
  493.    
  494.     for mesh in meshes:
  495.         layr = get_layr(mesh, meshindex, pivots[mesh])
  496.         meshindex += 1
  497.         meshdata.write(b"LAYR")
  498.         meshdata.write(struct.pack(">L", len(layr)))
  499.         meshdata.write(layr)
  500.         chunks.append(layr)
  501.        
  502.         pnts = get_pnts(mesh)
  503.         meshdata.write(b"PNTS")
  504.         meshdata.write(struct.pack(">L", len(pnts)))
  505.         meshdata.write(pnts)
  506.         chunks.append(pnts)
  507.        
  508.         bbox = get_bbox(mesh)
  509.         meshdata.write(b"BBOX")
  510.         meshdata.write(struct.pack(">L", len(bbox)))
  511.         meshdata.write(bbox)
  512.         chunks.append(bbox)
  513.        
  514.         pols = get_pols(mesh)
  515.         meshdata.write(b"POLS")
  516.         meshdata.write(struct.pack(">L", len(pols)))
  517.         meshdata.write(pols)
  518.         chunks.append(pols)
  519.        
  520.         ptag = get_ptag(mesh, materials)
  521.         meshdata.write(b"PTAG")
  522.         meshdata.write(struct.pack(">L", len(ptag)))
  523.         meshdata.write(ptag)
  524.         chunks.append(ptag)
  525.  
  526.         if mesh.uv_layers:
  527.             print("\t- Generating UV layers for mesh '" + mesh.name + "'")
  528.             for uvlayer in mesh.uv_layers:
  529.                 vmad = get_vmad_uv(mesh, uvlayer, mesh.uv_layers.active.name)
  530.                 meshdata.write(b"VMAD")
  531.                 meshdata.write(struct.pack(">L", len(vmad)))
  532.                 meshdata.write(vmad)
  533.                 chunks.append(vmad)
  534.        
  535.         clipid = 1
  536.        
  537.         print("\t- Generating Images for mesh '" + mesh.name + "'")
  538.         for mat in mesh.materials:
  539.             if mat and mat.node_tree and mat.node_tree.nodes:
  540.                 for node in mat.node_tree.nodes:
  541.                     if node:
  542.                         if node.type == 'TEX_IMAGE':
  543.                             clip = get_clip(node.image, clipid)
  544.                             meshdata.write(b"CLIP")
  545.                             meshdata.write(struct.pack(">L", len(clip)))
  546.                             meshdata.write(clip)
  547.                             chunks.append(clip)
  548.                             clipid += 1
  549.        
  550.         if mesh.vertex_colors:
  551.             print("\t- Generating Vertex colors for mesh '" + mesh.name + "'")
  552.             for vclayer in mesh.vertex_colors:
  553.                 vmad = get_vmad_vc(mesh, vclayer, mesh.vertex_colors.active.name)
  554.                 meshdata.write(b"VMAD")
  555.                 meshdata.write(struct.pack(">L", len(vmad)))
  556.                 meshdata.write(vmad)
  557.                 chunks.append(vmad)
  558.        
  559.         if mesh in vgroups:
  560.             if len(vgroups[mesh]):
  561.                 print("\t- Generating Vertex groups for mesh '" + mesh.name + "'")
  562.                 for vglayer in vgroups[mesh]:
  563.                     vmap = get_vmap_vg(mesh, vglayer,  vgroups[mesh].active.name)
  564.                     meshdata.write(b"VMAP")
  565.                     meshdata.write(struct.pack(">L", len(vmap)))
  566.                     meshdata.write(vmap)
  567.                     chunks.append(vmap)
  568.        
  569.         if mesh in activeshapekey:
  570.             if mesh in shapekeys:
  571.                 print("\t- Generating Key Blocks for mesh '" + mesh.name + "'")
  572.                 for emlayer in shapekeys[mesh].key_blocks:
  573.                     vmap = get_vmap_em(mesh, emlayer, activeshapekey[mesh])
  574.                     meshdata.write(b"VMAP")
  575.                     meshdata.write(struct.pack(">L", len(vmap)))
  576.                     meshdata.write(vmap)
  577.                     chunks.append(vmap)
  578.                    
  579.         bpy.data.meshes.remove(mesh)
  580.    
  581.     print("\t- Generating Surfaces")
  582.     for mat in materials:
  583.         surf = get_surf(mat)
  584.         meshdata.write(b"SURF")
  585.         meshdata.write(struct.pack(">L", len(surf)))
  586.         meshdata.write(surf)
  587.         chunks.append(surf)
  588.    
  589.     header = get_header(chunks)
  590.    
  591.     if not filepath.lower().endswith('.lwo'): filepath += '.lwo'
  592.     file = open(filepath, 'wb')
  593.    
  594.     file.write(header)
  595.    
  596.     file.write(b"TAGS")
  597.     file.write(struct.pack(">L", len(tags)))
  598.     file.write(tags)
  599.    
  600.     file.write(meshdata.getvalue())
  601.     meshdata.close()
  602.    
  603.     file.close()
  604.    
  605.     print("LWO exporter ended in %.03f seconds!" % (time.time() - start))
  606.    
  607. from bpy_extras.io_utils import ExportHelper
  608. from bpy.props import StringProperty, BoolProperty, EnumProperty
  609.  
  610. class EXPORT_OT_lwo(bpy.types.Operator, ExportHelper):
  611.     bl_idname= "export_scene.lwo"
  612.     bl_label= "Export LWO"
  613.     bl_description= "Export a LightWave Object file"
  614.     bl_options= {'REGISTER'}
  615.    
  616.     filename_ext = ".lwo"
  617.     filter_glob = StringProperty(default = "*.lwo", options = {'HIDDEN'})
  618.    
  619.     def execute(self, context):
  620.         write_lwo(self.filepath)
  621.         return {'FINISHED'}
  622.    
  623.     def invoke(self, context, event):
  624.         wm = context.window_manager
  625.         wm.fileselect_add(self)
  626.         return {'RUNNING_MODAL'}
  627.    
  628. def menu_func(self, context):
  629.     self.layout.operator(EXPORT_OT_lwo.bl_idname, text="LightWave Object (.lwo)")
  630.  
  631.  
  632. def register():
  633.     bpy.utils.register_module(__name__)
  634.     bpy.types.INFO_MT_file_export.append(menu_func)
  635.  
  636.  
  637. def unregister():
  638.     bpy.utils.unregister_module(__name__)
  639.     bpy.types.INFO_MT_file_export.remove(menu_func)
  640.  
  641. if __name__ == "__main__":
  642.     register()
Advertisement
Add Comment
Please, Sign In to add comment