Skip to content
Snippets Groups Projects
io_import_scene_lwo.py 42.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • Ken Nign's avatar
    Ken Nign committed
            if surf_data.refl != 0.0:
                surf_data.bl_mat.raytrace_mirror.use= True
            surf_data.bl_mat.raytrace_mirror.reflect_factor= surf_data.refl
            surf_data.bl_mat.raytrace_mirror.gloss_factor= 1.0-surf_data.rblr
            if surf_data.tran != 0.0:
                surf_data.bl_mat.use_transparency= True
                surf_data.bl_mat.transparency_method= 'RAYTRACE'
            surf_data.bl_mat.alpha= 1.0 - surf_data.tran
            surf_data.bl_mat.raytrace_transparency.ior= surf_data.rind
            surf_data.bl_mat.raytrace_transparency.gloss_factor= 1.0 - surf_data.tblr
            surf_data.bl_mat.translucency= surf_data.trnl
    
            surf_data.bl_mat.specular_hardness= int(4*((10*surf_data.glos)*(10*surf_data.glos)))+4
            # The Gloss is as close as possible given the differences.
    
    
    Ken Nign's avatar
    Ken Nign committed
        # Single layer objects use the object file's name instead.
        if len(object_layers) and object_layers[-1].name == 'Layer 1':
            object_layers[-1].name= object_name
    
            print("Building '%s' Object" % object_name)
    
    Ken Nign's avatar
    Ken Nign committed
        else:
    
            print("Building %d Objects" % len(object_layers))
    
    Ken Nign's avatar
    Ken Nign committed
        # Before adding any meshes or armatures go into Object mode.
        if bpy.ops.object.mode_set.poll():
            bpy.ops.object.mode_set(mode='OBJECT')
    
    
    Ken Nign's avatar
    Ken Nign committed
        for layer_data in object_layers:
    
            me= bpy.data.meshes.new(layer_data.name)
    
    Ken Nign's avatar
    Ken Nign committed
            me.vertices.add(len(layer_data.pnts))
            me.faces.add(len(layer_data.pols))
    
            # for vi in range(len(layer_data.pnts)):
            #     me.vertices[vi].co= layer_data.pnts[vi]
    
            # faster, would be faster again to use an array
    
            me.vertices.foreach_set("co", [axis for co in layer_data.pnts for axis in co])
    
    Ken Nign's avatar
    Ken Nign committed
            ngons= {}   # To keep the FaceIdx consistant, handle NGons later.
    
            edges= []   # Holds the FaceIdx of the 2-point polys.
    
            for fi, fpol in enumerate(layer_data.pols):
    
                fpol.reverse()   # Reversing gives correct normal directions
    
    Ken Nign's avatar
    Ken Nign committed
                # PointID 0 in the last element causes Blender to think it's un-used.
    
                if fpol[-1] == 0:
                    fpol.insert(0, fpol[-1])
                    del fpol[-1]
    
    Ken Nign's avatar
    Ken Nign committed
                if vlen == 3 or vlen == 4:
                    for i in range(vlen):
    
                        me.faces[fi].vertices_raw[i]= fpol[i]
    
    Ken Nign's avatar
    Ken Nign committed
                elif vlen == 2:
    
    Ken Nign's avatar
    Ken Nign committed
                elif vlen != 1:
    
                    ngons[fi]= fpol  # Deal with them later
    
    Ken Nign's avatar
    Ken Nign committed
            ob= bpy.data.objects.new(layer_data.name, me)
            bpy.context.scene.objects.link(ob)
            ob_dict[layer_data.index]= [ob, layer_data.parent_index]
    
    Ken Nign's avatar
    Ken Nign committed
            # Move the object so the pivot is in the right place.
    
            ob.location= layer_data.pivot
    
    Ken Nign's avatar
    Ken Nign committed
            # Create the Material Slots and assign the MatIndex to the correct faces.
            mat_slot= 0
            for surf_key in layer_data.surf_tags:
                if object_tags[surf_key] in object_surfs:
                    me.materials.append(object_surfs[object_tags[surf_key]].bl_mat)
    
    Ken Nign's avatar
    Ken Nign committed
                    for fi in layer_data.surf_tags[surf_key]:
                        me.faces[fi].material_index= mat_slot
                        me.faces[fi].use_smooth= object_surfs[object_tags[surf_key]].smooth
    
    Ken Nign's avatar
    Ken Nign committed
                    mat_slot+=1
    
    Ken Nign's avatar
    Ken Nign committed
            # Create the Vertex Groups (LW's Weight Maps).
            if len(layer_data.wmaps) > 0:
    
                print("Adding %d Vertex Groups" % len(layer_data.wmaps))
    
    Ken Nign's avatar
    Ken Nign committed
                for wmap_key in layer_data.wmaps:
                    vgroup= ob.vertex_groups.new()
                    vgroup.name= wmap_key
                    wlist= layer_data.wmaps[wmap_key]
                    for pvp in wlist:
    
                        vgroup.add((pvp[0], ), pvp[1], 'REPLACE')
    
    Ken Nign's avatar
    Ken Nign committed
            # Create the Shape Keys (LW's Endomorphs).
            if len(layer_data.morphs) > 0:
    
                print("Adding %d Shapes Keys" % len(layer_data.morphs))
    
                ob.shape_key_add('Basis')   # Got to have a Base Shape.
    
    Ken Nign's avatar
    Ken Nign committed
                for morph_key in layer_data.morphs:
    
                    skey= ob.shape_key_add(morph_key)
    
    Ken Nign's avatar
    Ken Nign committed
                    dlist= layer_data.morphs[morph_key]
                    for pdp in dlist:
    
                        me.shape_keys.keys[skey.name].data[pdp[0]].co= [pdp[1], pdp[2], pdp[3]]
    
    
    Ken Nign's avatar
    Ken Nign committed
            # Create the Vertex Color maps.
            if len(layer_data.colmaps) > 0:
    
                print("Adding %d Vertex Color Maps" % len(layer_data.colmaps))
    
    Ken Nign's avatar
    Ken Nign committed
                for cmap_key in layer_data.colmaps:
                    map_pack= create_mappack(layer_data, cmap_key, "COLOR")
                    vcol= me.vertex_colors.new(cmap_key)
                    if not vcol:
                        break
                    for fi in map_pack:
                        if fi > len(vcol.data):
                            continue
                        face= map_pack[fi]
                        colf= vcol.data[fi]
    
    Ken Nign's avatar
    Ken Nign committed
                        if len(face) > 2:
                            colf.color1= face[0]
                            colf.color2= face[1]
                            colf.color3= face[2]
                        if len(face) == 4:
                            colf.color4= face[3]
    
    Ken Nign's avatar
    Ken Nign committed
            # Create the UV Maps.
            if len(layer_data.uvmaps) > 0:
    
                print("Adding %d UV Textures" % len(layer_data.uvmaps))
    
    Ken Nign's avatar
    Ken Nign committed
                for uvmap_key in layer_data.uvmaps:
                    map_pack= create_mappack(layer_data, uvmap_key, "UV")
                    uvm= me.uv_textures.new(uvmap_key)
                    if not uvm:
                        break
                    for fi in map_pack:
                        if fi > len(uvm.data):
                            continue
                        face= map_pack[fi]
                        uvf= uvm.data[fi]
    
    Ken Nign's avatar
    Ken Nign committed
                        if len(face) > 2:
                            uvf.uv1= face[0]
                            uvf.uv2= face[1]
                            uvf.uv3= face[2]
                        if len(face) == 4:
                            uvf.uv4= face[3]
    
            # Now add the NGons.
            if len(ngons) > 0:
                for ng_key in ngons:
                    face_offset= len(me.faces)
                    ng= ngons[ng_key]
                    v_locs= []
                    for vi in range(len(ng)):
                        v_locs.append(mathutils.Vector(layer_data.pnts[ngons[ng_key][vi]]))
    
                    tris= tesselate_polygon([v_locs])
    
    Ken Nign's avatar
    Ken Nign committed
                    me.faces.add(len(tris))
                    for tri in tris:
                        face= me.faces[face_offset]
                        face.vertices_raw[0]= ng[tri[0]]
                        face.vertices_raw[1]= ng[tri[1]]
                        face.vertices_raw[2]= ng[tri[2]]
                        face.material_index= me.faces[ng_key].material_index
                        face.use_smooth= me.faces[ng_key].use_smooth
                        face_offset+= 1
    
    
            # FaceIDs are no longer a concern, so now update the mesh.
            has_edges= len(edges) > 0 or len(layer_data.edge_weights) > 0
    
            me.update(calc_edges=has_edges)
    
    
            # Add the edges.
            edge_offset= len(me.edges)
            me.edges.add(len(edges))
            for edge_fi in edges:
                me.edges[edge_offset].vertices[0]= layer_data.pols[edge_fi][0]
                me.edges[edge_offset].vertices[1]= layer_data.pols[edge_fi][1]
                edge_offset+= 1
    
            # Apply the Edge Weighting.
            if len(layer_data.edge_weights) > 0:
                for edge in me.edges:
    
                    edge_sa= "{0} {1}".format(edge.vertices[0], edge.vertices[1])
                    edge_sb= "{0} {1}".format(edge.vertices[1], edge.vertices[0])
    
                    if edge_sa in layer_data.edge_weights:
                        edge.crease= layer_data.edge_weights[edge_sa]
                    elif edge_sb in layer_data.edge_weights:
                        edge.crease= layer_data.edge_weights[edge_sb]
    
    
    Ken Nign's avatar
    Ken Nign committed
            # Unfortunately we can't exlude certain faces from the subdivision.
            if layer_data.has_subds and add_subd_mod:
                ob.modifiers.new(name="Subsurf", type='SUBSURF')
    
    Ken Nign's avatar
    Ken Nign committed
            # Should we build an armature from the embedded rig?
            if len(layer_data.bones) > 0 and skel_to_arm:
                bpy.ops.object.armature_add()
                arm_object= bpy.context.active_object
                arm_object.name= "ARM_" + layer_data.name
                arm_object.data.name= arm_object.name
                arm_object.location= layer_data.pivot
                bpy.ops.object.mode_set(mode='EDIT')
                build_armature(layer_data, arm_object.data.edit_bones)
                bpy.ops.object.mode_set(mode='OBJECT')
    
    Ken Nign's avatar
    Ken Nign committed
            # Clear out the dictionaries for this layer.
            layer_data.bone_names.clear()
            layer_data.bone_rolls.clear()
            layer_data.wmaps.clear()
            layer_data.colmaps.clear()
            layer_data.uvmaps.clear()
            layer_data.morphs.clear()
            layer_data.surf_tags.clear()
    
    Ken Nign's avatar
    Ken Nign committed
        # With the objects made, setup the parents and re-adjust the locations.
        for ob_key in ob_dict:
            if ob_dict[ob_key][1] != -1 and ob_dict[ob_key][1] in ob_dict:
                parent_ob = ob_dict[ob_dict[ob_key][1]]
                ob_dict[ob_key][0].parent= parent_ob[0]
                ob_dict[ob_key][0].location-= parent_ob[0].location
    
    Ken Nign's avatar
    Ken Nign committed
        bpy.context.scene.update()
    
    Ken Nign's avatar
    Ken Nign committed
        print("Done Importing LWO File")
    
    Ken Nign's avatar
    Ken Nign committed
    from bpy.props import *
    
    
    Ken Nign's avatar
    Ken Nign committed
    class IMPORT_OT_lwo(bpy.types.Operator):
        '''Import LWO Operator.'''
        bl_idname= "import_scene.lwo"
        bl_label= "Import LWO"
        bl_description= "Import a LightWave Object file."
        bl_options= {'REGISTER', 'UNDO'}
    
    Ken Nign's avatar
    Ken Nign committed
        filepath= StringProperty(name="File Path", description="Filepath used for importing the LWO file", maxlen=1024, default="")
    
    
        ADD_SUBD_MOD= BoolProperty(name="Apply SubD Modifier", description="Apply the Subdivision Surface modifier to layers with Subpatches", default=True)
        LOAD_HIDDEN= BoolProperty(name="Load Hidden Layers", description="Load object layers that have been marked as hidden", default=False)
        SKEL_TO_ARM= BoolProperty(name="Create Armature", description="Create an armature from an embedded Skelegon rig", default=True)
    
    
    Ken Nign's avatar
    Ken Nign committed
        def execute(self, context):
    
    Ken Nign's avatar
    Ken Nign committed
                     context,
    
    Ken Nign's avatar
    Ken Nign committed
            return {'FINISHED'}
    
    Ken Nign's avatar
    Ken Nign committed
        def invoke(self, context, event):
            wm= context.window_manager
    
            wm.fileselect_add(self)
    
    Ken Nign's avatar
    Ken Nign committed
            return {'RUNNING_MODAL'}
    
    
    def menu_func(self, context):
        self.layout.operator(IMPORT_OT_lwo.bl_idname, text="LightWave Object (.lwo)")
    
    
    Ken Nign's avatar
    Ken Nign committed
    def register():
    
    Ken Nign's avatar
    Ken Nign committed
        bpy.types.INFO_MT_file_import.append(menu_func)
    
    Ken Nign's avatar
    Ken Nign committed
    def unregister():
    
    Ken Nign's avatar
    Ken Nign committed
        bpy.types.INFO_MT_file_import.remove(menu_func)
    
    if __name__ == "__main__":
    
    Guillermo S. Romero's avatar
    Guillermo S. Romero committed
        register()