def import_bounding_box(self, bbox):
        """Import a bounding box (BSBound, or NiNode with bounding box)."""
        # calculate bounds
        if isinstance(bbox, NifFormat.BSBound):
            b_mesh = bpy.data.meshes.new('BSBound')
            minx = bbox.center.x - bbox.dimensions.x
            miny = bbox.center.y - bbox.dimensions.y
            minz = bbox.center.z - bbox.dimensions.z
            maxx = bbox.center.x + bbox.dimensions.x
            maxy = bbox.center.y + bbox.dimensions.y
            maxz = bbox.center.z + bbox.dimensions.z
        
        elif isinstance(bbox, NifFormat.NiNode):
            if not bbox.has_bounding_box:
                raise ValueError("Expected NiNode with bounding box.")
            b_mesh = bpy.data.meshes.new('Bounding Box')
            
            #Ninode's(bbox) internal bounding_box behaves like a seperate mesh.
            #bounding_box center(bbox.bounding_box.translation) is relative to the bound_box
            minx = bbox.bounding_box.translation.x - bbox.translation.x - bbox.bounding_box.radius.x
            miny = bbox.bounding_box.translation.y - bbox.translation.y - bbox.bounding_box.radius.y
            minz = bbox.bounding_box.translation.z - bbox.translation.z - bbox.bounding_box.radius.z
            maxx = bbox.bounding_box.translation.x - bbox.translation.x + bbox.bounding_box.radius.x
            maxy = bbox.bounding_box.translation.y - bbox.translation.y + bbox.bounding_box.radius.y
            maxz = bbox.bounding_box.translation.z - bbox.translation.z + bbox.bounding_box.radius.z
        
        else:
            raise TypeError("Expected BSBound or NiNode but got %s."
                            % bbox.__class__.__name__)

        # create mesh
        for x in [minx, maxx]:
            for y in [miny, maxy]:
                for z in [minz, maxz]:
                    b_mesh.vertices.add(1)
                    b_mesh.vertices[-1].co = (x,y,z)

        faces = [[0,1,3,2],[6,7,5,4],[0,2,6,4],[3,1,5,7],[4,5,1,0],[7,6,2,3]]
        b_mesh.faces.add(len(faces))
        b_mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))

        # link box to scene and set transform
        if isinstance(bbox, NifFormat.BSBound):
            b_obj = bpy.data.objects.new('BSBound', b_mesh)
        else:
            b_obj = bpy.data.objects.new('Bounding Box', b_mesh)
            # XXX this is set in the import_branch() method
            #ob.matrix_local = mathutils.Matrix(
            #    *bbox.bounding_box.rotation.as_list())
            #ob.setLocation(
            #    *bbox.bounding_box.translation.as_list())

        # set bounds type
        b_obj.show_bounds = True
        b_obj.draw_type = 'BOUNDS'
        b_obj.draw_bounds_type = 'BOX'
        #quick radius estimate
        b_obj.game.radius = max(maxx, maxy, maxz)
        bpy.context.scene.objects.link(b_obj)
        return b_obj
Beispiel #2
0
 def addGeometry(cls, mesh, vertices, faces):
     from bpy_extras.io_utils import unpack_list, unpack_face_list
     mesh.vertices.add(len(vertices))
     mesh.vertices.foreach_set("co", unpack_list(vertices))
     mesh.tessfaces.add(len(faces))
     mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
     #mesh.from_pydata(vertices, [], faces)
     """
     mesh.add_geometry(len(vertices), 0, len(faces))
     # add vertex
     unpackedVertices=[]
     for v in vertices:
         unpackedVertices.extend(v)
     mesh.vertices.foreach_set("co", unpackedVertices)
     # add face
     unpackedFaces = []
     for face in faces:
         if len(face) == 4:
             if face[3] == 0:
                 # rotate indices if the 4th is 0
                 face = [face[3], face[0], face[1], face[2]]
         elif len(face) == 3:
             if face[2] == 0:
                 # rotate indices if the 3rd is 0
                 face = [face[2], face[0], face[1], 0]
             else:
                 face.append(0)
         unpackedFaces.extend(face)
     mesh.faces.foreach_set("verts_raw", unpackedFaces)
     """
     assert(len(vertices)==len(mesh.vertices))
Beispiel #3
0
 def addGeometry(cls, mesh, vertices, faces):
     from bpy_extras.io_utils import unpack_list, unpack_face_list
     mesh.vertices.add(len(vertices))
     mesh.vertices.foreach_set("co", unpack_list(vertices))
     mesh.tessfaces.add(len(faces))
     mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
     #mesh.from_pydata(vertices, [], faces)
     """
     mesh.add_geometry(len(vertices), 0, len(faces))
     # add vertex
     unpackedVertices=[]
     for v in vertices:
         unpackedVertices.extend(v)
     mesh.vertices.foreach_set("co", unpackedVertices)
     # add face
     unpackedFaces = []
     for face in faces:
         if len(face) == 4:
             if face[3] == 0:
                 # rotate indices if the 4th is 0
                 face = [face[3], face[0], face[1], face[2]]
         elif len(face) == 3:
             if face[2] == 0:
                 # rotate indices if the 3rd is 0
                 face = [face[2], face[0], face[1], 0]
             else:
                 face.append(0)
         unpackedFaces.extend(face)
     mesh.faces.foreach_set("verts_raw", unpackedFaces)
     """
     assert (len(vertices) == len(mesh.vertices))
def make_mesh(verteces, faces, normals, uvs, global_matrix):
    mesh = bpy.data.meshes.new('name')
    mesh.vertices.add(len(verteces))
    mesh.vertices.foreach_set("co", unpack_list(verteces))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

    index = 0
    for vertex in mesh.vertices:
        vertex.normal = normals[index]
        index += 1

    uvtex = mesh.tessface_uv_textures.new()
    uvtex.name = "UV"

    for face, uv in enumerate(uvs):
        data = uvtex.data[face]
        data.uv1 = uv[0]
        data.uv2 = uv[1]
        data.uv3 = uv[2]
    mesh.update(calc_tessface=False, calc_edges=False)

    obj = bpy.data.objects.new('name', mesh)
    # apply transformation matrix
    obj.matrix_world = global_matrix
    bpy.context.scene.objects.link(obj)  # link object to scene
Beispiel #5
0
def make_mesh(verteces, faces, normals, uvs, global_matrix):
    mesh = bpy.data.meshes.new('name')
    mesh.vertices.add(len(verteces))
    mesh.vertices.foreach_set("co", unpack_list(verteces))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

    index = 0
    for vertex in mesh.vertices:
        vertex.normal = normals[index]
        index += 1

    uvtex = mesh.tessface_uv_textures.new()
    uvtex.name = "UV"

    for face, uv in enumerate(uvs):
        data = uvtex.data[face]
        data.uv1 = uv[0]
        data.uv2 = uv[1]
        data.uv3 = uv[2]
    mesh.update(calc_tessface=False, calc_edges=False)

    obj = bpy.data.objects.new('name', mesh)
    # apply transformation matrix
    obj.matrix_world = global_matrix
    bpy.context.scene.objects.link(obj)  # link object to scene
    def instance_group_dupli_face(self, name, default_material,
                                  component_stats):
        def get_orientations(v):
            orientations = defaultdict(list)
            for transform in v:
                loc, rot, scale = Matrix(transform).decompose()
                scale = (scale[0], scale[1], scale[2])
                orientations[scale].append(transform)
            for scale, transforms in orientations.items():
                yield scale, transforms

        for scale, transforms in get_orientations(
                component_stats[(name, default_material)]):
            main_loc, _, real_scale = Matrix(transforms[0]).decompose()
            verts = []
            faces = []
            f_count = 0
            for c in transforms:
                l_loc, l_rot, l_scale = Matrix(c).decompose()
                mat = Matrix.Translation(l_loc) * l_rot.to_matrix().to_4x4()
                verts.append(
                    Vector((mat * Vector((-0.05, -0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                verts.append(
                    Vector((mat * Vector((0.05, -0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                verts.append(
                    Vector((mat * Vector((0.05, 0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                verts.append(
                    Vector((mat * Vector((-0.05, 0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                faces.append(
                    (f_count + 0, f_count + 1, f_count + 2, f_count + 3))
                f_count += 4
            dme = bpy.data.meshes.new('DUPLI_' + name)
            dme.vertices.add(len(verts))
            dme.vertices.foreach_set("co", unpack_list(verts))

            dme.tessfaces.add(f_count / 4)
            dme.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
            dme.update(calc_edges=True)  # Update mesh with new data
            dme.validate()
            dob = bpy.data.objects.new("DUPLI_" + name, dme)
            dob.dupli_type = 'FACES'
            dob.location = main_loc
            #dob.use_dupli_faces_scale = True
            #dob.dupli_faces_scale = 10

            ob = self.instance_object_or_group(name, default_material)
            ob.scale = real_scale
            ob.parent = dob
            self.context.scene.objects.link(ob)
            self.context.scene.objects.link(dob)
            sketchupLog("Complex group {} {} instanced {} times".format(
                name, default_material, f_count / 4))
        return
Beispiel #7
0
def create_mesh(nvx2_vertices, nvx2_faces, nvx2_uvlayers):
    """TODO:Doc."""
    me = bpy.data.meshes.new('nvx2_mesh')
    # Add vertices
    me.vertices.add(len(nvx2_vertices))
    me.vertices.foreach_set('co', unpack_list(nvx2_vertices))
    # Add faces
    me.tessfaces.add(len(nvx2_faces))
    # TODO: eekadoodle fix
    me.tessfaces.foreach_set('vertices_raw', unpack_face_list(nvx2_faces))
    # Add texture coordinates
    material = create_material('nvx2_material')
    me.materials.append(material)
    uv_data = nvx2_uvlayers[0]
    if (len(uv_data) > 0):
        uv = me.tessface_uv_textures.new('nvx2_uv')
        me.tessface_uv_textures.active = uv
        for i in range(len(nvx2_faces)):
            tessface = me.tessfaces[i]
            tessface.material_index = 0
            tessfaceUV = me.tessface_uv_textures[0].data[i]
            face = nvx2_faces[i]
            # BEGIN EEEKADOODLE FIX
            # BUG: Evil eekadoodle problem where faces that have
            # vert index 0 at location 3 are shuffled.
            if face[2] == 0:
                face = [face[1], face[2], face[0]]
            # END EEEKADOODLE FIX
            tessfaceUV.uv1 = uv_data[face[0]]
            tessfaceUV.uv2 = uv_data[face[1]]
            tessfaceUV.uv3 = uv_data[face[2]]
            # Apply texture to uv face
            tessfaceUV.image = material.texture_slots[0].texture.image
        """
        me.uv_textures.new('nvx2_uv')
        uv_layer = me.uv_layers[-1].data
        vert_loops = {}
        for l in me.loops:
            vert_loops.setdefault(l.vertex_index, []).append(l.index)
        for i, coord in enumerate(uv_data):
            # For every loop of a vertex
            for li in vert_loops[i]:
                uv_layer[li].uv = coord
        """
        """
        vi_uv = {i: uv for i, uv in enumerate(uv_coords)}
        per_loop_list = [0.0] * len(me.loops)
        for loop in me.loops:
            per_loop_list[loop.index] = vi_uv.get(loop.vertex_index)
        per_loop_list = [uv for pair in per_loop_list for uv in pair]
        me.uv_textures.new('nvx2_uv')
        me.uv_layers[-1].data.foreach_set("uv", per_loop_list)
        """
    me.update()
    return me
Beispiel #8
0
def make_mesh(verteces, faces, normals, uvs, global_matrix):

    # Create a new mesh from the vertices and faces
    mesh = bpy.data.meshes.new("Imported Mesh")
    mesh.vertices.add(len(verteces))
    mesh.vertices.foreach_set("co", unpack_list(verteces))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

    # Generate normals
    index = 0
    for vertex in mesh.vertices:
        vertex.normal = normals[index]
        index += 1

    # Generate UV data
    uvtex = mesh.tessface_uv_textures.new(name="UVMap")

    for face, uv in enumerate(uvs):
        data = uvtex.data[face]
        data.uv1 = uv[0]
        data.uv2 = uv[1]
        data.uv3 = uv[2]

    # Update the mesh and link it to the scene
    mesh.update(calc_tessface=False, calc_edges=False)
    obj = bpy.data.objects.new(
        "Imported Mesh", mesh)  # Create the mesh object for the imported mesh
    obj.matrix_world = global_matrix  # Apply transformation matrix
    bpy.context.scene.objects.link(obj)  # Link object to scene

    # Prep for mesh cleaning --> https://blender.stackexchange.com/questions/174525/how-to-merge-all-vertices-by-distance-and-remove-all-inner-faces
    merge_threshold = 0.0001
    bpy.ops.object.select_all(action='DESELECT')
    obj.select = True  # Select the object we just made
    bpy.context.scene.objects.active = obj
    bpy.ops.object.mode_set(mode="EDIT")

    # Combine tri's to make a solid mesh and to remove unnecessary vertices
    bpy.ops.mesh.select_all(action="SELECT")
    bpy.ops.mesh.remove_doubles(threshold=merge_threshold)
    bpy.ops.mesh.select_all(action="DESELECT")

    # Remove interior faces that won't be seen
    bpy.ops.mesh.select_mode(type="FACE")
    bpy.ops.mesh.select_interior_faces()
    bpy.ops.mesh.delete(type="FACE")

    # Restore the scene to object mode
    if bpy.context.mode != "OBJECT":
        bpy.ops.object.mode_set(mode="OBJECT")
Beispiel #9
0
def mesh_from_data(name, coords, uvs, faces, face_mats, mats):
    mesh = bpy.data.meshes.new(name)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(coords))
    mesh.vertices.foreach_set('co', unpack_list(coords))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw', unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index', face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = uvs[fa[0]].to_tuple()
        mesh.tessface_uv_textures[0].data[fdx].uv2 = uvs[fa[1]].to_tuple()
        mesh.tessface_uv_textures[0].data[fdx].uv3 = uvs[fa[2]].to_tuple()
    mesh.update()
    return mesh
Beispiel #10
0
    def instance_group_dupli_face(self, name, default_material, component_stats):
        def get_orientations( v):
            orientations = defaultdict(list)
            for transform in v:
                loc, rot, scale = Matrix(transform).decompose()
                scale = (scale[0], scale[1], scale[2])
                orientations[scale].append(transform)
            for scale, transforms in orientations.items():
                yield scale, transforms


        for scale, transforms in get_orientations(component_stats[(name, default_material)]):
            main_loc, _, real_scale  = Matrix(transforms[0]).decompose()
            verts = []
            faces = []
            f_count = 0
            for c in transforms:
                l_loc, l_rot, l_scale = Matrix(c).decompose()
                mat = Matrix.Translation(l_loc) * l_rot.to_matrix().to_4x4()
                verts.append(Vector((mat * Vector((-0.05, -0.05, 0, 1.0)))[0:3]) - main_loc)
                verts.append(Vector((mat * Vector(( 0.05, -0.05, 0, 1.0)))[0:3]) - main_loc)
                verts.append(Vector((mat * Vector(( 0.05,  0.05, 0, 1.0)))[0:3]) - main_loc)
                verts.append(Vector((mat * Vector((-0.05,  0.05, 0, 1.0)))[0:3]) - main_loc)
                faces.append( (f_count + 0,  f_count + 1, f_count + 2, f_count + 3) )
                f_count += 4
            dme = bpy.data.meshes.new('DUPLI_' + name)
            dme.vertices.add(len(verts))
            dme.vertices.foreach_set("co", unpack_list(verts))

            dme.tessfaces.add(f_count /4 )
            dme.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
            dme.update(calc_edges=True) # Update mesh with new data
            dme.validate()
            dob = bpy.data.objects.new("DUPLI_" + name, dme)
            dob.dupli_type = 'FACES'
            dob.location = main_loc
            #dob.use_dupli_faces_scale = True
            #dob.dupli_faces_scale = 10

            ob = self.instance_object_or_group(name,default_material)
            ob.scale = real_scale
            ob.parent = dob
            self.context.scene.objects.link(ob)
            self.context.scene.objects.link(dob)
            sketchupLog("Complex group {} {} instanced {} times".format(name, default_material, f_count / 4))
        return
Beispiel #11
0
def createHiddenMeshObject(name, untransformedPositions, faces, matrix):
    mesh = bpy.data.meshes.new(name)
    meshObject = bpy.data.objects.new(name, mesh)
    meshObject.location = (0,0,0) 

    transformedPositions = []
    for v in untransformedPositions:
        transformedPositions.append(matrix * mathutils.Vector(v))

    mesh.vertices.add(len(transformedPositions))
    mesh.vertices.foreach_set("co", io_utils.unpack_list(transformedPositions))

    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", io_utils.unpack_face_list(faces))
    
    mesh.update(calc_edges=True)
    return meshObject
Beispiel #12
0
def mesh_from_data(name,coords,uvs,faces,face_mats,mats):
    mesh = bpy.data.meshes.new(name)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(coords))
    mesh.vertices.foreach_set('co',unpack_list(coords))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index',face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = uvs[fa[0]].to_tuple()
        mesh.tessface_uv_textures[0].data[fdx].uv2 = uvs[fa[1]].to_tuple() 
        mesh.tessface_uv_textures[0].data[fdx].uv3 = uvs[fa[2]].to_tuple() 
    mesh.update()
    return mesh
Beispiel #13
0
    def _createMesh(scene, name, vertices, faces):
        from bpy_extras.io_utils import unpack_list, unpack_face_list

        mesh = bpy.data.meshes.new(name=name)

        mesh.vertices.add(len(vertices))
        mesh.vertices.foreach_set("co", unpack_list(vertices))

        mesh.faces.add(len(faces))
        mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))

        mesh.update(calc_edges=True)

        ob = bpy.data.objects.new(name=name, object_data=mesh)

        scene.objects.link(ob)

        return ob
Beispiel #14
0
    def _createMesh(scene, name, vertices, faces):
        from bpy_extras.io_utils import unpack_list, unpack_face_list

        mesh = bpy.data.meshes.new(name=name)

        mesh.vertices.add(len(vertices))
        mesh.vertices.foreach_set("co", unpack_list(vertices))

        mesh.faces.add(len(faces))
        mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))

        mesh.update(calc_edges=True)

        ob = bpy.data.objects.new(name=name, object_data=mesh)

        scene.objects.link(ob)

        return ob
def importGMDL(file):
    result = {'FINISHED'}

    header = Header()
    header.read(file)

    triForm = TriangleFormat()
    triForm.read(file)

    vertexForm = VertexFormat()
    vertexForm.read(file)

    # Let's create the mesh
    mesh = bpy.data.meshes.new(ntpath.basename(file.name))
    obj = bpy.data.objects.new(ntpath.basename(file.name), mesh)
    bpy.context.scene.objects.link(obj)
    bpy.context.scene.objects.active = obj

    mesh.vertices.add(vertexForm.vertexCount)
    for v in range(len(vertexForm.vertices)):
        mesh.vertices[v].co = vertexForm.vertices[v].positions

    print("Num triangles %i" % len(triForm.triangles))
    mesh.tessfaces.add(len(triForm.triangles))
    mesh.tessfaces.foreach_set("vertices_raw",
                               unpack_face_list(triForm.triangles))

    if len(vertexForm.vertices[0].uvs) > 0:
        uvtex = mesh.tessface_uv_textures.new()
        uvtex.name = 'DefaultUV'
        for i, face in enumerate(mesh.tessfaces):
            uvtex.data[i].uv1 = vertexForm.vertices[face.vertices_raw[0]].uvs
            uvtex.data[i].uv2 = vertexForm.vertices[face.vertices_raw[1]].uvs
            uvtex.data[i].uv3 = vertexForm.vertices[face.vertices_raw[2]].uvs
            uvtex.data[i].uv4 = [0, 0]

    mesh.update()

    if len(vertexForm.vertices[0].normals) > 0:
        for v, vertex in enumerate(vertexForm.vertices):
            mesh.vertices[v].normal = vertex.normals

    file.close()
    return result
Beispiel #16
0
def load(operator, context, filepath):
    # Parse mesh from OFF file
    # TODO: Add support for NOFF and COFF
    filepath = os.fsencode(filepath)
    file = open(filepath, 'r')
    file.readline()
    vcount, fcount, ecount = [int(x) for x in file.readline().split()]
    verts = []
    facets = []
    i=0;
    while i<vcount:
        line = file.readline()
        try:
            px, py, pz = [float(x) for x in line.split()]
        except ValueError:
            continue
        verts.append((px, py, pz))
        i=i+1

    i=0;
    while i<fcount:
        line = file.readline()
        try:
            unused, vid1, vid2, vid3 = [int(x) for x in line.split()]
        except ValueError:
            continue
        facets.append((vid1, vid2, vid3))
        i=i+1

    # Assemble mesh
    off_name = bpy.path.display_name_from_filepath(filepath)
    mesh = bpy.data.meshes.new(name=off_name)
    mesh.vertices.add(len(verts))
    mesh.vertices.foreach_set("co", unpack_list(verts))

    mesh.tessfaces.add(len(facets))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(facets))

    mesh.validate()
    mesh.update()

    return mesh
Beispiel #17
0
def importGMSH(file):
    result = {'FINISHED'}

    model = Header()
    model.read(file)

    for me in model.meshes:
        mesh = bpy.data.meshes.new(ntpath.basename(file.name))
        obj = bpy.data.objects.new(ntpath.basename(file.name), mesh)
        bpy.context.scene.objects.link(obj)
        bpy.context.scene.objects.active = obj

        mesh.vertices.add(me.numVertices)
        mesh.vertices.foreach_set("co", unpack_list(me.positions))

        mesh.tessfaces.add(me.numTriangles)
        mesh.tessfaces.foreach_set("vertices_raw",
                                   unpack_face_list(me.triangles))

        uvtex = mesh.tessface_uv_textures.new()
        uvtex.name = 'DefaultUV'
        if len(me.UVs) > 0:
            for v, face in enumerate(mesh.tessfaces):
                uvtex.data[v].uv1 = me.UVs[face.vertices_raw[0]]
                uvtex.data[v].uv2 = me.UVs[face.vertices_raw[1]]
                uvtex.data[v].uv3 = me.UVs[face.vertices_raw[2]]
                uvtex.data[v].uv4 = [0, 0]

        mesh.update()

        if len(me.normals) > 0:
            mesh.vertices.foreach_set("normal", unpack_list(me.normals))

    file.close()

    return result
Beispiel #18
0
def build_model2(mod,**kwargs):

    default_materials()

    oname = mod.filename.replace('.mesh','.000')
    mname = oname+'.'+'mesh'

    ps = mod.pset.ps
    us = mod.uset.ps

    mats = ['generic','concrete1','grass2']
    fs_lookup = {}
    for fmx in range(len(mats)):
        fs_lookup[mats[fmx]] = fmx

    for gfx in mod.gfxmeshes:
        faces = [f for f in gfx.faces if not f is None]
        face_mats = [fs_lookup[gfx.fs_mats[f][1]] for f in faces]
        oloc = (0,0,0)

        #mesh = mesh_from_data(mname,ps,us,faces,face_mats,mats)
        #def mesh_from_data(name,ps,us,faces,face_mats,mats):

        mesh = bpy.data.meshes.new(mname)
        if not mats is None:
            [mesh.materials.append(materials[ma]) for ma in mats]
        mesh.vertices.add(len(ps))
        mesh.vertices.foreach_set('co',unpack_list(ps))
        mesh.tessfaces.add(len(faces))
        mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
        mesh.tessfaces.foreach_set('material_index',face_mats)
        mesh.tessface_uv_textures.new()
        for fdx in range(len(faces)):
            fa = faces[fdx]
            mesh.tessface_uv_textures[0].data[fdx].uv1 = tuple(us[fa[0]])[:-1]
            mesh.tessface_uv_textures[0].data[fdx].uv2 = tuple(us[fa[1]])[:-1]
            mesh.tessface_uv_textures[0].data[fdx].uv3 = tuple(us[fa[2]])[:-1]
        mesh.update()




    '''#
    faces = mod.gfxmeshes[0].faces
    face_mats = [fs_lookup[mod.gfxmeshes[0].fs_mats[f]] for f in faces]
    #face_mats = [0]*len(faces)
    #mats = ['generic']
    oloc = (0,0,0)

    #mesh = mesh_from_data(mname,ps,us,faces,face_mats,mats)
    #def mesh_from_data(name,ps,us,faces,face_mats,mats):

    mesh = bpy.data.meshes.new(mname)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(ps))
    mesh.vertices.foreach_set('co',unpack_list(ps))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index',face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = tuple(us[fa[0]])[:-1]
        mesh.tessface_uv_textures[0].data[fdx].uv2 = tuple(us[fa[1]])[:-1]
        mesh.tessface_uv_textures[0].data[fdx].uv3 = tuple(us[fa[2]])[:-1]
    mesh.update()
    '''#



    obj = object_from_mesh(oname,mesh,oloc,mats)
    object_to_scene(obj)
    return obj
Beispiel #19
0
def make_mesh_data(iqmodel, name, meshes, amtobj, dir):
	print("importing mesh", name, "with", len(meshes), "parts")

	mesh = bpy.data.meshes.new(name)
	obj = bpy.data.objects.new(name, mesh)
	bpy.context.scene.objects.link(obj)
	bpy.context.scene.objects.active = obj

	# Set the mesh to single-sided to spot normal errors
	mesh.show_double_sided = False

	has_vn = len(iqmodel.meshes[0].vn) > 0
	has_vt = len(iqmodel.meshes[0].vt) > 0
	has_vc = len(iqmodel.meshes[0].vc) > 0
	has_vb = len(iqmodel.meshes[0].vbi) > 0 and len(iqmodel.meshes[0].vbw) == len(iqmodel.meshes[0].vbi)
	has_v0 = len(iqmodel.meshes[0].v0) > 0
	has_v1 = len(iqmodel.meshes[0].v1) > 0
	has_v2 = len(iqmodel.meshes[0].v2) > 0
	has_v3 = len(iqmodel.meshes[0].v3) > 0
	has_v4 = len(iqmodel.meshes[0].v4) > 0
	has_v5 = len(iqmodel.meshes[0].v5) > 0
	has_v6 = len(iqmodel.meshes[0].v6) > 0
	has_v7 = len(iqmodel.meshes[0].v7) > 0
	has_v8 = len(iqmodel.meshes[0].v8) > 0
	has_v9 = len(iqmodel.meshes[0].v9) > 0

	# Flip winding and UV coords.

	for iqmesh in meshes:
		iqmesh.faces = [x[::-1] for x in iqmesh.faces]
		iqmesh.vt = [(u,1-v) for (u,v) in iqmesh.vt]

	# Blender has texcoords and colors on faces rather than vertices.
	# Create material slots for all materials used.
	# Create new vertices from unique vp/vn/vb sets (vertex data).
	# Create new faces which index these new vertices, and has associated face data.

	vertex_map = {}

	new_f = []
	new_ft = []
	new_fc = []
	new_fm_m = []
	new_fm_i = []

	new_vp = []
	new_vn = []
	new_vbi = []
	new_vbw = []
	new_v0 = []
	new_v1 = []
	new_v2 = []
	new_v3 = []
	new_v4 = []
	new_v5 = []
	new_v6 = []
	new_v7 = []
	new_v8 = []
	new_v9 = []

	for iqmesh in meshes:
		material, image = make_material(iqmesh.material, dir)
		if material.name not in mesh.materials:
			mesh.materials.append(material)
		material_index = mesh.materials.find(material.name)

		for iqface in iqmesh.faces:
			f = []
			ft = []
			fc = []
			for iqvert in iqface:
				vp = iqmesh.vp[iqvert]
				vn = iqmesh.vn[iqvert] if has_vn else None
				vbi = iqmesh.vbi[iqvert] if has_vb else None
				vbw = iqmesh.vbw[iqvert] if has_vb else None
				v0 = iqmesh.v0[iqvert] if has_v0 else None
				v1 = iqmesh.v1[iqvert] if has_v1 else None
				v2 = iqmesh.v2[iqvert] if has_v2 else None
				v3 = iqmesh.v3[iqvert] if has_v3 else None
				v4 = iqmesh.v4[iqvert] if has_v4 else None
				v5 = iqmesh.v5[iqvert] if has_v5 else None
				v6 = iqmesh.v6[iqvert] if has_v6 else None
				v7 = iqmesh.v7[iqvert] if has_v7 else None
				v8 = iqmesh.v8[iqvert] if has_v8 else None
				v9 = iqmesh.v9[iqvert] if has_v9 else None
				vertex = (vp, vn, vbi, vbw, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
				if not vertex in vertex_map:
					vertex_map[vertex] = len(new_vp)
					new_vp.append(vp)
					new_vn.append(vn)
					new_vbi.append(vbi)
					new_vbw.append(vbw)
					new_v0.append(v0)
					new_v1.append(v1)
					new_v2.append(v2)
					new_v3.append(v3)
					new_v4.append(v4)
					new_v5.append(v5)
					new_v6.append(v6)
					new_v7.append(v7)
					new_v8.append(v8)
					new_v9.append(v9)
				f.append(vertex_map[vertex])
				ft.append(iqmesh.vt[iqvert] if has_vt else None)
				fc.append(iqmesh.vc[iqvert] if has_vc else None)
			f, ft, fc = reorder(f, ft, fc)
			if isdegenerate(f):
				print("degenerate face", iqface, f)
				continue
			new_f.append(f)
			new_ft.append(ft)
			new_fc.append(fc)
			new_fm_m.append(material_index)
			new_fm_i.append(image)

	print("\tcollected %d vertices and %d faces" % (len(new_vp), len(new_f)))

	# Create mesh vertex and face data

	mesh.vertices.add(len(new_vp))
	mesh.vertices.foreach_set("co", unpack_list(new_vp))

	mesh.tessfaces.add(len(new_f))
	mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(new_f))

	# Set up UV and Color layers

	uvlayer = mesh.tessface_uv_textures.new() if has_vt else None
	clayer = mesh.tessface_vertex_colors.new() if has_vc else None

	for i, face in enumerate(mesh.tessfaces):
		face.use_smooth = True
		face.material_index = new_fm_m[i]
		if uvlayer:
			uvlayer.data[i].uv1 = new_ft[i][0]
			uvlayer.data[i].uv2 = new_ft[i][1]
			uvlayer.data[i].uv3 = new_ft[i][2]
			uvlayer.data[i].uv4 = new_ft[i][3] if len(new_ft[i]) == 4 else (0,0)
			uvlayer.data[i].image = new_fm_i[i]
		if clayer:
			clayer.data[i].color1 = new_fc[0]
			clayer.data[i].color2 = new_fc[1]
			clayer.data[i].color3 = new_fc[2]
			clayer.data[i].color4 = new_fc[3] if len(new_fc[i]) == 4 else (1,1,1)

	# Vertex groups and armature modifier for skinning

	if has_vb and amtobj:
		for iqbone in iqmodel.bones:
			obj.vertex_groups.new(iqbone.name)

		for vgroup in obj.vertex_groups:
			for v, vbi in enumerate(new_vbi):
				for i, bi in enumerate(vbi):
					bw = new_vbw[v][i]
					if bi == vgroup.index:
						vgroup.add([v], bw, 'REPLACE')

		mod = obj.modifiers.new("Armature", 'ARMATURE')
		mod.object = amtobj
		mod.use_vertex_groups = True

	# Vertex groups for custom attributes

	def make_custom_vgroup(obj, name, size, vdata):
		print("importing custom attribute as vertex group", name)
		if size == 1:
			xg = obj.vertex_groups.new(name)
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
		if size == 2:
			xg = obj.vertex_groups.new(name + ".x")
			yg = obj.vertex_groups.new(name + ".y")
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
				yg.add([i], v[1], 'REPLACE')
		if size == 3:
			xg = obj.vertex_groups.new(name + ".x")
			yg = obj.vertex_groups.new(name + ".y")
			zg = obj.vertex_groups.new(name + ".z")
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
				yg.add([i], v[1], 'REPLACE')
				zg.add([i], v[2], 'REPLACE')
		if size == 4:
			xg = obj.vertex_groups.new(name + ".x")
			yg = obj.vertex_groups.new(name + ".y")
			zg = obj.vertex_groups.new(name + ".z")
			wg = obj.vertex_groups.new(name + ".z")
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
				yg.add([i], v[1], 'REPLACE')
				zg.add([i], v[2], 'REPLACE')
				wg.add([i], v[3], 'REPLACE')

	if has_v0: make_custom_vgroup(obj, iqmodel.custom_name[0], iqmodel.custom_size[0], new_v0)
	if has_v1: make_custom_vgroup(obj, iqmodel.custom_name[1], iqmodel.custom_size[1], new_v1)
	if has_v2: make_custom_vgroup(obj, iqmodel.custom_name[2], iqmodel.custom_size[2], new_v2)
	if has_v3: make_custom_vgroup(obj, iqmodel.custom_name[3], iqmodel.custom_size[3], new_v3)
	if has_v4: make_custom_vgroup(obj, iqmodel.custom_name[4], iqmodel.custom_size[4], new_v4)
	if has_v5: make_custom_vgroup(obj, iqmodel.custom_name[5], iqmodel.custom_size[5], new_v5)
	if has_v6: make_custom_vgroup(obj, iqmodel.custom_name[6], iqmodel.custom_size[6], new_v6)
	if has_v7: make_custom_vgroup(obj, iqmodel.custom_name[7], iqmodel.custom_size[7], new_v7)
	if has_v8: make_custom_vgroup(obj, iqmodel.custom_name[8], iqmodel.custom_size[8], new_v8)
	if has_v9: make_custom_vgroup(obj, iqmodel.custom_name[9], iqmodel.custom_size[9], new_v9)

	# Update mesh polygons from tessfaces

	mesh.update()

	# Must set normals after mesh.update() or they will be recalculated.
	mesh.vertices.foreach_set("normal", unpack_list(new_vn))

	return obj
Beispiel #20
0
def load(operator, context, filepath,
         global_clamp_size=0.0,
         use_verbose=False,
         dump_first_only=False,
         use_uv_map=True,
         use_diffuse_texture=True,
         use_normal_texture=True,
         use_specular_texture=True,         
         use_computed_normals=False,
         use_shadeless=True,
         viz_normals=True,
         viz_blendweights=False,
         use_specular=True,
         global_matrix=None,
         use_debug_bones=False
         ):
    '''
    Called by the user interface or another script.
    load_obj(path) - should give acceptable results.
    This function passes the file and sends the data off
        to be split into objects and then converted into mesh objects
    '''
    print('\nimporting crf %r' % filepath)

    filepath = os.fsencode(filepath)

    if global_matrix is None:
        global_matrix = mathutils.Matrix()

    new_objects = []  # put new objects here
    
    time_main = time.time()
    print("\tparsing crf file...")
    time_sub = time.time()

    file = open(filepath, "rb")
    CRF = CRF_object()    
    CRF.parse_bin(file)
    meshfile = CRF.meshfile

    bad_vertex_list = []
    
    # start importing meshes
    for i in range(0, meshfile.num_meshes):
        verts_loc = []
        verts_tex0 = []
        verts_tex1 = []
        faces = []  # tuples of the faces
        face_tex = [] # tuples of uv coordinates for faces
        vertex_normals = []
        vertex_specular = []
        vertex_blendweights1 = []        
        
        mesh = meshfile.meshes[i]
        faces = mesh.face_list
        
        #convert from DirectX to Blender face vertex ordering
        bad_mesh_vertex_list = []
        for i in range(0, len(faces)):
            v1,v2,v3 = faces[i]
            # if there are duplicated vertices in triangle, delete that face by making all vertices the same
            if v1 == v2 or v1 == v3 or v2 == v3:
                print("Found a bad face %i, eliminating %i,%i,%i" % (i,v1,v2,v3))
                faces[i] = (v3,v3,v3)
                bad_mesh_vertex_list.append(v1)
                bad_mesh_vertex_list.append(v2)
                bad_mesh_vertex_list.append(v3)
            else:
                faces[i] = (v3,v2,v1)
        bad_vertex_list.append(bad_mesh_vertex_list)
        
        for vertex in mesh.vertices0:
            verts_loc.append( (vertex.x_blend, vertex.y_blend, vertex.z_blend) )            
            verts_tex0.append( (vertex.u0_blend, vertex.v0_blend) )        

            vertex_normals.append( (vertex.normal_x_blend, vertex.normal_y_blend, vertex.normal_z_blend, vertex.normal_w_blend) )
            vertex_specular.append( (vertex.specular_red_blend, vertex.specular_green_blend, vertex.specular_blue_blend, vertex.specular_alpha_blend) )
            vertex_blendweights1.append( (vertex.blendweights1_x_blend, vertex.blendweights1_y_blend, vertex.blendweights1_z_blend, vertex.blendweights1_w_blend) )
        
        # deselect all
        if bpy.ops.object.select_all.poll():
            bpy.ops.object.select_all(action='DESELECT')

        # create blender mesh
        me = bpy.data.meshes.new("Dumped_Mesh")   # create a new mesh
        object_name = os.path.splitext(os.path.basename(filepath))[0]
        ob = bpy.data.objects.new(os.fsdecode(object_name) + "_%i" % mesh.mesh_number, me)
        # Fill the mesh with verts, edges, faces
        me.vertices.add(len(verts_loc))
        me.vertices.foreach_set("co", unpack_list(verts_loc))
        me.tessfaces.add(len(faces))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        
        
        # use computed normals
        if use_computed_normals:
            for vertex, vertex_normal in zip(me.vertices, vertex_normals):
                print("vertex index", vertex.index, vertex_normal)
                vertex.normal = vertex_normal[0:3]
                
        # fill face uv texture array
        for face in ob.data.tessfaces:
            verts_in_face = face.vertices[:]
            if use_verbose:
                print("face index", face.index)  
                print("normal", face.normal)  
                for vert in verts_in_face:  
                    print("vert", vert, " vert co", ob.data.vertices[vert].co)
                    print("Normal X:%s Y:%s Z:%s " % (vertex_normals[vert][0], vertex_normals[vert][1], vertex_normals[vert][2]))
                    print("specular R:%s G:%s B:%s " % (vertex_specular[vert][0], vertex_specular[vert][1], vertex_specular[vert][2]))
                    print("UV0: ", verts_tex0[vert])
                    print()
            i = face.index
            v1 = verts_in_face[0]
            v2 = verts_in_face[1]
            v3 = verts_in_face[2]
            face_tex.append([ verts_tex0[v1], verts_tex0[v2], verts_tex0[v3] ]) 
        
        # start all optional tasks        
        # add uv map
        if use_uv_map:
            uvMain = createTextureLayer("UV_Main", me, face_tex)

        # add texture
        if use_diffuse_texture or use_normal_texture or use_specular_texture:
            # create a material to which textures can be added
            mat = createMaterial('TexMat', use_shadeless, viz_normals)
            if use_diffuse_texture:
                diffuse_texture = mesh.materials.diffuse_texture            
                diffuse_texture_filepath = findTextureFile(os.fsdecode(filepath),  diffuse_texture.decode(sys.stdout.encoding))
                print("Adding diffuse texture ", diffuse_texture_filepath)        
                if diffuse_texture_filepath != None and diffuse_texture_filepath != "":
                    addDiffuseTexture(diffuse_texture_filepath, mat)
                    mat.use_transparency = True
                    mat.alpha = 0 #TODO check model data for this param
            if use_normal_texture:
                normal_texture = mesh.materials.normal_texture            
                normal_texture_filepath = findTextureFile(os.fsdecode(filepath),  normal_texture.decode(sys.stdout.encoding))
                print("Adding normals texture ", normal_texture_filepath)        
                if normal_texture_filepath != None and normal_texture_filepath != "":
                    addNormalTexture(normal_texture_filepath, mat)
            if use_specular_texture:
                specular_texture = mesh.materials.specular_texture            
                specular_texture_filepath = findTextureFile(os.fsdecode(filepath),  specular_texture.decode(sys.stdout.encoding))
                print("Adding normals texture ", specular_texture_filepath)        
                if specular_texture_filepath != None and specular_texture_filepath != "":
                    addSpecularTexture(specular_texture_filepath, mat)                            
            ob.data.materials.append(mat)

        # viz normals
                
        # add specular constant
        if use_specular:
            vertex_specular = []
            for vertex in mesh.vertices0:
                vertex_specular.append((vertex.specular_red_blend, vertex.specular_green_blend, vertex.specular_blue_blend, vertex.specular_alpha_blend))
                
            setVertexSpecularColors(me, ob.data.tessfaces, vertex_specular)
            # if no materials exist, create one+
            if len(ob.data.materials) == 0:
                mat = createMaterial('Specular', use_shadeless, viz_normals)
                mat.specular_color = mesh.materials.specular_constant
                ob.data.materials.append(mat)
            else:
                if mesh.materials.specular_constant != None:
                    ob.data.materials[0].specular_color = mesh.materials.specular_constant
                else:
                    ob.data.materials[0].specular_color = (1, 0, 0)
                    print("Failed to find specular constnat! FIXME")
                print(ob.data.materials[0].specular_color)
                      
        # viz blendweights
        
        # end all optional tasks
        
        me.update(calc_tessface=True, calc_edges=True)
        new_objects.append(ob)
    # end loop for importing meshes
    
    # import bones, create armature    
    if CRF.footer.get_jointmap() != None:                
        amt = bpy.data.armatures.new("Armature")
        amt_ob = bpy.data.objects.new("Armature", amt)
        scn = bpy.context.scene
        scn.objects.link(amt_ob)
        scn.objects.active = amt_ob
        amt_ob.select = True
        
        bpy.ops.object.mode_set(mode='EDIT')        
        make_skel(amt, CRF.jointmap, 0)

        if use_debug_bones:
            for key,value in CRF.jointmap.bone_dict.items():
                crf_joint = CRF.jointmap.joint_list[key]
                m = bone_transform(crf_joint.matrix)
                print("Bone %i\n" % key, m, "parent", crf_joint.parent_id)            
                bpy.ops.mesh.primitive_uv_sphere_add(size=0.1, location=(0,0,0))
                bpy.context.object.matrix_world = m
                bpy.context.object.name = "joint_%s_%s" % (key, CRF.jointmap.bone_dict[key].bone_name)
               
        bpy.ops.object.mode_set(mode='OBJECT')
        amt_ob.select = False
        
            
    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new

    print('\tloading materials and images...')


    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new
    
    # Create new obj
    scene = context.scene    
    for ob,bad_vertices in zip(new_objects,bad_vertex_list):
        base = scene.objects.link(ob)
        base.select = True

        # we could apply this anywhere before scaling.
        ob.matrix_world = global_matrix
        
        #delete bad vertices
        bpy.context.scene.objects.active = ob 
        ob.select = True
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='DESELECT')
        bpy.ops.object.mode_set(mode='OBJECT')
        for v in bad_vertices:
            print("Deleting vertex %i in %s" % (v, ob.name))
            ob.data.vertices[v].select = True        
        bpy.ops.object.mode_set(mode='EDIT')        
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.mode_set(mode='OBJECT')

    if CRF.footer.get_jointmap() != None:
        #select objects, select armature as active, parent objects to armature      
        bpy.ops.object.select_all(action='DESELECT') #deselect all object        
        for ob in new_objects:
            print("in loop ", ob)
            ob.select = True
        bpy.context.scene.objects.active = amt_ob    #the active object will be the parent of all selected object
        bpy.ops.object.parent_set(type='ARMATURE_NAME')

        # print all vertex groups for each object
        #for ob in new_objects:
        #    print(ob.vertex_groups.keys())
        #for ob in new_objects:
        #    for v in ob.data.vertices:
        #        print("number of groups", len(v.groups))

        obj_id = 0
        for ob in new_objects:
            if len(CRF.meshfile.meshes[obj_id].vertices1) != 0:
                for v in ob.data.vertices:                
                    CRF.meshfile.meshes[obj_id].vertices1[v.index].raw2blend() # convert 
                    blendindices = CRF.meshfile.meshes[obj_id].vertices1[v.index].blendindices
                    blendweights = CRF.meshfile.meshes[obj_id].vertices1[v.index].blendweights_blend
                    """
                    try:
                        pos  = blendindices.index(CRF.jointmap.bone_name_id_dict[b"Bone01_L_Forearm"])
                        blendindices = [blendindices[pos]+1]
                        blendweights = [1.0]
                    except ValueError:
                        blendindices = []
                        blendindices = []
                    """
                    
                    #print(blendindices, blendweights)
                    for bi,bw in zip(blendindices, blendweights):
                        #print("Assign vertex %s group %s with weight %s" % (v.index, bi, bw))
                        new_objects[obj_id].vertex_groups[bi].add([v.index], bw, 'ADD')
            obj_id+=1                    
 
    scene.update()

    axis_min = [1000000000] * 3
    axis_max = [-1000000000] * 3

    if global_clamp_size:
        # Get all object bounds
        for ob in new_objects:
            for v in ob.bound_box:
                for axis, value in enumerate(v):
                    if axis_min[axis] > value:
                        axis_min[axis] = value
                    if axis_max[axis] < value:
                        axis_max[axis] = value

        # Scale objects
        max_axis = max(axis_max[0] - axis_min[0], axis_max[1] - axis_min[1], axis_max[2] - axis_min[2])
        scale = 1.0

        while global_clamp_size < max_axis * scale:
            scale = scale / 10.0

        for obj in new_objects:
            obj.scale = scale, scale, scale

    time_new = time.time()    
    print("finished importing: %r in %.4f sec." % (filepath, (time_new - time_main)))
    return {'FINISHED'}
Beispiel #21
0
def processSkinnedGeneral(f, blocks):
    verts = []
    faces = []
    uvs = []
    texs = []
    
    #Get Version
    version = struct.unpack('<B', f.read(1))[0]
    
    #Get Flag
    flag = struct.unpack('<I', f.read(4))[0]
    print("Flag: %d" % flag)
    
    #skip unknown
    f.read(24)
    
    #Get Textures
    for i in range(8):
        length = struct.unpack('<I', f.read(4))[0]
        texStr = '<%ds' % length
        tex = struct.unpack(texStr, f.read(length))[0].decode()
        texs.append(tex)
        
        print("Texture: %s" % tex)
    
        
    #skip unknown data
    f.read(4)
    
    #Check Vertice Type
    if(version == 0 or flag != 0x80000):
        #Small Vertices
        print("Vertex Type: Small")
        
        #Get Vertex Count
        vertCount = struct.unpack('<I', f.read(4))[0]
        print("Vertices: %d" % vertCount)
        
        for vert in range(vertCount):
            x = struct.unpack('<f', f.read(4))[0]
            y = struct.unpack('<f', f.read(4))[0]
            z = struct.unpack('<f', f.read(4))[0]
       
            extra1 = struct.unpack('<B', f.read(1))[0]
            extra2 = struct.unpack('<B', f.read(1))[0]
            extra3 = struct.unpack('<B', f.read(1))[0]
            extra4 = struct.unpack('<B', f.read(1))[0]
            
            extra5 = struct.unpack('<B', f.read(1))[0]
            extra6 = struct.unpack('<B', f.read(1))[0]
            extra7 = struct.unpack('<B', f.read(1))[0]
            extra8 = struct.unpack('<B', f.read(1))[0]
            
            verts.append((x, z, y))
    elif(version == 3 or flag == 0x80000):
        #Small Vertices
        print("Vertex Type: Big")
        
        #Get Vertex Count
        vertCount = struct.unpack('<I', f.read(4))[0]
        print("Vertices: %d" % vertCount)
        
        for vert in range(vertCount):
            x = struct.unpack('<f', f.read(4))[0]
            y = struct.unpack('<f', f.read(4))[0]
            z = struct.unpack('<f', f.read(4))[0]
       
            extra1 = struct.unpack('<I', f.read(4))[0]
            extra2 = struct.unpack('<I', f.read(4))[0]
            extra3 = struct.unpack('<i', f.read(4))[0]
            extra4 = struct.unpack('<I', f.read(4))[0]
            
            verts.append((x, z, y))
            
    #Process Extra Data
    uvCount = struct.unpack('<I', f.read(4))[0]
    print("UVs: %d" % uvCount)
    
    for uv in range(uvCount):
        r = struct.unpack('<I', f.read(4))[0]
        g = struct.unpack('<I', f.read(4))[0]
        b = struct.unpack('<I', f.read(4))[0]
        
        u = struct.unpack('<f', f.read(4))[0]
        v = struct.unpack('<f', f.read(4))[0]
        
        uvs.append((u, 1-v))
        
    #Process SkinBatch/Weights
    skinCount = struct.unpack('<I', f.read(4))[0]
    print("Skin: %d" % skinCount)
    
    for skin in range(skinCount):
        
        #skip unknown data
        f.read(8)
        
        #weights
        weightCount = struct.unpack('<I', f.read(4))[0]
        print("Weights: %d" % weightCount)
        
        for weight in range(weightCount):
            w = struct.unpack('<H', f.read(2))
            #print("Weight: %d" % w)
            
    #process faces
    faceCount = struct.unpack('<I', f.read(4))[0]
    print("Faces: %d" % faceCount)
     
    for face in range(int(faceCount/3)):
        vert1 = struct.unpack('<H', f.read(2))[0]
        vert2 = struct.unpack('<H', f.read(2))[0]
        vert3 = struct.unpack('<H', f.read(2))[0]
        
        
        
        faces.append((vert1, vert3, vert2))
    
    #Read Check
    check = struct.unpack('<I', f.read(4))[0]
        
    #Add object data
    mesh = bpy.data.meshes.new("Mesh")
    mesh.vertices.add(vertCount)
    mesh.tessfaces.add(faceCount/3)
    
    mesh.vertices.foreach_set("co", unpack_list(verts))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
    mesh.tessface_uv_textures.new()
    
    for face in range(int(faceCount/3)):
        uv = mesh.tessface_uv_textures[0].data[face]
        
        uv.uv1 = uvs[faces[face][0]]
        uv.uv2 = uvs[faces[face][1]]
        uv.uv3 = uvs[faces[face][2]]
    
    mesh.validate()
    mesh.update()
    
    obj = bpy.data.objects.new("Mesh_SkinnedGeneral_0", mesh)

    blocks.append(obj)
Beispiel #22
0
def load_ply(filepath):
    import time
    from bpy_extras.io_utils import unpack_face_list
    # from bpy_extras.image_utils import load_image  # UNUSED

    t = time.time()
    obj_spec, obj = read(filepath)
    if obj is None:
        print('Invalid file')
        return

    uvindices = colindices = None
    colmultiply = None

    # noindices = None # Ignore normals

    for el in obj_spec.specs:
        if el.name == b'vertex':
            vindices_x, vindices_y, vindices_z = el.index(b'x'), el.index(b'y'), el.index(b'z')
            # noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
            # if -1 in noindices: noindices = None
            uvindices = (el.index(b's'), el.index(b't'))
            if -1 in uvindices:
                uvindices = None
            colindices = el.index(b'red'), el.index(b'green'), el.index(b'blue')
            if -1 in colindices:
                colindices = None
            else:  # if not a float assume uchar
                colmultiply = [1.0 if el.properties[i].numeric_type in {'f', 'd'} else (1.0 / 256.0) for i in colindices]

        elif el.name == b'face':
            findex = el.index(b'vertex_indices')

    mesh_faces = []
    mesh_uvs = []
    mesh_colors = []

    def add_face(vertices, indices, uvindices, colindices):
        mesh_faces.append(indices)
        if uvindices:
            mesh_uvs.append([(vertices[index][uvindices[0]], 1.0 - vertices[index][uvindices[1]]) for index in indices])
        if colindices:
            mesh_colors.append([(vertices[index][colindices[0]] * colmultiply[0],
                                 vertices[index][colindices[1]] * colmultiply[1],
                                 vertices[index][colindices[2]] * colmultiply[2],
                                 ) for index in indices])

    if uvindices or colindices:
        # If we have Cols or UVs then we need to check the face order.
        add_face_simple = add_face

        # EVIL EEKADOODLE - face order annoyance.
        def add_face(vertices, indices, uvindices, colindices):
            if len(indices) == 4:
                if indices[2] == 0 or indices[3] == 0:
                    indices = indices[2], indices[3], indices[0], indices[1]
            elif len(indices) == 3:
                if indices[2] == 0:
                    indices = indices[1], indices[2], indices[0]

            add_face_simple(vertices, indices, uvindices, colindices)

    verts = obj[b'vertex']

    if b'face' in obj:
        for f in obj[b'face']:
            ind = f[findex]
            len_ind = len(ind)
            if len_ind <= 4:
                add_face(verts, ind, uvindices, colindices)
            else:
                # Fan fill the face
                for j in range(len_ind - 2):
                    add_face(verts, (ind[0], ind[j + 1], ind[j + 2]), uvindices, colindices)

    ply_name = bpy.path.display_name_from_filepath(filepath)

    mesh = bpy.data.meshes.new(name=ply_name)

    mesh.vertices.add(len(obj[b'vertex']))

    mesh.vertices.foreach_set("co", [a for v in obj[b'vertex'] for a in (v[vindices_x], v[vindices_y], v[vindices_z])])

    if mesh_faces:
        mesh.faces.add(len(mesh_faces))
        mesh.faces.foreach_set("vertices_raw", unpack_face_list(mesh_faces))

        if uvindices or colindices:
            if uvindices:
                uvlay = mesh.uv_textures.new()
            if colindices:
                vcol_lay = mesh.vertex_colors.new()

            if uvindices:
                for i, f in enumerate(uvlay.data):
                    ply_uv = mesh_uvs[i]
                    for j, uv in enumerate(f.uv):
                        uv[0], uv[1] = ply_uv[j]

            if colindices:
                for i, f in enumerate(vcol_lay.data):
                    # XXX, colors dont come in right, needs further investigation.
                    ply_col = mesh_colors[i]
                    if len(ply_col) == 4:
                        f_col = f.color1, f.color2, f.color3, f.color4
                    else:
                        f_col = f.color1, f.color2, f.color3

                    for j, col in enumerate(f_col):
                        col.r, col.g, col.b = ply_col[j]

    mesh.validate()
    mesh.update()

    scn = bpy.context.scene
    #scn.objects.selected = [] # XXX25

    obj = bpy.data.objects.new(ply_name, mesh)
    scn.objects.link(obj)
    scn.objects.active = obj
    obj.select = True

    print('\nSuccessfully imported %r in %.3f sec' % (filepath, time.time() - t))
Beispiel #23
0
def processDeformableWindow(f, blocks):
    verts = []
    faces = []
    uvs = []
    texs = []
    
    print("44 Bytes")
    
    #Get Version
    version = struct.unpack('<B', f.read(1))[0]
    
    #Get Textures
    for i in range(8):
        length = struct.unpack('<I', f.read(4))[0]
        texStr = '<%ds' % length
        tex = struct.unpack(texStr, f.read(length))[0].decode()
        texs.append(tex)
        
        print("Texture: %s" % tex)
        
    #skip unknown data
    f.read(4)
    
    #skip unknown data
    if(version == 2):
        f.read(1024)
    

    #Get Vertices
    vertCount = struct.unpack('<I', f.read(4))[0]
    print("Vertices: %d" % vertCount)
    
    for vert in range(vertCount):
        
        x = struct.unpack('<f', f.read(4))[0]
        y = struct.unpack('<f', f.read(4))[0]
        z = struct.unpack('<f', f.read(4))[0]
        w = struct.unpack('<f', f.read(4))[0]
        
        extra1 = struct.unpack('<f', f.read(4))[0]
        extra2 = struct.unpack('<f', f.read(4))[0]
        extra3 = struct.unpack('<f', f.read(4))[0]
        extra4 = struct.unpack('<f', f.read(4))[0]
        extra5 = struct.unpack('<f', f.read(4))[0]
        extra6 = struct.unpack('<f', f.read(4))[0]
        
        u = struct.unpack('<f', f.read(4))[0]
        v = struct.unpack('<f', f.read(4))[0]
        
        verts.append((x, z, y))
        uvs.append((u, 1-v))
        
    #Get Faces
    faceCount = struct.unpack('<I', f.read(4))[0]
    print("Faces: %d" % faceCount)
    
    for face in range(int(faceCount/3)):
        
        vert1 = struct.unpack('<H', f.read(2))[0]
        vert2 = struct.unpack('<H', f.read(2))[0]
        vert3 = struct.unpack('<H', f.read(2))[0]

        faces.append((vert1, vert3, vert2))

    #skip unknown data
    if(version == 1):
        f.read(1024)

    #Read Check
    check = struct.unpack('<I', f.read(4))[0]
    
    #Add object data
    mesh = bpy.data.meshes.new("Mesh")
    mesh.vertices.add(vertCount)
    mesh.tessfaces.add(faceCount/3)
    
    mesh.vertices.foreach_set("co", unpack_list(verts))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
    mesh.tessface_uv_textures.new()
    
    for face in range(int(faceCount/3)):
        uv = mesh.tessface_uv_textures[0].data[face]
        
        uv.uv1 = uvs[faces[face][0]]
        uv.uv2 = uvs[faces[face][1]]
        uv.uv3 = uvs[faces[face][2]]
    
    mesh.validate()
    mesh.update()
    
    obj = bpy.data.objects.new("Mesh_DeformableWindow_0", mesh)

    blocks.append(obj)
Beispiel #24
0
	def ReadMesh(self, mesh):
		print("Name: {}".format(mesh["name"]))
		print("Num Verts: {}".format(len(mesh["vertices"])))
		print("Num Indices: {}".format(len(mesh["indices"][0])))

		scn = bpy.context.scene

		for o in scn.objects:
			o.select = False
		


		blenmesh = bpy.data.meshes.new(mesh["name"])
		blenmesh.vertices.add(len(mesh["vertices"]))
		blenmesh.vertices.foreach_set("co", unpack_list(mesh["vertices"]))
		blenmesh.tessfaces.add(len(mesh["indices"][0]))
		# Add faces
		blenmesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(mesh["indices"][0]))

		uvlay = blenmesh.tessface_uv_textures.new()

		for i, f in enumerate(uvlay.data):
			index = mesh["indices"][0][i]
			for j, uv in enumerate(f.uv):
				uv[0] = mesh["uvs"][index[j]][0]
				uv[1] = mesh["uvs"][index[j]][1]

		#add object to scene
		blenmesh.update()
		blenmesh.validate()
		nobj = bpy.data.objects.new(mesh["name"], blenmesh)
		scn.objects.link(nobj)


		#print("Skel: {}".format(mesh["skeleton"]))

		# Create Armature and Object
		bpy.ops.object.add(type='ARMATURE', enter_editmode=True)
		object = bpy.context.object
		object.name = 'armguy'
		armature = object.data
		armature.name = 'armguy'

		#create bones
		for the_bone in mesh["skeleton"]:
			nobj.vertex_groups.new(name=the_bone["name"])
			bone = armature.edit_bones.new(the_bone["name"])
			bone.tail = Vector([0,0,0.1]) # if you won't do it, the bone will have zero lenghtand will be removed immediately by Blender

		#map parents
		for the_bone in mesh["skeleton"]:
			if 'parent' in the_bone:
				armature.edit_bones[the_bone['name']].parent = armature.edit_bones[the_bone['parent']]
				parent = self.FindBoneByName(mesh["skeleton"], the_bone['parent'])

		for the_bone in mesh["skeleton"]:
			matrix = Matrix(the_bone["matrix"])
			matrix.transpose()
			matrix = matrix.inverted()
			armature.edit_bones[the_bone['name']].transform(matrix)

		for vidx in range(0, len(mesh["vertices"])):
			bones = mesh["bone_indices"][0][vidx]
			weights = mesh["weights"][0][vidx]
			print("Vertex: {}".format(vidx))
			print("Data: {} {}".format(bones, weights))
			for widx in range(0, len(weights)):
				bone_idx = bones[widx]
				if bone_idx == 0:
					break
				weight = weights[widx]
				nobj.vertex_groups[bone_idx].add([vidx], weight, 'ADD')
#		for vwidx, wval in enumerate(mesh["weights"][0]):
#			bones = mesh["bone_indices"][0][vwidx]
#			print("Vertex: {}".format(vwidx))
#			print("Data: {} {}".format(bones, wval))
#			for vwsidx, vwsval in enumerate(wval):
#				bone_idx = bones[vwsidx]
#				the_bone = mesh["skeleton"][bone_idx]
#				print("Bone: {} ({}): {}".format(bone_idx, the_bone["name"], vwsval))
#				nobj.vertex_groups[bone_idx].add([vwidx], vwsval, 'ADD')
		return nobj
Beispiel #25
0
	def makeObject(self):
		print("Creating mesh", end='')
		# Create the mesh
		mesh = bpy.data.meshes.new(self.name)
		mesh.tessface_uv_textures.new()

		# Skins
		if self.numSkins > 0:
			material = bpy.data.materials.new(self.name)
			for skin in self.skins:
				skinImg = Util.loadImage(skin, self.filePath)
				skinImg.mapping = 'UV'
				skinTex = bpy.data.textures.new(self.name + skin, type='IMAGE')
				skinTex.image = skinImg
				matTex = material.texture_slots.add()
				matTex.texture = skinTex
				matTex.texture_coords = 'UV'
				matTex.use_map_color_diffuse = True
				matTex.use_map_alpha = True
				matTex.uv_layer = mesh.tessface_uv_textures[0].name
			mesh.materials.append(material)
		print('.', end='')

		# Prepare vertices and faces
		mesh.vertices.add(self.numVerts)
		mesh.tessfaces.add(self.numTris)
		print('.', end='')

		# Verts
		mesh.vertices.foreach_set("co", unpack_list(self.frames[0].verts))
		mesh.transform(Matrix.Rotation(-pi / 2, 4, 'Z'))
		print('.', end='')

		# Tris
		mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list([face[0] for face in self.tris]))
		print('.', end='')

		# UV
		mesh.tessface_uv_textures[0].data.foreach_set("uv_raw", unpack_list([self.uvs[i] for i in unpack_face_list([face[1] for face in self.tris])]))
		if self.numSkins > 0:
			image = mesh.materials[0].texture_slots[0].texture.image
			if image != None:
				for uv in mesh.tessface_uv_textures[0].data:
					uv.image = image
		print('.', end='')

		mesh.validate()
		mesh.update()
		obj = bpy.data.objects.new(mesh.name, mesh)
		base = bpy.context.scene.objects.link(obj)
		bpy.context.scene.objects.active = obj
		base.select = True
		print("Done")

		# Animate
		if self.options.fImportAnimation:
			for i, frame in enumerate(self.frames):
				progressStatus = i / self.numFrames * 100
				#bpy.context.scene.frame_set(i + 1)
				obj.shape_key_add(name=frame.name, from_mix=False)
				mesh.vertices.foreach_set("co", unpack_list(frame.verts))
				mesh.transform(Matrix.Rotation(-pi / 2, 4, 'Z'))
				mesh.shape_keys.key_blocks[i].value = 1.0
				mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame = i + 1)
				if i < len(self.frames) - 1:
					mesh.shape_keys.key_blocks[i].value = 0.0
					mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame = i + 2)
				if i > 0:
					mesh.shape_keys.key_blocks[i].value = 0.0
					mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame = i)
				print("Animating - progress: %3i%%\r" % int(progressStatus), end='')
			print("Animating - progress: 100%.")
		print("Model imported")
Beispiel #26
0
def make_mesh_data(iqmodel, name, meshes, amtobj, dir):
    print("importing mesh", name, "with", len(meshes), "parts")

    mesh = bpy.data.meshes.new(name)
    obj = bpy.data.objects.new(name, mesh)
    bpy.context.scene.objects.link(obj)
    bpy.context.scene.objects.active = obj

    # Set the mesh to single-sided to spot normal errors
    mesh.show_double_sided = False

    has_vn = len(iqmodel.meshes[0].vn) > 0
    has_vt = len(iqmodel.meshes[0].vt) > 0
    has_vc = len(iqmodel.meshes[0].vc) > 0
    has_vb = len(iqmodel.meshes[0].vbi) > 0 and len(
        iqmodel.meshes[0].vbw) == len(iqmodel.meshes[0].vbi)
    has_v0 = len(iqmodel.meshes[0].v0) > 0
    has_v1 = len(iqmodel.meshes[0].v1) > 0
    has_v2 = len(iqmodel.meshes[0].v2) > 0
    has_v3 = len(iqmodel.meshes[0].v3) > 0
    has_v4 = len(iqmodel.meshes[0].v4) > 0
    has_v5 = len(iqmodel.meshes[0].v5) > 0
    has_v6 = len(iqmodel.meshes[0].v6) > 0
    has_v7 = len(iqmodel.meshes[0].v7) > 0
    has_v8 = len(iqmodel.meshes[0].v8) > 0
    has_v9 = len(iqmodel.meshes[0].v9) > 0

    # Flip winding and UV coords.

    for iqmesh in meshes:
        iqmesh.faces = [x[::-1] for x in iqmesh.faces]
        iqmesh.vt = [(u, 1 - v) for (u, v) in iqmesh.vt]

    # Blender has texcoords and colors on faces rather than vertices.
    # Create material slots for all materials used.
    # Create new vertices from unique vp/vn/vb sets (vertex data).
    # Create new faces which index these new vertices, and has associated face data.

    vertex_map = {}

    new_f = []
    new_ft = []
    new_fc = []
    new_fm_m = []
    new_fm_i = []

    new_vp = []
    new_vn = []
    new_vbi = []
    new_vbw = []
    new_v0 = []
    new_v1 = []
    new_v2 = []
    new_v3 = []
    new_v4 = []
    new_v5 = []
    new_v6 = []
    new_v7 = []
    new_v8 = []
    new_v9 = []

    for iqmesh in meshes:
        material, image = make_material(iqmesh.material, dir)
        if material.name not in mesh.materials:
            mesh.materials.append(material)
        material_index = mesh.materials.find(material.name)

        for iqface in iqmesh.faces:
            f = []
            ft = []
            fc = []
            for iqvert in iqface:
                vp = iqmesh.vp[iqvert]
                vn = iqmesh.vn[iqvert] if has_vn else None
                vbi = iqmesh.vbi[iqvert] if has_vb else None
                vbw = iqmesh.vbw[iqvert] if has_vb else None
                v0 = iqmesh.v0[iqvert] if has_v0 else None
                v1 = iqmesh.v1[iqvert] if has_v1 else None
                v2 = iqmesh.v2[iqvert] if has_v2 else None
                v3 = iqmesh.v3[iqvert] if has_v3 else None
                v4 = iqmesh.v4[iqvert] if has_v4 else None
                v5 = iqmesh.v5[iqvert] if has_v5 else None
                v6 = iqmesh.v6[iqvert] if has_v6 else None
                v7 = iqmesh.v7[iqvert] if has_v7 else None
                v8 = iqmesh.v8[iqvert] if has_v8 else None
                v9 = iqmesh.v9[iqvert] if has_v9 else None
                vertex = (vp, vn, vbi, vbw, v0, v1, v2, v3, v4, v5, v6, v7, v8,
                          v9)
                if not vertex in vertex_map:
                    vertex_map[vertex] = len(new_vp)
                    new_vp.append(vp)
                    new_vn.append(vn)
                    new_vbi.append(vbi)
                    new_vbw.append(vbw)
                    new_v0.append(v0)
                    new_v1.append(v1)
                    new_v2.append(v2)
                    new_v3.append(v3)
                    new_v4.append(v4)
                    new_v5.append(v5)
                    new_v6.append(v6)
                    new_v7.append(v7)
                    new_v8.append(v8)
                    new_v9.append(v9)
                f.append(vertex_map[vertex])
                ft.append(iqmesh.vt[iqvert] if has_vt else None)
                fc.append(iqmesh.vc[iqvert] if has_vc else None)
            f, ft, fc = reorder(f, ft, fc)
            if isdegenerate(f):
                print("degenerate face", iqface, f)
                continue
            new_f.append(f)
            new_ft.append(ft)
            new_fc.append(fc)
            new_fm_m.append(material_index)
            new_fm_i.append(image)

    print("\tcollected %d vertices and %d faces" % (len(new_vp), len(new_f)))

    # Create mesh vertex and face data

    mesh.vertices.add(len(new_vp))
    mesh.vertices.foreach_set("co", unpack_list(new_vp))

    mesh.tessfaces.add(len(new_f))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(new_f))

    # Set up UV and Color layers

    uvlayer = mesh.tessface_uv_textures.new() if has_vt else None
    clayer = mesh.tessface_vertex_colors.new() if has_vc else None

    for i, face in enumerate(mesh.tessfaces):
        face.use_smooth = True
        face.material_index = new_fm_m[i]
        if uvlayer:
            uvlayer.data[i].uv1 = new_ft[i][0]
            uvlayer.data[i].uv2 = new_ft[i][1]
            uvlayer.data[i].uv3 = new_ft[i][2]
            uvlayer.data[i].uv4 = new_ft[i][3] if len(new_ft[i]) == 4 else (0,
                                                                            0)
            uvlayer.data[i].image = new_fm_i[i]
        if clayer:
            clayer.data[i].color1 = new_fc[0]
            clayer.data[i].color2 = new_fc[1]
            clayer.data[i].color3 = new_fc[2]
            clayer.data[i].color4 = new_fc[3] if len(new_fc[i]) == 4 else (1,
                                                                           1,
                                                                           1)

    # Vertex groups and armature modifier for skinning

    if has_vb and amtobj:
        for iqbone in iqmodel.bones:
            obj.vertex_groups.new(iqbone.name)

        for vgroup in obj.vertex_groups:
            for v, vbi in enumerate(new_vbi):
                for i, bi in enumerate(vbi):
                    bw = new_vbw[v][i]
                    if bi == vgroup.index:
                        vgroup.add([v], bw, 'REPLACE')

        mod = obj.modifiers.new("Armature", 'ARMATURE')
        mod.object = amtobj
        mod.use_vertex_groups = True

    # Vertex groups for custom attributes

    def make_custom_vgroup(obj, name, size, vdata):
        print("importing custom attribute as vertex group", name)
        if size == 1:
            xg = obj.vertex_groups.new(name)
            for i, v in enumerate(vdata):
                xg.add([i], v[0], 'REPLACE')
        if size == 2:
            xg = obj.vertex_groups.new(name + ".x")
            yg = obj.vertex_groups.new(name + ".y")
            for i, v in enumerate(vdata):
                xg.add([i], v[0], 'REPLACE')
                yg.add([i], v[1], 'REPLACE')
        if size == 3:
            xg = obj.vertex_groups.new(name + ".x")
            yg = obj.vertex_groups.new(name + ".y")
            zg = obj.vertex_groups.new(name + ".z")
            for i, v in enumerate(vdata):
                xg.add([i], v[0], 'REPLACE')
                yg.add([i], v[1], 'REPLACE')
                zg.add([i], v[2], 'REPLACE')
        if size == 4:
            xg = obj.vertex_groups.new(name + ".x")
            yg = obj.vertex_groups.new(name + ".y")
            zg = obj.vertex_groups.new(name + ".z")
            wg = obj.vertex_groups.new(name + ".z")
            for i, v in enumerate(vdata):
                xg.add([i], v[0], 'REPLACE')
                yg.add([i], v[1], 'REPLACE')
                zg.add([i], v[2], 'REPLACE')
                wg.add([i], v[3], 'REPLACE')

    if has_v0:
        make_custom_vgroup(obj, iqmodel.custom_name[0], iqmodel.custom_size[0],
                           new_v0)
    if has_v1:
        make_custom_vgroup(obj, iqmodel.custom_name[1], iqmodel.custom_size[1],
                           new_v1)
    if has_v2:
        make_custom_vgroup(obj, iqmodel.custom_name[2], iqmodel.custom_size[2],
                           new_v2)
    if has_v3:
        make_custom_vgroup(obj, iqmodel.custom_name[3], iqmodel.custom_size[3],
                           new_v3)
    if has_v4:
        make_custom_vgroup(obj, iqmodel.custom_name[4], iqmodel.custom_size[4],
                           new_v4)
    if has_v5:
        make_custom_vgroup(obj, iqmodel.custom_name[5], iqmodel.custom_size[5],
                           new_v5)
    if has_v6:
        make_custom_vgroup(obj, iqmodel.custom_name[6], iqmodel.custom_size[6],
                           new_v6)
    if has_v7:
        make_custom_vgroup(obj, iqmodel.custom_name[7], iqmodel.custom_size[7],
                           new_v7)
    if has_v8:
        make_custom_vgroup(obj, iqmodel.custom_name[8], iqmodel.custom_size[8],
                           new_v8)
    if has_v9:
        make_custom_vgroup(obj, iqmodel.custom_name[9], iqmodel.custom_size[9],
                           new_v9)

    # Update mesh polygons from tessfaces

    mesh.update()

    # Must set normals after mesh.update() or they will be recalculated.
    mesh.vertices.foreach_set("normal", unpack_list(new_vn))

    return obj
Beispiel #27
0
def make_mesh(model, name, meshes, amtobj):
	print("importing mesh", name, "with", len(meshes), "parts")

	mesh = bpy.data.meshes.new(name)
	obj = bpy.data.objects.new(name, mesh)
	bpy.context.scene.objects.link(obj)
	bpy.context.scene.objects.active = obj

	# Set the mesh to single-sided to spot normal errors
	mesh.show_double_sided = False

	# Flip winding
	for m in meshes:
		m.faces = [x[::-1] for x in m.faces]

	# Positions, normals, blends and vertex groups go to vertices.
	# Material, texture coords and vertex colors go to faces.

	weld = {}
	out_vp, out_vn, out_vb = [], [], []
	out_f, out_f_mat, out_f_img, out_ft, out_fc = [], [], [], [], []

	for m in meshes:
		material, image = make_material(m.material)
		if material.name not in mesh.materials:
			mesh.materials.append(material)
		material_index = mesh.materials.find(material.name)

		out_from_in = []

		for i, p in enumerate(m.positions):
			n = m.normals[i] if len(m.normals) > i else (0,0,1)
			b = m.blends[i] if len(m.blends) > i else None
			# TODO: vertex groups custom data
			key = p, n, b
			if not key in weld:
				weld[key] = len(out_vp)
				out_vp.append(p)
				out_vn.append(n)
				out_vb.append(b)
			out_from_in.append(weld[key])

		vt, vt_names = gather_vt(model.vertexarrays, m)
		vc, vc_names = gather_vc(model.vertexarrays, m)

		print(vc_names)
		print(vc)

		for face in m.faces:
			f = [out_from_in[v] for v in face]
			ft = [[t[v] for t in vt] for v in face]
			fc = [[c[v] for c in vc] for v in face]
			f, ft, fc = reorder(f, ft, fc)
			if isdegenerate(f):
				print("degenerate face", f)
				continue

			out_f.append(f)
			out_ft.append(ft)
			out_fc.append(fc)
			out_f_mat.append(material_index)
			out_f_img.append(image)

	print("\tcollected %d vertices and %d faces" % (len(out_vp), len(out_f)))

	# Create mesh vertex and face data

	mesh.vertices.add(len(out_vp))
	mesh.vertices.foreach_set("co", unpack_list(out_vp))

	mesh.tessfaces.add(len(out_f))
	mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(out_f))

	for i, face in enumerate(mesh.tessfaces):
		face.use_smooth = True
		face.material_index = out_f_mat[i]

	for k, name in enumerate(vt_names):
		layer = mesh.tessface_uv_textures.new(name)
		for i, face in enumerate(mesh.tessfaces):
			data = layer.data[i]
			ft = out_ft[i]
			data.image = out_f_img[i]
			data.uv1 = (ft[0][k][0], 1-ft[0][k][1])
			data.uv2 = (ft[1][k][0], 1-ft[1][k][1])
			data.uv3 = (ft[2][k][0], 1-ft[2][k][1])
			if len(ft) > 3:
				data.uv4 = (ft[3][k][0], 1-ft[3][k][1])

	for k, name in enumerate(vc_names):
		layer = mesh.tessface_vertex_colors.new(name)
		for i, face in enumerate(mesh.tessfaces):
			data = layer.data[i]
			data.color1 = tuple(out_fc[i][0][k][:3])
			data.color2 = tuple(out_fc[i][1][k][:3])
			data.color3 = tuple(out_fc[i][2][k][:3])
			if len(out_fc[i]) > 3:
				data.color4 = tuple(out_fc[i][3][k][:3])

	# Vertex groups and armature modifier for skinning

	if amtobj:
		for iqbone in iqmodel.bones:
			obj.vertex_groups.new(iqbone[0])

		for vgroup in obj.vertex_groups:
			for i, b in enumerate(out_vb):
				idx, wgt = b
				if idx == vgroup.index:
					vgroup.add([i], idx, 'REPLACE')

		mod = obj.modifiers.new("Armature", 'ARMATURE')
		mod.object = amtobj
		mod.use_vertex_groups = True

	# Update mesh polygons from tessfaces

	mesh.update()

	# Must set normals after mesh.update() or they will be recalculated.
	mesh.vertices.foreach_set("normal", unpack_list(out_vn))

	return obj
Beispiel #28
0
    def createMesh(self):
        model = self.model
        vertexClass = None
        if model.vFlags == 0x180007d:
            return # no vertices
        
        vertexClassName = "VertexFormat" + hex(self.model.vFlags)
        if not vertexClassName in m3.structMap:
            raise Exception("Vertex flags %s can't behandled yet" % hex(self.model.vFlags))
        vertexClass = m3.structMap[vertexClassName]

        numberOfVertices = len(self.model.vertices) // vertexClass.size
        m3Vertices = vertexClass.createInstances(rawBytes=self.model.vertices, count=numberOfVertices)

        for division in self.model.divisions:
            divisionFaceIndices = division.faces
            for region in division.regions:
                bpy.ops.object.mode_set(mode='OBJECT')
                regionVertexIndices = range(region.firstVertexIndex,region.firstVertexIndex + region.numberOfVertices)
                firstVertexIndexIndex = region.firstFaceVertexIndexIndex
                lastVertexIndexIndex = firstVertexIndexIndex + region.numberOfFaceVertexIndices
                vertexIndexIndex = firstVertexIndexIndex
                firstVertexIndex = region.firstVertexIndex
                assert region.numberOfFaceVertexIndices % 3 == 0

                facesWithOldIndices = [] # old index = index of vertex in m3Vertices
                while vertexIndexIndex + 2 <= lastVertexIndexIndex:
                    i0 = firstVertexIndex + divisionFaceIndices[vertexIndexIndex]
                    i1 = firstVertexIndex + divisionFaceIndices[vertexIndexIndex + 1]
                    i2 = firstVertexIndex + divisionFaceIndices[vertexIndexIndex + 2]
                    face = (i0, i1, i2)
                    facesWithOldIndices.append(face)
                    vertexIndexIndex += 3

                mesh = bpy.data.meshes.new('Mesh')
                meshObject = bpy.data.objects.new('MeshObject', mesh)
                meshObject.location = (0,0,0)
                meshObject.show_name = True
                bpy.context.scene.objects.link(meshObject)
                
                # merge vertices together which have always the same position and normal:
                # This way there are not only fewer vertices to edit,
                # but also the calculated normals will more likly match
                # the given ones.
                vertexPositions = []
                nextNewVertexIndex = 0
                oldVertexIndexToNewVertexIndexMap = {}
                vertexIdTupleToNewIndexMap = {}
                for vertexIndex in regionVertexIndices:
                    m3Vertex = m3Vertices[vertexIndex]
                    v = m3Vertex
                    idTuple = (v.position.x, v.position.y, v.position.z, v.boneWeight0, v.boneWeight1, v.boneWeight2, v.boneWeight3, v.boneLookupIndex0, v.boneLookupIndex1, v.boneLookupIndex2, v.boneLookupIndex3, v.normal.x, v.normal.y, v.normal.z)
                    newIndex = vertexIdTupleToNewIndexMap.get(idTuple)
                    if newIndex == None:
                        newIndex = nextNewVertexIndex
                        nextNewVertexIndex += 1
                        position = (m3Vertex.position.x, m3Vertex.position.y, m3Vertex.position.z)
                        vertexPositions.append(position)
                        vertexIdTupleToNewIndexMap[idTuple] = newIndex
                    oldVertexIndexToNewVertexIndexMap[vertexIndex] = newIndex
                
                # since vertices got merged, the indices of the faces aren't correct anymore.
                # the old face indices however are still later required to figure out
                # what Uv coordinates a face has.
                facesWithNewIndices = []
                for faceWithOldIndices in facesWithOldIndices:
                    i0 = oldVertexIndexToNewVertexIndexMap[faceWithOldIndices[0]]
                    i1 = oldVertexIndexToNewVertexIndexMap[faceWithOldIndices[1]]
                    i2 = oldVertexIndexToNewVertexIndexMap[faceWithOldIndices[2]]
                    faceWithNewIndices = (i0, i1, i2)
                    facesWithNewIndices.append(faceWithNewIndices)
                
                mesh.vertices.add(len(vertexPositions))
                mesh.vertices.foreach_set("co", io_utils.unpack_list(vertexPositions))

                mesh.tessfaces.add(len(facesWithNewIndices))
                mesh.tessfaces.foreach_set("vertices_raw", io_utils.unpack_face_list(facesWithNewIndices))

                for vertexUVAttribute in ["uv0", "uv1", "uv2", "uv3"]:
                    if vertexUVAttribute in vertexClass.fieldToTypeInfoMap: 
                        uvLayer = mesh.tessface_uv_textures.new()
                        for faceIndex, face in enumerate(facesWithOldIndices):
                            faceUV = uvLayer.data[faceIndex]
                            faceUV.uv1 = toBlenderUVCoordinate(getattr(m3Vertices[face[0]],vertexUVAttribute))
                            faceUV.uv2 = toBlenderUVCoordinate(getattr(m3Vertices[face[1]],vertexUVAttribute))
                            faceUV.uv3 = toBlenderUVCoordinate(getattr(m3Vertices[face[2]],vertexUVAttribute))

                mesh.update(calc_edges=True)
                
                boneIndexLookup = model.boneLookup[region.firstBoneLookupIndex:region.firstBoneLookupIndex + region.numberOfBoneLookupIndices]
                vertexGroupLookup = []
                for boneIndex in boneIndexLookup:
                    boneName = shared.toValidBoneName(model.bones[boneIndex].name)
                    if boneName in meshObject.vertex_groups:
                        vertexGroup = meshObject.vertex_groups[boneName]
                    else:
                        vertexGroup =  meshObject.vertex_groups.new(boneName)
                    vertexGroupLookup.append(vertexGroup)
                for vertexIndex in range(region.firstVertexIndex,region.firstVertexIndex + region.numberOfVertices):
                    m3Vertex = m3Vertices[vertexIndex]
                    boneWeightsAsInt = [m3Vertex.boneWeight0, m3Vertex.boneWeight1, m3Vertex.boneWeight2, m3Vertex.boneWeight3]
                    boneLookupIndices = [m3Vertex.boneLookupIndex0, m3Vertex.boneLookupIndex1,  m3Vertex.boneLookupIndex2,  m3Vertex.boneLookupIndex3]
                    boneWeights = []
                    for boneWeightAsInt, boneLookupIndex in zip(boneWeightsAsInt, boneLookupIndices):
                        if boneWeightAsInt != 0:
                            vertexGroup = vertexGroupLookup[boneLookupIndex]
                            boneWeight = boneWeightAsInt / 255.0
                            vertexGroup.add([oldVertexIndexToNewVertexIndexMap[vertexIndex]], boneWeight, 'REPLACE')

                modifier = meshObject.modifiers.new('UseArmature', 'ARMATURE')
                modifier.object = self.armatureObject
                modifier.use_bone_envelopes = False
                modifier.use_vertex_groups = True
def load(operator, context, filepath,
         global_clamp_size=0.0,
         use_verbose=False,
         use_image_search=True,
         use_computed_normals=False,
         use_shadeless=True,
         viz_normals=True,
         viz_blendweights=False,
         use_specular=True,
         global_matrix=None,
         ):
    '''
    Called by the user interface or another script.
    load_obj(path) - should give acceptable results.
    This function passes the file and sends the data off
        to be split into objects and then converted into mesh objects
    '''
    print('\nimporting crf %r' % filepath)

    filepath = os.fsencode(filepath)

    if global_matrix is None:
        global_matrix = mathutils.Matrix()

    new_objects = []  # put new objects here
    
    time_main = time.time()
    print("\tparsing crf file...")
    time_sub = time.time()
#     time_sub= sys.time()

    file = open(filepath, "rb")
    crf_magick, = struct.unpack("<Q", file.read(8))    
    if crf_magick != 0x1636E6B66:
        print("Not a CRF file!")
        return 

    footer_offset1,footer_offset2 = struct.unpack("<II", file.read(8))
    # so far found model type 0x2 and 0x4
    object_type, magick4, num_meshes_in_file = struct.unpack("<III", file.read(12))
    LoX, LoY, LoZ = struct.unpack("<fff", file.read(12))        
    HiX, HiY, HiZ = struct.unpack("<fff", file.read(12)) #bounding box?
    print("(%f, %f, %f) (%f, %f, %f)" % (LoX, LoY, LoZ, HiX, HiY, HiZ))
    print("Object type", hex(object_type))

    # start unpacking loop here
    for model_number in range(0, num_meshes_in_file):
        verts_loc = []
        verts_tex0 = []
        verts_tex1 = []
        faces = []  # tuples of the faces
        face_tex = [] # tuples of uv coordinates for faces
        vertex_normals = []
        vertex_specular = []
        vertex_blendweights1 = []

        number_of_verteces, = struct.unpack("<I", file.read(4))
        number_of_faces, = struct.unpack("<I", file.read(4))
        print("Model: %i, verteces: %i, faces: %i" % (model_number, number_of_verteces, number_of_faces))
        # read in face/vertex index list
        for i in range(0, number_of_faces):
                v1, v2, v3 = struct.unpack("<HHH", file.read(6))
                face_vert_loc_indices = [v1, v2, v3]
                face_vert_tex_indices = [v1, v2, v3]
                faces.append((v1, v2, v3))
                if use_verbose:
                    print("face index %s, verts (%s, %s, %s)" % (i, v1, v2, v3))


        #read start token     #0x0000200c01802102, 0x00
        start_token, = struct.unpack("<Qx", file.read(9)) 


        if use_verbose:
            print("Loading file, printing raw vertex information.")
        # read in verteces, vertex normals, ks, and UVs
        for i in range(0, number_of_verteces):
            vertex = CRF_vertex()
            vertex.index = i
            vertex.x, vertex.y, vertex.z, \
                vertex.normal_x, vertex.normal_y, vertex.normal_z, vertex.normal_w, \
                vertex.specular_blue, vertex.specular_green, vertex.specular_red, vertex.specular_alpha, \
                vertex.u0, vertex.v0, vertex.u1, vertex.v1, \
                vertex.blendweights1_x, vertex.blendweights1_y, \
                vertex.blendweights1_z, vertex.blendweights1_w = struct.unpack("<fffBBBBBBBBhhhhBBBB", file.read(32))
            
            vertex.raw2blend()
            
            if use_verbose:                
                print(vertex)            
            
            verts_loc.append( (vertex.x_blend, vertex.y_blend, vertex.z_blend) )            
            verts_tex0.append( (vertex.u0_blend, vertex.v0_blend) )        

            vertex_normals.append( (vertex.normal_x_blend, vertex.normal_y_blend, vertex.normal_z_blend, vertex.normal_w_blend) )
            vertex_specular.append( (vertex.specular_red_blend, vertex.specular_green_blend, vertex.specular_blue_blend, vertex.specular_alpha_blend) )
            vertex_blendweights1.append( (vertex.blendweights1_x_blend, vertex.blendweights1_y_blend, vertex.blendweights1_z_blend, vertex.blendweights1_w_blend) )

        #read in separator 0x000000080008000000
        #TODO not all files have this separator
        print("Separator at", hex(file.tell()))
        separator = struct.unpack("<8B", file.read(8))

        if use_verbose:
            print("Second vertex data stream at", hex(file.tell()))
        #read in second vertex stream, but don't use it for anything
        #TODO figure out why this is here
        for i in range(0, number_of_verteces):
            unknown0, unknown1 = struct.unpack("<ff", file.read(8))
            if use_verbose:
                print("vert index=%s, x?=%s, y?=%s" % (i, unknown0, unknown1))

        #if object type is 0x4, read in second set of blendweights
        #TODO not sure how this data is used
        if object_type == 0x4:
            if use_verbose:
                print("Second blendweight? list at", hex(file.tell()))
            unknown1, unknown2 = struct.unpack("<II", file.read(8))
            for i in range(0, number_of_verteces):
                blendweights2, = struct.unpack("<I", file.read(4))
                if use_verbose:
                    print(i, blendweights2)
            # read in one more int
            #file.read(8)
        print(hex(file.tell()))
            
        #read in bounding box?
        bounding_box = struct.unpack("<6f", file.read(24))
        if use_verbose:
            print("Bounding box? ", bounding_box)
            
        #read in material information
        texture_name = b''
        normal_name = b''
        specular_name = b''
        specular_list = []
        texture_name, normal_name, specular_name = parseMaterialInfo(file, specular_list)        
        print(texture_name, normal_name, specular_name, specular_list)    
        #next is object bone information, not parsed
        
        # deselect all
        if bpy.ops.object.select_all.poll():
            bpy.ops.object.select_all(action='DESELECT')

        scene = context.scene
    #     scn.objects.selected = []

        me = bpy.data.meshes.new("Dumped_Mesh")   # create a new mesh
        object_name = os.path.splitext(os.path.basename(filepath))[0]
        ob = bpy.data.objects.new(os.fsdecode(object_name) + "_%i" % model_number, me)
        # Fill the mesh with verts, edges, faces
        from bpy_extras.io_utils import unpack_list
        me.vertices.add(len(verts_loc))
        me.vertices.foreach_set("co", unpack_list(verts_loc))
        me.tessfaces.add(len(faces))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        #me.update(calc_edges=True)    # Update mesh with new data and in 2.63 convert tessfaces to poly

        # fill face uv texture array
        for face in ob.data.tessfaces:
            verts_in_face = face.vertices[:]
            if use_verbose:
                print("face index", face.index)  
                print("normal", face.normal)  
                for vert in verts_in_face:  
                    print("vert", vert, " vert co", ob.data.vertices[vert].co)
                    print("Normal X:%s Y:%s Z:%s " % (vertex_normals[vert][0], vertex_normals[vert][1], vertex_normals[vert][2]))
                    print("specular R:%s G:%s B:%s " % (vertex_specular[vert][0], vertex_specular[vert][1], vertex_specular[vert][2]))
                    print("UV0: ", verts_tex0[vert])
                    print()
            i = face.index
            v1 = verts_in_face[0]
            v2 = verts_in_face[1]
            v3 = verts_in_face[2]
            face_tex.append([ verts_tex0[v1], verts_tex0[v2], verts_tex0[v3] ] )

        if use_image_search:
            uvMain = createTextureLayer("UV_Main", me, face_tex)
            texture_filepath = findTextureFile(os.fsdecode(filepath),  texture_name.decode(sys.stdout.encoding))
            normals_filepath = findTextureFile(os.fsdecode(filepath),  normal_name.decode(sys.stdout.encoding))
            specular_filepath = findTextureFile(os.fsdecode(filepath),  specular_name.decode(sys.stdout.encoding))            
            print(texture_filepath, normals_filepath, specular_filepath)            
            mat = createMaterial('TexMat', use_shadeless, viz_normals)
            if texture_filepath != None and texture_filepath != "":
                addDiffuseTexture(texture_filepath, mat)
            if normals_filepath != None and normals_filepath != "":
                addNormalTexture(normals_filepath, mat)
            if use_specular and specular_filepath != None and specular_filepath != "":
                addSpecularTexture(specular_filepath, mat)                
            ob.data.materials.append(mat)

        if viz_normals:
            setVertexNormalsColors(me, ob.data.tessfaces, vertex_normals)
            # if no materials exist, create one+
            if len(ob.data.materials) == 0 and not use_image_search:
                mat = createMaterial('SimpleMat', use_shadeless, viz_normals)
                ob.data.materials.append(mat)
        
        if use_computed_normals:
            for vertex, vertex_normal in zip(me.vertices, vertex_normals):
                print("vertex index", vertex.index, vertex_normal)
                vertex.normal = vertex_normal[0:3]
                
        if use_specular:
            setVertexSpecularColors(me, ob.data.tessfaces, vertex_specular)
            # if no materials exist, create one+
            if len(ob.data.materials) == 0 and not use_image_search:
                mat = createMaterial('Specular', use_shadeless, viz_normals)
                mat.specular_color = specular_list[0]
                ob.data.materials.append(mat)
            else:
                #ob.data.materials[0] = specular_list[0]
                ob.data.materials[0].specular_color = specular_list[0]
                print(ob.data.materials[0].specular_color)

        if viz_blendweights:
            setVertexBlendweightColors(me, ob.data.tessfaces, vertex_blendweights1)
            # if no materials exist, create one+
            if len(ob.data.materials) == 0 and not use_image_search:
                mat = createMaterial('BlendweightMat', use_shadeless, True)
                ob.data.materials.append(mat)

        me.update(calc_tessface=True, calc_edges=True)
        new_objects.append(ob)

    # end loop
    
    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new

    print('\tloading materials and images...')


    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new
    
    # Create new obj
    for obj in new_objects:
        base = scene.objects.link(obj)
        base.select = True

        # we could apply this anywhere before scaling.
        obj.matrix_world = global_matrix

    scene.update()

    axis_min = [1000000000] * 3
    axis_max = [-1000000000] * 3

    if global_clamp_size:
        # Get all object bounds
        for ob in new_objects:
            for v in ob.bound_box:
                for axis, value in enumerate(v):
                    if axis_min[axis] > value:
                        axis_min[axis] = value
                    if axis_max[axis] < value:
                        axis_max[axis] = value

        # Scale objects
        max_axis = max(axis_max[0] - axis_min[0], axis_max[1] - axis_min[1], axis_max[2] - axis_min[2])
        scale = 1.0

        while global_clamp_size < max_axis * scale:
            scale = scale / 10.0

        for obj in new_objects:
            obj.scale = scale, scale, scale

    
    time_new = time.time()

    print("finished importing: %r in %.4f sec." % (filepath, (time_new - time_main)))
    return {'FINISHED'}
Beispiel #30
0
	def create_blender_object(self, ac_matlist, str_pre, bLevelLinked):

		if self.type == 'world':
			self.name = self.import_config.ac_name
			self.rotation = self.import_config.global_matrix
		me = None
		if self.type == 'group':
			# Create an empty object
			self.bl_obj = bpy.data.objects.new(self.name, None)

		if self.type == 'poly':
			meshname = self.name
			if len(self.data)>0:
				meshname = self.data
			me = bpy.data.meshes.new(meshname)
			self.bl_obj = bpy.data.objects.new(self.name, me)

		# setup parent object
		if self.ac_parent:
			self.bl_obj.parent = self.ac_parent.bl_obj

		# make sure we have something to work with
		if self.vert_list and me:

			me.use_auto_smooth = self.import_config.use_auto_smooth
			me.auto_smooth_angle = radians(self.crease)
			
			for surf in self.surf_list:
				surf_edges = surf.get_edges()
				surf_face = surf.get_faces()
				for edge in surf_edges:
					self.edge_list.append(edge)

				if surf.flags.type == 0:
					# test for invalid face (ie, >4 vertices)
					if len(surf.refs) > 4 or len(surf.refs) < 3:
						# not bringing in faces (assumed that there are none in a poly-line)
						TRACE("Ignoring surface (vertex-count: {0})".format(len(surf.refs)))
					else:

						self.face_list.append(surf_face)
						
						# Material index is 1 based, the list we built is 0 based
						ac_material = ac_matlist[surf.mat_index]
						bl_material = ac_material.get_blender_material(self.tex_name)

						if bl_material == None:
							TRACE("Error getting material {0} '{1}'".format(surf.mat_index, self.tex_name))

						fm_index = 0
						if not bl_material.name in me.materials:
							me.materials.append(bl_material)
							fm_index = len(me.materials)-1
						else:
							for mat in me.materials:
								if mat == bl_material:
									continue
								fm_index += 1
							if fm_index > len(me.materials):
								TRACE("Failed to find material index")
								fm_index = 0
						self.face_mat_list.append(fm_index)
				else:
					# treating as a polyline (nothing more to do)
					pass

			me.vertices.add(len(self.vert_list))
			me.tessfaces.add(len(self.face_list))
			
			# verts_loc is a list of (x, y, z) tuples
			me.vertices.foreach_set("co", unpack_list(self.vert_list))
			
			# faces is a list of (vert_indices, texco_indices, ...) tuples
			me.tessfaces.foreach_set("vertices_raw", unpack_face_list(self.face_list))
				
#			face_mat = [m for m in self.face_mat_list]
#			me.tessfaces.foreach_set("material_index", face_mat)
#			del face_mat
				
			if len(self.tex_name):
				me.tessface_uv_textures.new()
#				uv_tex.active = True
#				uv_tex.active_render = True
			else:
				uv_tex = None
				
			two_sided_lighting = False
				
			for i, face in enumerate(self.face_list):
				blender_face = me.tessfaces[i]
				surf = self.surf_list[i]
				
				blender_face.use_smooth = surf.flags.shaded

				# If one surface is twosided, they all will be...
				two_sided_lighting |= surf.flags.two_sided

				if len(self.tex_name) and len(surf.uv_refs) >= 3:
					blender_tface = me.tessface_uv_textures[0].data[i]

					blender_tface.uv1 = surf.uv_refs[0]
					blender_tface.uv2 = surf.uv_refs[1]
					blender_tface.uv3 = surf.uv_refs[2]

					if len(surf.uv_refs) > 3:
						blender_tface.uv4 = surf.uv_refs[3]

					surf_material = me.materials[self.face_mat_list[i]]
					blender_tface.image = surf_material.texture_slots[0].texture.image

#						uv_tex.data[f_index].use_image = True

			me.show_double_sided = two_sided_lighting
			
			self.bl_obj.show_transparent = self.import_config.display_transparency

		if self.bl_obj:
			self.bl_obj.rotation_euler = self.rotation.to_euler()

			self.bl_obj.location = self.location
			
			self.import_config.context.scene.objects.link(self.bl_obj)
# There's a bug somewhere - this ought to work....
			self.import_config.context.scene.objects.active = self.bl_obj
#			bpy.ops.object.origin_set('ORIGIN_GEOMETRY', 'MEDIAN')
			

		TRACE("{0}+-{1} ({2})".format(str_pre, self.name, self.data))

		# Add any children
		str_pre_new = ""
		bUseLink = True
		for obj in self.children:
			if bLevelLinked:
				str_pre_new = str_pre + "| "
			else:
				str_pre_new = str_pre + "  "

			if self.children.index(obj) == len(self.children)-1:
				bUseLink = False

			obj.create_blender_object(ac_matlist, str_pre_new, bUseLink)


		if me:
#			me.calc_normals()
			me.validate()
			me.update(calc_edges=True)
Beispiel #31
0
    def FLDSMDFR(self, file_gpu):
        file_gpu.seek(self.mesh_header.mesh_dataStart, 0)
        self.byte_count = self.mesh_header.vertexCount * self.m0.stride
        ti_0 = np.fromfile(file_gpu, dtype='B', count=self.byte_count).reshape(
            (self.mesh_header.vertexCount, self.m0.stride))

        for x in cat_list:
            cat(self.m0.data, x)
        for p in self.m0.data:
            g = self.m0.data[p]
            chunc = data_paver(g["start"], g["end"],
                               self.mesh_header.vertexCount,
                               g["item_subCount"], g["d_type"], ti_0)
            if p == "POSITION0":
                chunc[:, [1, 2]] = chunc[:, [2, 1]]
                self.VA = chunc.tolist()
            elif p == "BLENDINDICES":
                self.bone_ids = chunc.tolist()
            elif p == "BLENDWEIGHTS":
                self.weights = chunc.tolist()

        chunk2_start = self.mesh_header.mesh_dataStart + self.m1.offset
        byteCount2 = self.mesh_header.vertexCount * self.m1.stride
        file_gpu.seek(chunk2_start, 0)
        ti_1 = np.fromfile(file_gpu, dtype='B', count=byteCount2).reshape(
            (self.mesh_header.vertexCount, self.m1.stride))

        uv_count = 0
        for j in self.m1.data:
            z = self.m1.data[j]
            chunc = data_paver(z["start"], z["end"],
                               self.mesh_header.vertexCount,
                               z["item_subCount"], z["d_type"], ti_1)
            if j == "NORMAL0":
                Normal_Array0 = chunc[:, 0:3].reshape(
                    (self.mesh_header.vertexCount, 3))
                Normal_Array0[:, [1, 2]] = Normal_Array0[:, [2, 1]]
                Normal_Array = Normal_Array0.tolist()
            elif j == "TANGENT0":
                pass
            elif j == "TEXCOORD0":
                uv_count += 1
                chunc[:, 1:2] *= -1
                chunc[:, 1:2] += 1
                uvData0 = chunc.tolist()
                self.UVs0 = [mu.Vector(x) for x in uvData0]
            elif j == "TEXCOORD1":
                uv_count += 1
                chunc[:, 1:2] *= -1
                chunc[:, 1:2] += 1
                uvData1 = chunc.tolist()
                self.UVs1 = [mu.Vector(x) for x in uvData1]
            elif j == "TEXCOORD2":
                uv_count += 1
                chunc[:, 1:2] *= -1
                chunc[:, 1:2] += 1
                uvData2 = chunc.tolist()
                self.UVs2 = [mu.Vector(x) for x in uvData2]
            elif j == "TEXCOORD3":
                uv_count += 1
                chunc[:, 1:2] *= -1
                chunc[:, 1:2] += 1
                uvData3 = chunc.tolist()
                self.UVs3 = [mu.Vector(x) for x in uvData3]
            elif j == "NORMAL4FACTORS0":
                pass
            elif j == "NORMAL2FACTORS0":
                pass

        mesh = bpy.data.meshes.new(self.name)
        mesh.vertices.add(len(self.VA))
        mesh.tessfaces.add(len(self.faces))
        mesh.vertices.foreach_set("co", unpack_list(self.VA))
        mesh.tessfaces.foreach_set("vertices_raw",
                                   unpack_face_list(self.faces))
        for g in range(uv_count):
            mesh.tessface_uv_textures.new()
        me_faces = mesh.tessfaces
        '''
		for f, g in enumerate(mesh.vertices):
			g.normal = Normal_Array[f]
		'''

        # UVs
        UVS = 0
        for g in range(uv_count):
            if g == 0: UVS = self.UVs0
            elif g == 1: UVS = self.UVs1
            elif g == 2: UVS = self.UVs2
            elif g == 3: UVS = self.UVs3
            for i, face in enumerate(self.faces):
                idx = self.faces[i]
                blender_tface = mesh.tessface_uv_textures[g].data[i]
                blender_tface.uv1 = UVS[face[0]]
                blender_tface.uv2 = UVS[face[1]]
                blender_tface.uv3 = UVS[face[2]]

        mesh.validate()
        mesh.update()

        self.meshObject = bpy.data.objects.new(self.name, mesh)

        if self.V_28:
            bpy.context.scene.collection.objects.link(self.meshObject)
            self.meshObject.select_set("SELECT")
        else:
            bpy.context.scene.objects.link(self.meshObject)
            self.meshObject.select = True

        mesh.polygons.foreach_set("use_smooth", [True] * len(mesh.polygons))
        bpy.context.scene.update()
Beispiel #32
0
def load(operator,
         context,
         filepath,
         global_clamp_size=0.0,
         use_verbose=False,
         dump_first_only=False,
         use_uv_map=True,
         use_diffuse_texture=True,
         use_normal_texture=True,
         use_specular_texture=True,
         use_computed_normals=False,
         use_shadeless=True,
         viz_normals=True,
         viz_blendweights=False,
         use_specular=True,
         global_matrix=None,
         use_debug_bones=False):
    '''
    Called by the user interface or another script.
    load_obj(path) - should give acceptable results.
    This function passes the file and sends the data off
        to be split into objects and then converted into mesh objects
    '''
    print('\nimporting crf %r' % filepath)

    filepath = os.fsencode(filepath)

    if global_matrix is None:
        global_matrix = mathutils.Matrix()

    new_objects = []  # put new objects here

    time_main = time.time()
    print("\tparsing crf file...")
    time_sub = time.time()

    file = open(filepath, "rb")
    CRF = CRF_object()
    CRF.parse_bin(file)
    meshfile = CRF.meshfile

    bad_vertex_list = []

    # start importing meshes
    for i in range(0, meshfile.num_meshes):
        verts_loc = []
        verts_tex0 = []
        verts_tex1 = []
        faces = []  # tuples of the faces
        face_tex = []  # tuples of uv coordinates for faces
        vertex_normals = []
        vertex_specular = []
        vertex_blendweights1 = []

        mesh = meshfile.meshes[i]
        faces = mesh.face_list

        #convert from DirectX to Blender face vertex ordering
        bad_mesh_vertex_list = []
        for i in range(0, len(faces)):
            v1, v2, v3 = faces[i]
            # if there are duplicated vertices in triangle, delete that face by making all vertices the same
            if v1 == v2 or v1 == v3 or v2 == v3:
                print("Found a bad face %i, eliminating %i,%i,%i" %
                      (i, v1, v2, v3))
                faces[i] = (v3, v3, v3)
                bad_mesh_vertex_list.append(v1)
                bad_mesh_vertex_list.append(v2)
                bad_mesh_vertex_list.append(v3)
            else:
                faces[i] = (v3, v2, v1)
        bad_vertex_list.append(bad_mesh_vertex_list)

        for vertex in mesh.vertices0:
            verts_loc.append((vertex.x_blend, vertex.y_blend, vertex.z_blend))
            verts_tex0.append((vertex.u0_blend, vertex.v0_blend))

            vertex_normals.append(
                (vertex.normal_x_blend, vertex.normal_y_blend,
                 vertex.normal_z_blend, vertex.normal_w_blend))
            vertex_specular.append(
                (vertex.specular_red_blend, vertex.specular_green_blend,
                 vertex.specular_blue_blend, vertex.specular_alpha_blend))
            vertex_blendweights1.append(
                (vertex.blendweights1_x_blend, vertex.blendweights1_y_blend,
                 vertex.blendweights1_z_blend, vertex.blendweights1_w_blend))

        # deselect all
        if bpy.ops.object.select_all.poll():
            bpy.ops.object.select_all(action='DESELECT')

        # create blender mesh
        me = bpy.data.meshes.new("Dumped_Mesh")  # create a new mesh
        object_name = os.path.splitext(os.path.basename(filepath))[0]
        ob = bpy.data.objects.new(
            os.fsdecode(object_name) + "_%i" % mesh.mesh_number, me)
        # Fill the mesh with verts, edges, faces
        me.vertices.add(len(verts_loc))
        me.vertices.foreach_set("co", unpack_list(verts_loc))
        me.tessfaces.add(len(faces))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

        # use computed normals
        if use_computed_normals:
            for vertex, vertex_normal in zip(me.vertices, vertex_normals):
                print("vertex index", vertex.index, vertex_normal)
                vertex.normal = vertex_normal[0:3]

        # fill face uv texture array
        for face in ob.data.tessfaces:
            verts_in_face = face.vertices[:]
            if use_verbose:
                print("face index", face.index)
                print("normal", face.normal)
                for vert in verts_in_face:
                    print("vert", vert, " vert co", ob.data.vertices[vert].co)
                    print("Normal X:%s Y:%s Z:%s " %
                          (vertex_normals[vert][0], vertex_normals[vert][1],
                           vertex_normals[vert][2]))
                    print("specular R:%s G:%s B:%s " %
                          (vertex_specular[vert][0], vertex_specular[vert][1],
                           vertex_specular[vert][2]))
                    print("UV0: ", verts_tex0[vert])
                    print()
            i = face.index
            v1 = verts_in_face[0]
            v2 = verts_in_face[1]
            v3 = verts_in_face[2]
            face_tex.append([verts_tex0[v1], verts_tex0[v2], verts_tex0[v3]])

        # start all optional tasks
        # add uv map
        if use_uv_map:
            uvMain = createTextureLayer("UV_Main", me, face_tex)

        # add texture
        if use_diffuse_texture or use_normal_texture or use_specular_texture:
            # create a material to which textures can be added
            mat = createMaterial('TexMat', use_shadeless, viz_normals)
            if use_diffuse_texture:
                diffuse_texture = mesh.materials.diffuse_texture
                diffuse_texture_filepath = findTextureFile(
                    os.fsdecode(filepath),
                    diffuse_texture.decode(sys.stdout.encoding))
                print("Adding diffuse texture ", diffuse_texture_filepath)
                if diffuse_texture_filepath != None and diffuse_texture_filepath != "":
                    addDiffuseTexture(diffuse_texture_filepath, mat)
                    mat.use_transparency = True
                    mat.alpha = 0  #TODO check model data for this param
            if use_normal_texture:
                normal_texture = mesh.materials.normal_texture
                normal_texture_filepath = findTextureFile(
                    os.fsdecode(filepath),
                    normal_texture.decode(sys.stdout.encoding))
                print("Adding normals texture ", normal_texture_filepath)
                if normal_texture_filepath != None and normal_texture_filepath != "":
                    addNormalTexture(normal_texture_filepath, mat)
            if use_specular_texture:
                specular_texture = mesh.materials.specular_texture
                specular_texture_filepath = findTextureFile(
                    os.fsdecode(filepath),
                    specular_texture.decode(sys.stdout.encoding))
                print("Adding normals texture ", specular_texture_filepath)
                if specular_texture_filepath != None and specular_texture_filepath != "":
                    addSpecularTexture(specular_texture_filepath, mat)
            ob.data.materials.append(mat)

        # viz normals

        # add specular constant
        if use_specular:
            vertex_specular = []
            for vertex in mesh.vertices0:
                vertex_specular.append(
                    (vertex.specular_red_blend, vertex.specular_green_blend,
                     vertex.specular_blue_blend, vertex.specular_alpha_blend))

            setVertexSpecularColors(me, ob.data.tessfaces, vertex_specular)
            # if no materials exist, create one+
            if len(ob.data.materials) == 0:
                mat = createMaterial('Specular', use_shadeless, viz_normals)
                mat.specular_color = mesh.materials.specular_constant
                ob.data.materials.append(mat)
            else:
                if mesh.materials.specular_constant != None:
                    ob.data.materials[
                        0].specular_color = mesh.materials.specular_constant
                else:
                    ob.data.materials[0].specular_color = (1, 0, 0)
                    print("Failed to find specular constnat! FIXME")
                print(ob.data.materials[0].specular_color)

        # viz blendweights

        # end all optional tasks

        me.update(calc_tessface=True, calc_edges=True)
        new_objects.append(ob)
    # end loop for importing meshes

    # import bones, create armature
    if CRF.footer.get_jointmap() != None:
        amt = bpy.data.armatures.new("Armature")
        amt_ob = bpy.data.objects.new("Armature", amt)
        scn = bpy.context.scene
        scn.objects.link(amt_ob)
        scn.objects.active = amt_ob
        amt_ob.select = True

        bpy.ops.object.mode_set(mode='EDIT')
        make_skel(amt, CRF.jointmap, 0)

        if use_debug_bones:
            for key, value in CRF.jointmap.bone_dict.items():
                crf_joint = CRF.jointmap.joint_list[key]
                m = bone_transform(crf_joint.matrix)
                print("Bone %i\n" % key, m, "parent", crf_joint.parent_id)
                bpy.ops.mesh.primitive_uv_sphere_add(size=0.1,
                                                     location=(0, 0, 0))
                bpy.context.object.matrix_world = m
                bpy.context.object.name = "joint_%s_%s" % (
                    key, CRF.jointmap.bone_dict[key].bone_name)

        bpy.ops.object.mode_set(mode='OBJECT')
        amt_ob.select = False

    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new

    print('\tloading materials and images...')

    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new

    # Create new obj
    scene = context.scene
    for ob, bad_vertices in zip(new_objects, bad_vertex_list):
        base = scene.objects.link(ob)
        base.select = True

        # we could apply this anywhere before scaling.
        ob.matrix_world = global_matrix

        #delete bad vertices
        bpy.context.scene.objects.active = ob
        ob.select = True
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='DESELECT')
        bpy.ops.object.mode_set(mode='OBJECT')
        for v in bad_vertices:
            print("Deleting vertex %i in %s" % (v, ob.name))
            ob.data.vertices[v].select = True
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.mode_set(mode='OBJECT')

    if CRF.footer.get_jointmap() != None:
        #select objects, select armature as active, parent objects to armature
        bpy.ops.object.select_all(action='DESELECT')  #deselect all object
        for ob in new_objects:
            print("in loop ", ob)
            ob.select = True
        bpy.context.scene.objects.active = amt_ob  #the active object will be the parent of all selected object
        bpy.ops.object.parent_set(type='ARMATURE_NAME')

        # print all vertex groups for each object
        #for ob in new_objects:
        #    print(ob.vertex_groups.keys())
        #for ob in new_objects:
        #    for v in ob.data.vertices:
        #        print("number of groups", len(v.groups))

        obj_id = 0
        for ob in new_objects:
            if len(CRF.meshfile.meshes[obj_id].vertices1) != 0:
                for v in ob.data.vertices:
                    CRF.meshfile.meshes[obj_id].vertices1[
                        v.index].raw2blend()  # convert
                    blendindices = CRF.meshfile.meshes[obj_id].vertices1[
                        v.index].blendindices
                    blendweights = CRF.meshfile.meshes[obj_id].vertices1[
                        v.index].blendweights_blend
                    """
                    try:
                        pos  = blendindices.index(CRF.jointmap.bone_name_id_dict[b"Bone01_L_Forearm"])
                        blendindices = [blendindices[pos]+1]
                        blendweights = [1.0]
                    except ValueError:
                        blendindices = []
                        blendindices = []
                    """

                    #print(blendindices, blendweights)
                    for bi, bw in zip(blendindices, blendweights):
                        #print("Assign vertex %s group %s with weight %s" % (v.index, bi, bw))
                        new_objects[obj_id].vertex_groups[bi].add([v.index],
                                                                  bw, 'ADD')
            obj_id += 1

    scene.update()

    axis_min = [1000000000] * 3
    axis_max = [-1000000000] * 3

    if global_clamp_size:
        # Get all object bounds
        for ob in new_objects:
            for v in ob.bound_box:
                for axis, value in enumerate(v):
                    if axis_min[axis] > value:
                        axis_min[axis] = value
                    if axis_max[axis] < value:
                        axis_max[axis] = value

        # Scale objects
        max_axis = max(axis_max[0] - axis_min[0], axis_max[1] - axis_min[1],
                       axis_max[2] - axis_min[2])
        scale = 1.0

        while global_clamp_size < max_axis * scale:
            scale = scale / 10.0

        for obj in new_objects:
            obj.scale = scale, scale, scale

    time_new = time.time()
    print("finished importing: %r in %.4f sec." % (filepath,
                                                   (time_new - time_main)))
    return {'FINISHED'}
Beispiel #33
0
def create_mesh(new_objects,
                has_ngons,
                use_ngons,
                use_edges,
                verts_loc,
                verts_tex,
                faces,
                unique_materials,
                unique_material_images,
                unique_smooth_groups,
                vertex_groups,
                dataname,
                ):
    """
    Takes all the data gathered and generates a mesh, adding the new object to new_objects
    deals with ngons, sharp edges and assigning materials
    """
    from bpy_extras.mesh_utils import ngon_tessellate

    if not has_ngons:
        use_ngons = False

    if unique_smooth_groups:
        sharp_edges = {}
        smooth_group_users = {context_smooth_group: {} for context_smooth_group in list(unique_smooth_groups.keys())}
        context_smooth_group_old = -1

    # Split ngons into tri's
    fgon_edges = set()  # Used for storing fgon keys
    if use_edges:
        edges = []

    context_object = None

    # reverse loop through face indices
    for f_idx in range(len(faces) - 1, -1, -1):

        (face_vert_loc_indices,
         face_vert_tex_indices,
         context_material,
         context_smooth_group,
         context_object,
         ) = faces[f_idx]

        len_face_vert_loc_indices = len(face_vert_loc_indices)

        if len_face_vert_loc_indices == 1:
            faces.pop(f_idx)  # cant add single vert faces

        elif not face_vert_tex_indices or len_face_vert_loc_indices == 2:  # faces that have no texture coords are lines
            if use_edges:
                # generators are better in python 2.4+ but can't be used in 2.3
                # edges.extend( (face_vert_loc_indices[i], face_vert_loc_indices[i+1]) for i in xrange(len_face_vert_loc_indices-1) )
                edges.extend([(face_vert_loc_indices[i], face_vert_loc_indices[i + 1]) for i in range(len_face_vert_loc_indices - 1)])

            faces.pop(f_idx)
        else:

            # Smooth Group
            if unique_smooth_groups and context_smooth_group:
                # Is a part of of a smooth group and is a face
                if context_smooth_group_old is not context_smooth_group:
                    edge_dict = smooth_group_users[context_smooth_group]
                    context_smooth_group_old = context_smooth_group

                for i in range(len_face_vert_loc_indices):
                    i1 = face_vert_loc_indices[i]
                    i2 = face_vert_loc_indices[i - 1]
                    if i1 > i2:
                        i1, i2 = i2, i1

                    try:
                        edge_dict[i1, i2] += 1
                    except KeyError:
                        edge_dict[i1, i2] = 1

            # NGons into triangles
            if has_ngons and len_face_vert_loc_indices > 4:

                ngon_face_indices = ngon_tessellate(verts_loc, face_vert_loc_indices)
                faces.extend([([face_vert_loc_indices[ngon[0]],
                                face_vert_loc_indices[ngon[1]],
                                face_vert_loc_indices[ngon[2]],
                                ],
                               [face_vert_tex_indices[ngon[0]],
                                face_vert_tex_indices[ngon[1]],
                                face_vert_tex_indices[ngon[2]],
                                ],
                               context_material,
                               context_smooth_group,
                               context_object,
                              )
                             for ngon in ngon_face_indices]
                            )

                # edges to make ngons
                if use_ngons:
                    edge_users = {}
                    for ngon in ngon_face_indices:
                        for i in (0, 1, 2):
                            i1 = face_vert_loc_indices[ngon[i]]
                            i2 = face_vert_loc_indices[ngon[i - 1]]
                            if i1 > i2:
                                i1, i2 = i2, i1

                            try:
                                edge_users[i1, i2] += 1
                            except KeyError:
                                edge_users[i1, i2] = 1

                    for key, users in edge_users.items():
                        if users > 1:
                            fgon_edges.add(key)

                # remove all after 3, means we dont have to pop this one.
                faces.pop(f_idx)

    # Build sharp edges
    if unique_smooth_groups:
        for edge_dict in list(smooth_group_users.values()):
            for key, users in list(edge_dict.items()):
                if users == 1:  # This edge is on the boundry of a group
                    sharp_edges[key] = None

    # map the material names to an index
    material_mapping = {name: i for i, name in enumerate(unique_materials)}  # enumerate over unique_materials keys()

    materials = [None] * len(unique_materials)

    for name, index in list(material_mapping.items()):
        materials[index] = unique_materials[name]

    me = bpy.data.meshes.new(dataname.decode('utf-8', "replace"))

    # make sure the list isnt too big
    for material in materials:
        me.materials.append(material)

    me.vertices.add(len(verts_loc))
    me.tessfaces.add(len(faces))

    # verts_loc is a list of (x, y, z) tuples
    me.vertices.foreach_set("co", unpack_list(verts_loc))

    # faces is a list of (vert_indices, texco_indices, ...) tuples
    # XXX faces should contain either 3 or 4 verts
    # XXX no check for valid face indices
    me.tessfaces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces]))

    if verts_tex and me.tessfaces:
        me.tessface_uv_textures.new()

    context_material_old = -1  # avoid a dict lookup
    mat = 0  # rare case it may be un-initialized.
    me_faces = me.tessfaces

    for i, face in enumerate(faces):
        if len(face[0]) < 2:
            pass  # raise "bad face"
        elif len(face[0]) == 2:
            if use_edges:
                edges.append(face[0])
        else:

            blender_face = me.tessfaces[i]

            (face_vert_loc_indices,
             face_vert_tex_indices,
             context_material,
             context_smooth_group,
             context_object,
             ) = face

            if context_smooth_group:
                blender_face.use_smooth = True

            if context_material:
                if context_material_old is not context_material:
                    mat = material_mapping[context_material]
                    context_material_old = context_material

                blender_face.material_index = mat
#                blender_face.mat= mat

            if verts_tex:

                blender_tface = me.tessface_uv_textures[0].data[i]

                if context_material:
                    image = unique_material_images[context_material]
                    if image:  # Can be none if the material dosnt have an image.
                        blender_tface.image = image

                # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled.
                if len(face_vert_loc_indices) == 4:
                    if face_vert_loc_indices[2] == 0 or face_vert_loc_indices[3] == 0:
                        face_vert_tex_indices = face_vert_tex_indices[2], face_vert_tex_indices[3], face_vert_tex_indices[0], face_vert_tex_indices[1]
                else:  # length of 3
                    if face_vert_loc_indices[2] == 0:
                        face_vert_tex_indices = face_vert_tex_indices[1], face_vert_tex_indices[2], face_vert_tex_indices[0]
                # END EEEKADOODLE FIX

                # assign material, uv's and image
                blender_tface.uv1 = verts_tex[face_vert_tex_indices[0]]
                blender_tface.uv2 = verts_tex[face_vert_tex_indices[1]]
                blender_tface.uv3 = verts_tex[face_vert_tex_indices[2]]

                if len(face_vert_loc_indices) == 4:
                    blender_tface.uv4 = verts_tex[face_vert_tex_indices[3]]

#                for ii, uv in enumerate(blender_face.uv):
#                    uv.x, uv.y=  verts_tex[face_vert_tex_indices[ii]]
    del me_faces
#     del ALPHA

    if use_edges and not edges:
        use_edges = False

    if use_edges:
        me.edges.add(len(edges))

        # edges should be a list of (a, b) tuples
        me.edges.foreach_set("vertices", unpack_list(edges))
#         me_edges.extend( edges )

#     del me_edges

    # Add edge faces.
#     me_edges= me.edges

    def edges_match(e1, e2):
        return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])

    me.validate()
    me.update(calc_edges=use_edges)

    if unique_smooth_groups and sharp_edges:
        import bmesh
        bm = bmesh.new()
        bm.from_mesh(me)
        # to avoid slow iterator lookups later / indexing verts is slow in bmesh
        bm_verts = bm.verts[:]

        for sharp_edge in sharp_edges.keys():
            vert1 = bm_verts[sharp_edge[0]]
            vert2 = bm_verts[sharp_edge[1]]
            if vert1 != vert2:
                edge = bm.edges.get((vert1, vert2))
                if edge is not None:
                    me.edges[edge.index].use_edge_sharp = True

        bm.free()
        del bm

    mesh_untessellate(me, fgon_edges)

    # XXX slow
#     if unique_smooth_groups and sharp_edges:
#         for sharp_edge in sharp_edges.keys():
#             for ed in me.edges:
#                 if edges_match(sharp_edge, ed.vertices):
#                     ed.use_edge_sharp = True

#     if unique_smooth_groups and sharp_edges:
#         SHARP= Mesh.EdgeFlags.SHARP
#         for ed in me.findEdges( sharp_edges.keys() ):
#             if ed is not None:
#                 me_edges[ed].flag |= SHARP
#         del SHARP

    ob = bpy.data.objects.new(me.name, me)
    new_objects.append(ob)

    # Create the vertex groups. No need to have the flag passed here since we test for the
    # content of the vertex_groups. If the user selects to NOT have vertex groups saved then
    # the following test will never run
    for group_name, group_indices in vertex_groups.items():
        group = ob.vertex_groups.new(group_name.decode('utf-8', "replace"))
        group.add(group_indices, 1.0, 'REPLACE')
Beispiel #34
0
def import_mesh(filename):
	print("importing", filename)

	name = filename.split("/")[-1].split("\\")[-1].split(".")[0]
	file = open(filename)
	line = file.readline()
	if not line.startswith("# Inter-Quake Export"):
		raise Exception("Not an IQE file!")

	has_vc = has_vt = False

	faces = []
	mat, img = None, None
	for line in file.readlines():
		if "#" in line or "\"" in line:
			line = shlex.split(line, "#")
		else:
			line = line.split()
		if len(line) == 0: pass
		elif line[0] == "mesh": in_vp, in_vn, in_vt, in_vc = [], [], [], []
		elif line[0] == "material": mat, img = import_material(line[1])
		elif line[0] == "vp": in_vp.append((float(line[1]), float(line[2]), float(line[3])))
		elif line[0] == "vn": in_vn.append((float(line[1]), float(line[2]), float(line[3])))
		elif line[0] == "vt": has_vt = True; in_vt.append((float(line[1]), 1.0 - float(line[2])))
		elif line[0] == "vc": has_vc = True; in_vc.append((float(line[1]), float(line[2]), float(line[3])))
		elif line[0] == "fm":
			verts = []
			for f in [int(x) for x in line[1:]]:
				p, n = in_vp[f], in_vn[f]
				t = in_vt[f] if f < len(in_vt) else (0,0)
				c = in_vc[f] if f < len(in_vc) else (1,1,1)
				verts.insert(0, (p, n, t, c))
			faces.append((verts, mat, img))

	vertex_map = {}
	out_vp, out_vn, out_f, out_ft, out_fc, out_fm = [], [], [], [], [], []
	for verts, mat, img in faces:
		f, ft, fc = [], [], []
		for p, n, t, c in verts:
			if not (p,n) in vertex_map:
				vertex_map[(p,n)] = len(out_vp)
				out_vp.append(p)
				out_vn.append(n)
			f.append(vertex_map[p,n])
			ft.append(t)
			fc.append(c)
		f, ft, fc = reorder(f, ft, fc)
		if isdegenerate(f):
			print("degenerate face", f)
			continue
		out_f.append(f)
		out_ft.append(ft)
		out_fc.append(fc)
		out_fm.append((mat, img))

	mesh = bpy.data.meshes.new(name)
	obj = bpy.data.objects.new(name, mesh)
	grp = bpy.data.groups.new(name)
	grp.objects.link(obj)

	mesh.show_double_sided = False

	mesh.vertices.add(len(out_vp))
	mesh.vertices.foreach_set("co", unpack_list(out_vp))
	mesh.tessfaces.add(len(out_f))
	mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(out_f))

	if has_vt: uvlayer = mesh.tessface_uv_textures.new()
	if has_vc: vclayer = mesh.tessface_vertex_colors.new()
	for i, face in enumerate(mesh.tessfaces):
		mat, img = out_fm[i]
		if mat.name not in mesh.materials:
			mesh.materials.append(mat)
		face.material_index = mesh.materials.find(mat.name)
		face.use_smooth = True
		if has_vt:
			uvlayer.data[i].image = img
			uvlayer.data[i].uv1 = out_ft[i][0]
			uvlayer.data[i].uv2 = out_ft[i][1]
			uvlayer.data[i].uv3 = out_ft[i][2]
			uvlayer.data[i].uv4 = out_ft[i][3] if len(out_ft[i]) == 4 else (0,0)
		if has_vc:
			vclayer.data[i].color1 = out_fc[i][0]
			vclayer.data[i].color2 = out_fc[i][1]
			vclayer.data[i].color3 = out_fc[i][2]
			vclayer.data[i].color4 = out_fc[i][3] if len(out_fc[i]) == 4 else (1,1,1)

	for mat in mesh.materials:
		mat.use_vertex_color_paint = has_vc

	mesh.update()

	# Must set normals after mesh.update() or they will be recalculated
	mesh.vertices.foreach_set("normal", unpack_list(out_vn))

	bpy.context.scene.objects.link(obj)
	bpy.context.scene.objects.active = obj
    def create_blender_object(self, ac_matlist, str_pre, bLevelLinked):

        if self.type == 'world':
            self.name = self.import_config.ac_name
            self.rotation = self.import_config.global_matrix
        me = None
        if self.type == 'group':
            # Create an empty object
            self.bl_obj = bpy.data.objects.new(self.name, None)

        if self.type == 'poly':
            meshname = self.name
            if len(self.data) > 0:
                meshname = self.data
            me = bpy.data.meshes.new(meshname)
            self.bl_obj = bpy.data.objects.new(self.name, me)

        # setup parent object
        if self.ac_parent:
            self.bl_obj.parent = self.ac_parent.bl_obj

        # make sure we have something to work with
        if self.vert_list and me:

            me.use_auto_smooth = self.import_config.use_auto_smooth
            me.auto_smooth_angle = radians(self.crease)

            for surf in self.surf_list:
                surf_edges = surf.get_edges()
                surf_face = surf.get_faces()
                for edge in surf_edges:
                    self.edge_list.append(edge)

                if surf.flags.type == 0:
                    # test for invalid face (ie, >4 vertices)
                    if len(surf.refs) > 4 or len(surf.refs) < 3:
                        # not bringing in faces (assumed that there are none in a poly-line)
                        TRACE("Ignoring surface (vertex-count: {0})".format(
                            len(surf.refs)))
                    else:

                        self.face_list.append(surf_face)

                        # Material index is 1 based, the list we built is 0 based
                        ac_material = ac_matlist[surf.mat_index]
                        bl_material = ac_material.get_blender_material(
                            self.tex_name)

                        if bl_material == None:
                            TRACE("Error getting material {0} '{1}'".format(
                                surf.mat_index, self.tex_name))

                        fm_index = 0
                        if not bl_material.name in me.materials:
                            me.materials.append(bl_material)
                            fm_index = len(me.materials) - 1
                        else:
                            for mat in me.materials:
                                if mat == bl_material:
                                    continue
                                fm_index += 1
                            if fm_index > len(me.materials):
                                TRACE("Failed to find material index")
                                fm_index = 0
                        self.face_mat_list.append(fm_index)
                else:
                    # treating as a polyline (nothing more to do)
                    pass

            me.vertices.add(len(self.vert_list))
            me.tessfaces.add(len(self.face_list))

            # verts_loc is a list of (x, y, z) tuples
            me.vertices.foreach_set("co", unpack_list(self.vert_list))

            # faces is a list of (vert_indices, texco_indices, ...) tuples
            me.tessfaces.foreach_set("vertices_raw",
                                     unpack_face_list(self.face_list))

            #			face_mat = [m for m in self.face_mat_list]
            #			me.tessfaces.foreach_set("material_index", face_mat)
            #			del face_mat

            if len(self.tex_name):
                me.tessface_uv_textures.new()
#				uv_tex.active = True
#				uv_tex.active_render = True
            else:
                uv_tex = None

            two_sided_lighting = False

            for i, face in enumerate(self.face_list):
                blender_face = me.tessfaces[i]
                surf = self.surf_list[i]

                blender_face.use_smooth = surf.flags.shaded

                # If one surface is twosided, they all will be...
                two_sided_lighting |= surf.flags.two_sided

                if len(self.tex_name) and len(surf.uv_refs) >= 3:
                    blender_tface = me.tessface_uv_textures[0].data[i]

                    blender_tface.uv1 = surf.uv_refs[0]
                    blender_tface.uv2 = surf.uv_refs[1]
                    blender_tface.uv3 = surf.uv_refs[2]

                    if len(surf.uv_refs) > 3:
                        blender_tface.uv4 = surf.uv_refs[3]

                    surf_material = me.materials[self.face_mat_list[i]]
                    blender_tface.image = surf_material.texture_slots[
                        0].texture.image

#						uv_tex.data[f_index].use_image = True

            me.show_double_sided = two_sided_lighting

            self.bl_obj.show_transparent = self.import_config.display_transparency

        if self.bl_obj:
            self.bl_obj.rotation_euler = self.rotation.to_euler()

            self.bl_obj.location = self.location

            self.import_config.context.scene.objects.link(self.bl_obj)
            # There's a bug somewhere - this ought to work....
            self.import_config.context.scene.objects.active = self.bl_obj


#			bpy.ops.object.origin_set('ORIGIN_GEOMETRY', 'MEDIAN')

        TRACE("{0}+-{1} ({2})".format(str_pre, self.name, self.data))

        # Add any children
        str_pre_new = ""
        bUseLink = True
        for obj in self.children:
            if bLevelLinked:
                str_pre_new = str_pre + "| "
            else:
                str_pre_new = str_pre + "  "

            if self.children.index(obj) == len(self.children) - 1:
                bUseLink = False

            obj.create_blender_object(ac_matlist, str_pre_new, bUseLink)

        if me:
            #			me.calc_normals()
            me.validate()
            me.update(calc_edges=True)
Beispiel #36
0
    def write_mesh_data(self, entities, name, default_material='Material'):
        verts = []
        faces = []
        mat_index = []
        mats = keep_offset()
        seen = keep_offset()
        uv_list = []
        alpha = False # We assume object does not need alpha flag
        uvs_used = False # We assume no uvs need to be added


        for f in entities.faces:
            vs, tri, uvs = f.tessfaces

            if f.material:
                mat_number = mats[f.material.name]
            else:
                mat_number = mats[default_material]


            mapping = {}
            for i, (v, uv) in enumerate(zip(vs, uvs)):
                l = len(seen)
                mapping[i] = seen[v]
                if len(seen) > l:
                    verts.append(v)
                uvs.append(uv)


            for face in tri:
                f0, f1, f2 = face[0], face[1], face[2]
                if f2 == 0: ## eeekadoodle dance
                    faces.append( ( mapping[f1], mapping[f2], mapping[f0] ) )
                    uv_list.append(( uvs[f2][0], uvs[f2][1],
                                     uvs[f1][0], uvs[f1][1],
                                     uvs[f0][0], uvs[f0][1],
                                     0, 0 ) )
                else:
                    faces.append( ( mapping[f0], mapping[f1], mapping[f2] ) )
                    uv_list.append(( uvs[f0][0], uvs[f0][1],
                                     uvs[f1][0], uvs[f1][1],
                                     uvs[f2][0], uvs[f2][1],
                                     0, 0 ) )
                mat_index.append(mat_number)

        # verts, faces, uv_list, mat_index, mats = entities.get__triangles_lists(default_material)

        if len(verts) == 0:
            return None, False

        me = bpy.data.meshes.new(name)

        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))

        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                bmat = self.materials[k]
                me.materials.append(bmat)
                if bmat.alpha < 1.0:
                    alpha = True
                try:
                    if 'Image Texture' in bmat.node_tree.nodes.keys():
                        uvs_used = True
                except AttributeError as e:
                    uvs_used = False
        else:
            sketchupLog("WARNING OBJECT {} HAS NO MATERIAL".format(name))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)

        if uvs_used:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uv_list[i]

        me.update(calc_edges=True)
        me.validate()
        return me, alpha
Beispiel #37
0
def make_mesh(model, name, meshes, amtobj):
    print("importing mesh", name, "with", len(meshes), "parts")

    mesh = bpy.data.meshes.new(name)
    obj = bpy.data.objects.new(name, mesh)
    bpy.context.scene.objects.link(obj)
    bpy.context.scene.objects.active = obj

    # Set the mesh to single-sided to spot normal errors
    mesh.show_double_sided = False

    # Flip winding
    for m in meshes:
        m.faces = [x[::-1] for x in m.faces]

    # Positions, normals, blends and vertex groups go to vertices.
    # Material, texture coords and vertex colors go to faces.

    weld = {}
    out_vp, out_vn, out_vb, out_vg = [], [], [], []
    out_f, out_f_mat, out_f_img, out_ft, out_fc = [], [], [], [], []

    for m in meshes:
        material, image = make_material(m.material)
        if material.name not in mesh.materials:
            mesh.materials.append(material)
        material_index = mesh.materials.find(material.name)

        out_from_in = []

        vg, vg_names = gather_vg(model.vertexarrays, m)

        for i, p in enumerate(m.positions):
            n = m.normals[i] if len(m.normals) > i else (0, 0, 1)
            b = m.blends[i] if len(m.blends) > i else None
            g = tuple([g[i][0] for g in vg]) if len(vg) > 0 else None
            key = p, n, b, g
            if not key in weld:
                weld[key] = len(out_vp)
                out_vp.append(p)
                out_vn.append(n)
                out_vb.append(b)
                out_vg.append(g)
            out_from_in.append(weld[key])

        vt, vt_names = gather_vt(model.vertexarrays, m)
        vc, vc_names = gather_vc(model.vertexarrays, m)

        print("texcoords:", vt_names)
        print("colors:", vc_names)
        print("groups:", vg_names)

        for face in m.faces:
            f = [out_from_in[v] for v in face]
            ft = [[t[v] for t in vt] for v in face]
            fc = [[c[v] for c in vc] for v in face]
            f, ft, fc = reorder(f, ft, fc)
            if isdegenerate(f):
                print("degenerate face", f)
                continue

            out_f.append(f)
            out_ft.append(ft)
            out_fc.append(fc)
            out_f_mat.append(material_index)
            out_f_img.append(image)

    print("\tcollected %d vertices and %d faces" % (len(out_vp), len(out_f)))

    # Create mesh vertex and face data

    mesh.vertices.add(len(out_vp))
    mesh.vertices.foreach_set("co", unpack_list(out_vp))

    mesh.tessfaces.add(len(out_f))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(out_f))

    for i, face in enumerate(mesh.tessfaces):
        face.use_smooth = True
        face.material_index = out_f_mat[i]

    for k, name in enumerate(vt_names):
        layer = mesh.tessface_uv_textures.new(name)
        for i, face in enumerate(mesh.tessfaces):
            data = layer.data[i]
            ft = out_ft[i]
            data.image = out_f_img[i]
            data.uv1 = (ft[0][k][0], 1 - ft[0][k][1])
            data.uv2 = (ft[1][k][0], 1 - ft[1][k][1])
            data.uv3 = (ft[2][k][0], 1 - ft[2][k][1])
            if len(ft) > 3:
                data.uv4 = (ft[3][k][0], 1 - ft[3][k][1])

    for k, name in enumerate(vc_names):
        layer = mesh.tessface_vertex_colors.new(name)
        for i, face in enumerate(mesh.tessfaces):
            data = layer.data[i]
            data.color1 = tuple(out_fc[i][0][k][:3])
            data.color2 = tuple(out_fc[i][1][k][:3])
            data.color3 = tuple(out_fc[i][2][k][:3])
            if len(out_fc[i]) > 3:
                data.color4 = tuple(out_fc[i][3][k][:3])

    # Non-skinning vertex groups

    for k, name in enumerate(vg_names):
        vgroup = obj.vertex_groups.new(name)
        for i, g in enumerate(out_vg):
            vgroup.add([i], g[k], 'REPLACE')

    # Vertex groups and armature modifier for skinning

    if amtobj:
        for iqbone in model.bones:
            obj.vertex_groups.new(iqbone[0])

        for vgroup in obj.vertex_groups:
            for i, b in enumerate(out_vb):
                idx, wgt = b[0]
                if idx == vgroup.index:
                    vgroup.add([i], wgt, 'REPLACE')

        mod = obj.modifiers.new("Armature", 'ARMATURE')
        mod.object = amtobj
        mod.use_vertex_groups = True

    # Update mesh polygons from tessfaces

    mesh.update()

    # Must set normals after mesh.update() or they will be recalculated.
    mesh.vertices.foreach_set("normal", unpack_list(out_vn))

    return obj
Beispiel #38
0
def load_ply_mesh(filepath, ply_name):
    from bpy_extras.io_utils import unpack_face_list
    # from bpy_extras.image_utils import load_image  # UNUSED

    obj_spec, obj, texture = read(filepath)
    if obj is None:
        print('Invalid file')
        return

    uvindices = colindices = None
    colmultiply = None

    # noindices = None # Ignore normals

    for el in obj_spec.specs:
        if el.name == b'vertex':
            vindices_x, vindices_y, vindices_z = el.index(b'x'), el.index(b'y'), el.index(b'z')
            # noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
            # if -1 in noindices: noindices = None
            uvindices = (el.index(b's'), el.index(b't'))
            if -1 in uvindices:
                uvindices = None
            colindices = el.index(b'red'), el.index(b'green'), el.index(b'blue')
            if -1 in colindices:
                colindices = None
            else:  # if not a float assume uchar
                colmultiply = [1.0 if el.properties[i].numeric_type in {'f', 'd'} else (1.0 / 256.0) for i in colindices]

        elif el.name == b'face':
            findex = el.index(b'vertex_indices')

    mesh_faces = []
    mesh_uvs = []
    mesh_colors = []

    def add_face(vertices, indices, uvindices, colindices):
        mesh_faces.append(indices)
        if uvindices:
            mesh_uvs.append([(vertices[index][uvindices[0]], vertices[index][uvindices[1]]) for index in indices])
        if colindices:
            mesh_colors.append([(vertices[index][colindices[0]] * colmultiply[0],
                                 vertices[index][colindices[1]] * colmultiply[1],
                                 vertices[index][colindices[2]] * colmultiply[2],
                                 ) for index in indices])

    if uvindices or colindices:
        # If we have Cols or UVs then we need to check the face order.
        add_face_simple = add_face

        # EVIL EEKADOODLE - face order annoyance.
        def add_face(vertices, indices, uvindices, colindices):
            if len(indices) == 4:
                if indices[2] == 0 or indices[3] == 0:
                    indices = indices[2], indices[3], indices[0], indices[1]
            elif len(indices) == 3:
                if indices[2] == 0:
                    indices = indices[1], indices[2], indices[0]

            add_face_simple(vertices, indices, uvindices, colindices)

    verts = obj[b'vertex']

    if b'face' in obj:
        for f in obj[b'face']:
            ind = f[findex]
            len_ind = len(ind)
            if len_ind <= 4:
                add_face(verts, ind, uvindices, colindices)
            else:
                # Fan fill the face
                for j in range(len_ind - 2):
                    add_face(verts, (ind[0], ind[j + 1], ind[j + 2]), uvindices, colindices)

    mesh = bpy.data.meshes.new(name=ply_name)

    mesh.vertices.add(len(obj[b'vertex']))

    mesh.vertices.foreach_set("co", [a for v in obj[b'vertex'] for a in (v[vindices_x], v[vindices_y], v[vindices_z])])

    if mesh_faces:
        mesh.tessfaces.add(len(mesh_faces))
        mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(mesh_faces))

        if uvindices or colindices:
            if uvindices:
                uvlay = mesh.tessface_uv_textures.new()
            if colindices:
                vcol_lay = mesh.tessface_vertex_colors.new()

            if uvindices:
                for i, f in enumerate(uvlay.data):
                    ply_uv = mesh_uvs[i]
                    for j, uv in enumerate(f.uv):
                        uv[0], uv[1] = ply_uv[j]

            if colindices:
                for i, f in enumerate(vcol_lay.data):
                    # XXX, colors dont come in right, needs further investigation.
                    ply_col = mesh_colors[i]
                    if len(ply_col) == 4:
                        f_col = f.color1, f.color2, f.color3, f.color4
                    else:
                        f_col = f.color1, f.color2, f.color3

                    for j, col in enumerate(f_col):
                        col.r, col.g, col.b = ply_col[j]

    mesh.validate()
    mesh.update()

    if texture and uvindices:

        import os
        import sys
        from bpy_extras.image_utils import load_image

        encoding = sys.getfilesystemencoding()
        encoded_texture = texture.decode(encoding=encoding)
        name = bpy.path.display_name_from_filepath(texture)
        image = load_image(encoded_texture, os.path.dirname(filepath), recursive=True, place_holder=True)

        if image:
            texture = bpy.data.textures.new(name=name, type='IMAGE')
            texture.image = image

            material = bpy.data.materials.new(name=name)
            material.use_shadeless = True

            mtex = material.texture_slots.add()
            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_color_diffuse = True

            mesh.materials.append(material)
            for face in mesh.uv_textures[0].data:
                face.image = image

    return mesh
    def write_mesh_data(self, obj, name):
        '''
            Convert maxwell object into blender mesh datablock
            precond: check that obj != null and that it is actually a mesh
        '''
        uv_layer_count = obj.getNumChannelsUVW()
        verts = []
        faces = []
        normals = []
        vert_norm = {}
        mats = {}
        mat_index = []
        uvs = []
        max_vertex = 0
        max_normal = 0
        for i in range(obj.getNumTriangles()):
            triangle = obj.getTriangle(i)
            (v1, v2, v3, n1, n2, n3) = triangle
            max_vertex = max(max_vertex, v1, v2, v3)
            max_normal = max(max_normal, n1, n2, n3)
            mat = obj.getTriangleMaterial(i)
            if not mat.isNull():
              mat_name = mat.name
              if not mat_name in mats:
                mats[mat_name] = len(mats)
              mat_index.append(mats[mat_name])
            else:
              mat_index.append(0)
            if v3 == 0: # eeekadoodle dance
                faces.append((v2, v3, v1))
                zero_face_start = True
            else:
                faces.append((v1, v2, v3))
                zero_face_start = False
            vert_norm[v1] = n1
            vert_norm[v2] = n2
            vert_norm[v3] = n3
            if uv_layer_count > 0:
              u1, v1, w1, u2, v2, w2, u3, v3, w3 = obj.getTriangleUVW(i, 0)
              if not zero_face_start:
                  uvs.append(( u1, -1.0 * v1,
                               u2, -1.0 * v2,
                               u3, -1.0 * v3, 0.0, 0.0 ))
              else:
                  uvs.append((
                               u2, -1.0 * v2,
                               u3, -1.0 * v3, u1, -1.0 * v1, 0.0, 0.0 ))

            else:
                uvs.append((0.0, 0.0, 0.0, 0.0, 0.0 ,0.0 ,0.0, 0.0))

        for i in range(max_vertex + 1):
            vert = obj.getVertex(i, 0)
            verts.append((vert.x, vert.y, vert.z))
        for i in range(max_vertex + 1):
            n = obj.getNormal(vert_norm[i],0)
            normals.append((n.x, n.y, n.z))

        me = bpy.data.meshes.new(name)
        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))
        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                me.materials.append(self.materials[k])
        else:
            MaxwellLog("WARNING OBJECT {} HAS NO MATERIAL".format(obj.getName()))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.vertices.foreach_set("normal",  unpack_list(normals))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)
        if len(uvs) > 0:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uvs[i]

        me.update(calc_edges=True)    # Update mesh with new data
        me.validate()
        return me, len(verts)
Beispiel #40
0
    def write_mesh_data(self, obj, name):
        '''
            Convert maxwell object into blender mesh datablock
            precond: check that obj != null and that it is actually a mesh
        '''
        uv_layer_count = obj.getNumChannelsUVW()
        verts = []
        faces = []
        normals = []
        vert_norm = {}
        mats = {}
        mat_index = []
        uvs = []
        max_vertex = 0
        max_normal = 0
        for i in range(obj.getNumTriangles()):
            triangle = obj.getTriangle(i)
            (v1, v2, v3, n1, n2, n3) = triangle
            max_vertex = max(max_vertex, v1, v2, v3)
            max_normal = max(max_normal, n1, n2, n3)
            mat = obj.getTriangleMaterial(i)
            if not mat.isNull():
                mat_name = mat.name
                if not mat_name in mats:
                    mats[mat_name] = len(mats)
                mat_index.append(mats[mat_name])
            else:
                mat_index.append(0)
            if v3 == 0:  # eeekadoodle dance
                faces.append((v2, v3, v1))
                zero_face_start = True
            else:
                faces.append((v1, v2, v3))
                zero_face_start = False
            vert_norm[v1] = n1
            vert_norm[v2] = n2
            vert_norm[v3] = n3
            if uv_layer_count > 0:
                u1, v1, w1, u2, v2, w2, u3, v3, w3 = obj.getTriangleUVW(i, 0)
                if not zero_face_start:
                    uvs.append((u1, -1.0 * v1, u2, -1.0 * v2, u3, -1.0 * v3,
                                0.0, 0.0))
                else:
                    uvs.append((u2, -1.0 * v2, u3, -1.0 * v3, u1, -1.0 * v1,
                                0.0, 0.0))

            else:
                uvs.append((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))

        for i in range(max_vertex + 1):
            vert = obj.getVertex(i, 0)
            verts.append((vert.x, vert.y, vert.z))
        for i in range(max_vertex + 1):
            n = obj.getNormal(vert_norm[i], 0)
            normals.append((n.x, n.y, n.z))

        me = bpy.data.meshes.new(name)
        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))
        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                me.materials.append(self.materials[k])
        else:
            MaxwellLog("WARNING OBJECT {} HAS NO MATERIAL".format(
                obj.getName()))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.vertices.foreach_set("normal", unpack_list(normals))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)
        if len(uvs) > 0:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uvs[i]

        me.update(calc_edges=True)  # Update mesh with new data
        me.validate()
        return me, len(verts)
Beispiel #41
0
def create_mesh(sobj, use_smooth_groups, fore_is_y, import_textures):
    """Takes a submodel and adds a Blender mesh."""
    m = sobj.get_mesh()
    
    if fore_is_y:
        m.flip_yz()

    me = bpy.data.meshes.new("{}-mesh".format(sobj.name.decode()))

    vert_list = m.verts
    face_list = m.faces
    me.vertices.add(len(vert_list))
    me.vertices.foreach_set('co', unpack_list(vert_list))
    me.tessfaces.add(len(face_list))
    me.tessfaces.foreach_set('vertices_raw', unpack_face_list(face_list))

    invisible_faces = 0

    if import_textures:
        m.flip_v()
        uvtex = me.tessface_uv_textures.new()
        uvtex.name = me.name
        for n, tf in enumerate(m.uv):
            uv_data = uvtex.data[n]
            uv_data.uv1 = tf[0]
            uv_data.uv2 = tf[1]
            uv_data.uv3 = tf[2]
            if len(tf) == 4:
                uv_data.uv4 = tf[3]
            if m.tex_ids[n] is not None:
                tex_slot = import_textures[m.tex_ids[n]].texture_slots[0]
            else:
                tex_slot = None
            if tex_slot is not None:
                uv_data.image = tex_slot.texture.image
            else:
                invisible_faces += 1
        for mat in import_textures:
            me.materials.append(mat)
        for i, f in enumerate(me.tessfaces):
            if m.tex_ids[n] is not None:
                f.material_index = m.tex_ids[i]
        uvtex.active = True
        uvtex.active_render = True

    # index edges in a dict by a frozenset of the vert coords
    # that way we don't have to worry about messed up indicies when
    # adding the seams for smoothgroups (an edge might be [v1, v2] or [v2, v1])
    me.update(calc_edges=True)
    if use_smooth_groups:
        m.calc_sharp()
        for e in me.edges:
            v1 = tuple(me.vertices[e.vertices[0]].co)
            v2 = tuple(me.vertices[e.vertices[1]].co)
            this_edge = (v1, v2)
            this_edge = frozenset(this_edge)
            e.use_edge_sharp = m.edges[this_edge]
        for f in me.polygons:
            f.use_smooth = True

    bobj = bpy.data.objects.new("Mesh", me)
    bobj['POF model id'] = sobj.model_id
    bobj.name = sobj.name.decode()
    if use_smooth_groups:
        bobj.modifiers.new("POF smoothing", "EDGE_SPLIT")
    if invisible_faces > 2 * (len(me.polygons) / 3):
        bobj.draw_type = 'WIRE'
        
    return bobj
Beispiel #42
0
	def makeObject(self):
		print("Creating mesh", end='')
		# Create the mesh
		mesh = bpy.data.meshes.new(self.name)

		# Prepare vertices and faces
		mesh.vertices.add(self.numVerts)
		mesh.tessfaces.add(self.numTris)
		print('.', end='')

		# Verts
		mesh.vertices.foreach_set("co", unpack_list(self.frames[0]))
		mesh.transform(Matrix.Rotation(-pi / 2, 4, 'Z'))
		print('.', end='')

		# Tris
		mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list([face[0] for face in self.tris]))
		print('.', end='')

		# Skins
		mesh.tessface_uv_textures.new()
		if self.numSkins > 0:
			material = bpy.data.materials.new(self.name)
			for skin in self.skins:
				skinImg = Util.loadImage(skin, self.filePath)
				if skinImg == None:
					skinImg = bpy.data.images.new(os.path.join(self.filePath, skin), self.skinWidth, self.skinHeight)
				skinImg.mapping = 'UV'
				skinImg.name = skin
				skinTex = bpy.data.textures.new(self.name + skin, type='IMAGE')
				skinTex.image = skinImg
				matTex = material.texture_slots.add()
				matTex.texture = skinTex
				matTex.texture_coords = 'UV'
				matTex.use_map_color_diffuse = True
				matTex.use_map_alpha = True
				matTex.uv_layer = mesh.tessface_uv_textures[0].name
			mesh.materials.append(material)
		print('.', end='')

		# UV
		mesh.tessface_uv_textures[0].data.foreach_set("uv_raw", unpack_list([self.uvs[i] for i in unpack_face_list([face[1] for face in self.tris])]))
		if self.numSkins > 0:
			image = mesh.materials[0].texture_slots[0].texture.image
			if image != None:
				for uv in mesh.tessface_uv_textures[0].data:
					uv.image = image
		print('.', end='')

		mesh.validate()
		mesh.update()
		obj = bpy.data.objects.new(mesh.name, mesh)
		base = bpy.context.scene.objects.link(obj)
		bpy.context.scene.objects.active = obj
		base.select = True
		print("Done")

		# Animate
		if self.options.fImportAnimation and self.numFrames > 1:
			for i, frame in enumerate(self.frames):
				progressStatus = i / self.numFrames * 100
				#bpy.context.scene.frame_set(i + 1)
				obj.shape_key_add(from_mix=False)
				mesh.vertices.foreach_set("co", unpack_list(frame))
				mesh.transform(Matrix.Rotation(-pi / 2, 4, 'Z'))
				mesh.shape_keys.key_blocks[i].value = 1.0
				mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame=i + 1)
				if i < len(self.frames) - 1:
					mesh.shape_keys.key_blocks[i].value = 0.0
					mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame=i + 2)
				if i > 0:
					mesh.shape_keys.key_blocks[i].value = 0.0
					mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame=i)
				print("Animating - progress: %3i%%\r" % int(progressStatus), end='')
			print("Animating - progress: 100%.")

		bpy.context.scene.update()
		print("Model imported")
    def write_mesh_data(self,
                        entities=None,
                        name="",
                        default_material='Material'):
        mesh_key = (name, default_material)
        if mesh_key in self.component_meshes:
            return self.component_meshes[mesh_key]
        verts = []
        faces = []
        mat_index = []
        mats = keep_offset()
        seen = keep_offset()
        uv_list = []
        alpha = False  # We assume object does not need alpha flag
        uvs_used = False  # We assume no uvs need to be added

        for f in entities.faces:

            if f.material:
                mat_number = mats[f.material.name]
            else:
                mat_number = mats[default_material]
                if default_material != 'Material':
                    f.st_scale = self.materials_scales[default_material]

            vs, tri, uvs = f.tessfaces

            mapping = {}
            for i, (v, uv) in enumerate(zip(vs, uvs)):
                l = len(seen)
                mapping[i] = seen[v]
                if len(seen) > l:
                    verts.append(v)
                uvs.append(uv)

            for face in tri:
                f0, f1, f2 = face[0], face[1], face[2]
                if mapping[f2] == 0:  ## eeekadoodle dance
                    faces.append((mapping[f2], mapping[f0], mapping[f1]))
                    uv_list.append((uvs[f2][0], uvs[f2][1], uvs[f0][0],
                                    uvs[f0][1], uvs[f1][0], uvs[f1][1], 0, 0))
                else:
                    faces.append((mapping[f0], mapping[f1], mapping[f2]))
                    uv_list.append((uvs[f0][0], uvs[f0][1], uvs[f1][0],
                                    uvs[f1][1], uvs[f2][0], uvs[f2][1], 0, 0))
                mat_index.append(mat_number)

        # verts, faces, uv_list, mat_index, mats = entities.get__triangles_lists(default_material)

        if len(verts) == 0:
            return None, False

        me = bpy.data.meshes.new(name)

        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))

        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                bmat = self.materials[k]
                me.materials.append(bmat)
                if bmat.alpha < 1.0:
                    alpha = True
                try:
                    if 'Image Texture' in bmat.node_tree.nodes.keys():
                        uvs_used = True
                except AttributeError as e:
                    uvs_used = False
        else:
            sketchupLog("WARNING OBJECT {} HAS NO MATERIAL".format(name))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)

        if uvs_used:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uv_list[i]

        me.update(calc_edges=True)
        me.validate()
        self.component_meshes[mesh_key] = me, alpha
        return me, alpha
Beispiel #44
0
def build_model2(mod, **kwargs):

    default_materials()

    oname = mod.filename.replace('.mesh', '.000')
    mname = oname + '.' + 'mesh'

    ps = mod.pset.ps
    us = mod.uset.ps

    mats = ['generic', 'concrete1', 'grass2']
    fs_lookup = {}
    for fmx in range(len(mats)):
        fs_lookup[mats[fmx]] = fmx

    for gfx in mod.gfxmeshes:
        faces = [f for f in gfx.faces if not f is None]
        face_mats = [fs_lookup[gfx.fs_mats[f][1]] for f in faces]
        oloc = (0, 0, 0)

        #mesh = mesh_from_data(mname,ps,us,faces,face_mats,mats)
        #def mesh_from_data(name,ps,us,faces,face_mats,mats):

        mesh = bpy.data.meshes.new(mname)
        if not mats is None:
            [mesh.materials.append(materials[ma]) for ma in mats]
        mesh.vertices.add(len(ps))
        mesh.vertices.foreach_set('co', unpack_list(ps))
        mesh.tessfaces.add(len(faces))
        mesh.tessfaces.foreach_set('vertices_raw', unpack_face_list(faces))
        mesh.tessfaces.foreach_set('material_index', face_mats)
        mesh.tessface_uv_textures.new()
        for fdx in range(len(faces)):
            fa = faces[fdx]
            mesh.tessface_uv_textures[0].data[fdx].uv1 = tuple(us[fa[0]])[:-1]
            mesh.tessface_uv_textures[0].data[fdx].uv2 = tuple(us[fa[1]])[:-1]
            mesh.tessface_uv_textures[0].data[fdx].uv3 = tuple(us[fa[2]])[:-1]
        mesh.update()




    '''#
    faces = mod.gfxmeshes[0].faces
    face_mats = [fs_lookup[mod.gfxmeshes[0].fs_mats[f]] for f in faces]
    #face_mats = [0]*len(faces)
    #mats = ['generic']
    oloc = (0,0,0)

    #mesh = mesh_from_data(mname,ps,us,faces,face_mats,mats)
    #def mesh_from_data(name,ps,us,faces,face_mats,mats):

    mesh = bpy.data.meshes.new(mname)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(ps))
    mesh.vertices.foreach_set('co',unpack_list(ps))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index',face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = tuple(us[fa[0]])[:-1]
        mesh.tessface_uv_textures[0].data[fdx].uv2 = tuple(us[fa[1]])[:-1]
        mesh.tessface_uv_textures[0].data[fdx].uv3 = tuple(us[fa[2]])[:-1]
    mesh.update()
    '''#

    obj = object_from_mesh(oname, mesh, oloc, mats)
    object_to_scene(obj)
    return obj
def read_mesh(data):
  read_bounds(data)

  n_surfaces, = struct.unpack("<L",data.read(4))
  print ("found ",n_surfaces," surfaces")

  surface_names = []
  for i in range(n_surfaces):
    surface_name = read_string(data)
    surface_names.append(surface_name)
    print ("surface_name ",surface_name)
    read_bounds(data)

  for j in range(n_surfaces):
    n_vertices, = struct.unpack("<L",data.read(4))
    verts = []
    norms = []
    print(n_vertices," vertices")
    for i in range(n_vertices):
      x,y,z = struct.unpack("<fff",data.read(12))
      nx,ny,nz = struct.unpack("<hhh",data.read(6))
      verts.append((x,y,z))
      norms.append((float(nx)/33268.0,float(ny)/33268.0,float(nz)/33268.0))
    #print ("verts: ",verts)
    n_uvcoords0, = struct.unpack("<L",data.read(4))
    uvs0 = []
    for i in range(n_uvcoords0):
      (u,v) = struct.unpack("<ff",data.read(8))
      uvs0.append((u,v))
    n_uvcoords1, = struct.unpack("<L",data.read(4))
    uvs1 = []
    for i in range(n_uvcoords1):
      (u,v) = struct.unpack("<ff",data.read(8))
      uvs1.append((u,v))
    n_triangles, = struct.unpack("<L",data.read(4))
    faces = []
    if(n_vertices < 66536):
      for i in range(n_triangles):
        v0,v1,v2 = struct.unpack("<HHH",data.read(6))
        faces.append((v0,v1,v2))
    else:
      for i in range(n_triangles):
        v0,v1,v2  = struct.unpack("<LLL",data.read(12))
        faces.append((v0,v1,v2))
    surface_name = surface_names[j]
    me = bpy.data.meshes.new(surface_name)
    ob = bpy.data.objects.new(surface_name,me)
    bpy.context.scene.objects.link(ob)
    me.vertices.add(len(verts))
    me.vertices.foreach_set("co",unpack_list(verts))
    me.faces.add(len(faces))
    me.faces.foreach_set("vertices_raw",unpack_face_list(faces))

    for i in range(n_vertices):
      me.vertices[i].normal = norms[i]

    me.validate()
    me.update(calc_edges=True)

    if n_uvcoords0 > 0:
      b_uvs0 = me.uv_textures.new()
      for i in range(len(faces)):
        (v0,v1,v2) = faces[i]
        b_uvface = b_uvs0.data[i]
        b_uvface.uv1 = uvs0[v0]
        b_uvface.uv2 = uvs0[v1]
        b_uvface.uv3 = uvs0[v2]
    if n_uvcoords1 > 0:
      b_uvs1 = me.uv_textures.new()
      for i in range(len(faces)):
        (v0,v1,v2) = faces[i]
        b_uvface = b_uvs1.data[i]
        b_uvface.uv1 = uvs1[v0]
        b_uvface.uv2 = uvs1[v1]
        b_uvface.uv3 = uvs1[v2]
def load_ply_mesh(filepath, ply_name):
    from bpy_extras.io_utils import unpack_face_list
    # from bpy_extras.image_utils import load_image  # UNUSED

    obj_spec, obj, texture = read(filepath)
    if obj is None:
        print('Invalid file')
        return

    uvindices = colindices = None
    colmultiply = None

    # noindices = None # Ignore normals

    for el in obj_spec.specs:
        if el.name == b'vertex':
            vindices_x, vindices_y, vindices_z = el.index(b'x'), el.index(
                b'y'), el.index(b'z')
            # noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
            # if -1 in noindices: noindices = None
            uvindices = (el.index(b's'), el.index(b't'))
            if -1 in uvindices:
                uvindices = None
            colindices = el.index(b'red'), el.index(b'green'), el.index(
                b'blue')
            if -1 in colindices:
                colindices = None
            else:  # if not a float assume uchar
                colmultiply = [
                    1.0 if el.properties[i].numeric_type in {'f', 'd'} else
                    (1.0 / 255.0) for i in colindices
                ]

        elif el.name == b'face':
            findex = el.index(b'vertex_indices')
        elif el.name == b'tristrips':
            trindex = el.index(b'vertex_indices')
        elif el.name == b'edge':
            eindex1, eindex2 = el.index(b'vertex1'), el.index(b'vertex2')

    mesh_faces = []
    mesh_uvs = []
    mesh_colors = []

    def add_face(vertices, indices, uvindices, colindices):
        mesh_faces.append(indices)
        if uvindices:
            mesh_uvs.append([(vertices[index][uvindices[0]],
                              vertices[index][uvindices[1]])
                             for index in indices])
        if colindices:
            mesh_colors.append([(
                vertices[index][colindices[0]] * colmultiply[0],
                vertices[index][colindices[1]] * colmultiply[1],
                vertices[index][colindices[2]] * colmultiply[2],
            ) for index in indices])

    if uvindices or colindices:
        # If we have Cols or UVs then we need to check the face order.
        add_face_simple = add_face

        # EVIL EEKADOODLE - face order annoyance.
        def add_face(vertices, indices, uvindices, colindices):
            if len(indices) == 4:
                if indices[2] == 0 or indices[3] == 0:
                    indices = indices[2], indices[3], indices[0], indices[1]
            elif len(indices) == 3:
                if indices[2] == 0:
                    indices = indices[1], indices[2], indices[0]

            add_face_simple(vertices, indices, uvindices, colindices)

    verts = obj[b'vertex']

    if b'face' in obj:
        for f in obj[b'face']:
            ind = f[findex]
            len_ind = len(ind)
            if len_ind <= 4:
                add_face(verts, ind, uvindices, colindices)
            else:
                # Fan fill the face
                for j in range(len_ind - 2):
                    add_face(verts, (ind[0], ind[j + 1], ind[j + 2]),
                             uvindices, colindices)

    if b'tristrips' in obj:
        for t in obj[b'tristrips']:
            ind = t[trindex]
            len_ind = len(ind)
            for j in range(len_ind - 2):
                add_face(verts, (ind[j], ind[j + 1], ind[j + 2]), uvindices,
                         colindices)

    mesh = bpy.data.meshes.new(name=ply_name)

    mesh.vertices.add(len(obj[b'vertex']))

    mesh.vertices.foreach_set("co", [
        a for v in obj[b'vertex']
        for a in (v[vindices_x], v[vindices_y], v[vindices_z])
    ])

    if b'edge' in obj:
        mesh.edges.add(len(obj[b'edge']))
        mesh.edges.foreach_set(
            "vertices",
            [a for e in obj[b'edge'] for a in (e[eindex1], e[eindex2])])

    if mesh_faces:
        mesh.tessfaces.add(len(mesh_faces))
        mesh.tessfaces.foreach_set("vertices_raw",
                                   unpack_face_list(mesh_faces))

        if uvindices or colindices:
            if uvindices:
                uvlay = mesh.tessface_uv_textures.new()
            if colindices:
                vcol_lay = mesh.tessface_vertex_colors.new()

            if uvindices:
                for i, f in enumerate(uvlay.data):
                    ply_uv = mesh_uvs[i]
                    for j, uv in enumerate(f.uv):
                        uv[0], uv[1] = ply_uv[j]

            if colindices:
                for i, f in enumerate(vcol_lay.data):
                    # XXX, colors dont come in right, needs further investigation.
                    ply_col = mesh_colors[i]
                    if len(ply_col) == 4:
                        f_col = f.color1, f.color2, f.color3, f.color4
                    else:
                        f_col = f.color1, f.color2, f.color3

                    for j, col in enumerate(f_col):
                        col.r, col.g, col.b = ply_col[j]

    mesh.validate()
    mesh.update()

    if texture and uvindices:

        import os
        import sys
        from bpy_extras.image_utils import load_image

        encoding = sys.getfilesystemencoding()
        encoded_texture = texture.decode(encoding=encoding)
        name = bpy.path.display_name_from_filepath(texture)
        image = load_image(encoded_texture,
                           os.path.dirname(filepath),
                           recursive=True,
                           place_holder=True)

        if image:
            texture = bpy.data.textures.new(name=name, type='IMAGE')
            texture.image = image

            material = bpy.data.materials.new(name=name)
            material.use_shadeless = True

            mtex = material.texture_slots.add()
            mtex.texture = texture
            mtex.texture_coords = 'UV'
            mtex.use_map_color_diffuse = True

            mesh.materials.append(material)
            for face in mesh.uv_textures[0].data:
                face.image = image

    return mesh
Beispiel #47
0
    def create_mesh(self):
        global material_list
        global current_ac_file
        global xml_extra_position
        global xml_extra_rotation

        if not self.parent_name:
            return

        debug_info("ac_manager::MESH.create_mesh() %s" % self.mesh_name)
        obj_name = self.mesh_name
        context = CONTEXT

        mesh = bpy.data.meshes.new(obj_name + ".mesh")

        if self.crease != -1.0:
            mesh.use_auto_smooth = True
            mesh.auto_smooth_angle = radians(self.crease)

        mesh.vertices.add(len(self.vertices))
        mesh.tessfaces.add(len(self.faces))

        mesh.vertices.foreach_set("co", unpack_list(self.vertices))
        mesh.tessfaces.foreach_set("vertices_raw",
                                   unpack_face_list(self.faces))
        mesh.tessfaces.foreach_set("use_smooth", [(True)] * len(self.faces))

        mesh.update()

        sc = bpy.context.scene
        obj_new = bpy.data.objects.new(obj_name, mesh)
        current_ac_file.meshs.append(obj_new.name)
        current_ac_file.dic_name_meshs[obj_name] = obj_new.name

        obj_new.data.fg.name_ac = obj_name
        obj_new.location = self.location

        compute_extra_transforme(obj_new, xml_extra_position,
                                 xml_extra_rotation)

        self.mesh_name_bl = obj_new.name

        o = sc.objects.link(obj_new)

        if self.parent_name[-1] != 'WORLD':
            str_print = "create_mesh() %s   parent = %s" % (
                self.mesh_name_bl, self.parent_name[-1])
            obj_new.parent = bpy.data.objects[self.parent_name[-1]]
        else:
            str_print = "create_mesh() %s" % (self.mesh_name_bl)

        str_print += ' mat no = %d  texture="%s" image="%s"' % (
            self.mat_no, self.tex_name_bl, self.img_name_bl)
        debug_info(str_print)

        self.create_uv(mesh)
        self.assign_material(obj_new)

        #mesh.update(calc_edges=True)
        mesh.validate()
        mesh.update(calc_edges=True)

        obj_new.data.fg.ac_file = "" + self.filename
        self.edge_split(obj_new)
    def ReadMesh(self, mesh):
        print("Name: {}".format(mesh["name"]))
        print("Num Verts: {}".format(len(mesh["vertices"])))
        print("Num Indices: {}".format(len(mesh["indices"][0])))

        scn = bpy.context.scene

        for o in scn.objects:
            o.select = False

        blenmesh = bpy.data.meshes.new(mesh["name"])
        blenmesh.vertices.add(len(mesh["vertices"]))
        blenmesh.vertices.foreach_set("co", unpack_list(mesh["vertices"]))
        blenmesh.tessfaces.add(len(mesh["indices"][0]))
        # Add faces
        blenmesh.tessfaces.foreach_set("vertices_raw",
                                       unpack_face_list(mesh["indices"][0]))

        uvlay = blenmesh.tessface_uv_textures.new()

        for i, f in enumerate(uvlay.data):
            index = mesh["indices"][0][i]
            for j, uv in enumerate(f.uv):
                uv[0] = mesh["uvs"][index[j]][0]
                uv[1] = mesh["uvs"][index[j]][1]

        #add object to scene
        blenmesh.update()
        blenmesh.validate()
        nobj = bpy.data.objects.new(mesh["name"], blenmesh)
        scn.objects.link(nobj)

        #print("Skel: {}".format(mesh["skeleton"]))

        # Create Armature and Object
        bpy.ops.object.add(type='ARMATURE', enter_editmode=True)
        object = bpy.context.object
        object.name = 'armguy'
        armature = object.data
        armature.name = 'armguy'

        #create bones
        for the_bone in mesh["skeleton"]:
            nobj.vertex_groups.new(name=the_bone["name"])
            bone = armature.edit_bones.new(the_bone["name"])
            bone.tail = Vector(
                [0, 0, 0.1]
            )  # if you won't do it, the bone will have zero lenghtand will be removed immediately by Blender

        #map parents
        for the_bone in mesh["skeleton"]:
            if 'parent' in the_bone:
                armature.edit_bones[the_bone[
                    'name']].parent = armature.edit_bones[the_bone['parent']]
                parent = self.FindBoneByName(mesh["skeleton"],
                                             the_bone['parent'])

        for the_bone in mesh["skeleton"]:
            matrix = Matrix(the_bone["matrix"])
            matrix.transpose()
            matrix = matrix.inverted()
            armature.edit_bones[the_bone['name']].transform(matrix)

        for vidx in range(0, len(mesh["vertices"])):
            bones = mesh["bone_indices"][0][vidx]
            weights = mesh["weights"][0][vidx]
            print("Vertex: {}".format(vidx))
            print("Data: {} {}".format(bones, weights))
            for widx in range(0, len(weights)):
                bone_idx = bones[widx]
                if bone_idx == 0:
                    break
                weight = weights[widx]
                nobj.vertex_groups[bone_idx].add([vidx], weight, 'ADD')


#		for vwidx, wval in enumerate(mesh["weights"][0]):
#			bones = mesh["bone_indices"][0][vwidx]
#			print("Vertex: {}".format(vwidx))
#			print("Data: {} {}".format(bones, wval))
#			for vwsidx, vwsval in enumerate(wval):
#				bone_idx = bones[vwsidx]
#				the_bone = mesh["skeleton"][bone_idx]
#				print("Bone: {} ({}): {}".format(bone_idx, the_bone["name"], vwsval))
#				nobj.vertex_groups[bone_idx].add([vwidx], vwsval, 'ADD')
        return nobj
Beispiel #49
0
def processLambert(f, blocks):
    verts = []
    faces = []
    uvs = []
    texs = []
    
    #Get Version
    version = struct.unpack('<B', f.read(1))[0]
    
    type = struct.unpack('<I', f.read(4))[0]
    
    #skip
    f.read(40)
    
    #Get Textures
    for i in range(8):
        length = struct.unpack('<I', f.read(4))[0]
        texStr = '<%ds' % length
        tex = struct.unpack(texStr, f.read(length))[0].decode()
        texs.append(tex)
        
        print("Texture: %s" % tex)
        
    #skip unknown data
    f.read(4)
    
    print("Type: %d" % (type))
    
    if(type == 1):
        vertCount = struct.unpack('<I', f.read(4))[0]
        print("Vertices: %d" % vertCount)
        
        for vert in range(vertCount):
            extra1 = struct.unpack('<H', f.read(2))[0]
            extra2 = struct.unpack('<H', f.read(2))[0]
            extra3 = struct.unpack('<H', f.read(2))[0]
            extra4 = struct.unpack('<H', f.read(2))[0]
            
            extra5 = struct.unpack('<f', f.read(4))[0]
            extra6 = struct.unpack('<f', f.read(4))[0]
            extra7 = struct.unpack('<f', f.read(4))[0]
            
            
            x = struct.unpack('<H', f.read(2))[0]
            y = struct.unpack('<H', f.read(2))[0]
            z = struct.unpack('<H', f.read(2))[0]
            
            extra8 = struct.unpack('<H', f.read(2))[0]
            
            print("Data: %d %d %d" % (x, y, z))
            
            
            verts.append((x/65550, z/65550, y/65550))
            
            
        faceCount = struct.unpack('<I', f.read(4))[0]
        print("Faces: %d" % faceCount)
         
        for face in range(int(faceCount/3)):
            vert1 = struct.unpack('<H', f.read(2))[0]
            vert2 = struct.unpack('<H', f.read(2))[0]
            vert3 = struct.unpack('<H', f.read(2))[0]
        
            faces.append((vert1, vert2, vert3))
            
    #Read Check
    check = struct.unpack('<I', f.read(4))[0]
        
    #Add object data
    mesh = bpy.data.meshes.new("Mesh")
    mesh.vertices.add(vertCount)
    mesh.tessfaces.add(faceCount/3)
    
    mesh.vertices.foreach_set("co", unpack_list(verts))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
    mesh.tessface_uv_textures.new()
    
    for face in range(int(faceCount/3)):
        uv = mesh.tessface_uv_textures[0].data[face]
        
        #uv.uv1 = uvs[faces[face][0]]
        #uv.uv2 = uvs[faces[face][1]]
        #uv.uv3 = uvs[faces[face][2]]
    
    mesh.validate()
    mesh.update()
    
    obj = bpy.data.objects.new("Mesh_Lambert_0", mesh)

    blocks.append(obj)
def load_ply(filepath):
    import time
    from bpy_extras.io_utils import unpack_face_list
    # from bpy_extras.image_utils import load_image  # UNUSED

    t = time.time()
    obj_spec, obj = read(filepath)
    if obj is None:
        print('Invalid file')
        return

    uvindices = colindices = None
    colmultiply = None

    # noindices = None # Ignore normals

    for el in obj_spec.specs:
        if el.name == b'vertex':
            vindices_x, vindices_y, vindices_z = el.index(b'x'), el.index(b'y'), el.index(b'z')
            # noindices = (el.index('nx'), el.index('ny'), el.index('nz'))
            # if -1 in noindices: noindices = None
            uvindices = (el.index(b's'), el.index(b't'))
            if -1 in uvindices:
                uvindices = None
            colindices = el.index(b'red'), el.index(b'green'), el.index(b'blue')
            if -1 in colindices:
                colindices = None
            else:  # if not a float assume uchar
                colmultiply = [1.0 if el.properties[i].numeric_type in {'f', 'd'} else (1.0 / 256.0) for i in colindices]

        elif el.name == b'face':
            findex = el.index(b'vertex_indices')

    mesh_faces = []
    mesh_uvs = []
    mesh_colors = []

    def add_face(vertices, indices, uvindices, colindices):
        mesh_faces.append(indices)
        if uvindices:
            mesh_uvs.append([(vertices[index][uvindices[0]], 1.0 - vertices[index][uvindices[1]]) for index in indices])
        if colindices:
            mesh_colors.append([(vertices[index][colindices[0]] * colmultiply[0],
                                 vertices[index][colindices[1]] * colmultiply[1],
                                 vertices[index][colindices[2]] * colmultiply[2],
                                 ) for index in indices])

    if uvindices or colindices:
        # If we have Cols or UVs then we need to check the face order.
        add_face_simple = add_face

        # EVIL EEKADOODLE - face order annoyance.
        def add_face(vertices, indices, uvindices, colindices):
            if len(indices) == 4:
                if indices[2] == 0 or indices[3] == 0:
                    indices = indices[2], indices[3], indices[0], indices[1]
            elif len(indices) == 3:
                if indices[2] == 0:
                    indices = indices[1], indices[2], indices[0]

            add_face_simple(vertices, indices, uvindices, colindices)

    verts = obj[b'vertex']

    if b'face' in obj:
        for f in obj[b'face']:
            ind = f[findex]
            len_ind = len(ind)
            if len_ind <= 4:
                add_face(verts, ind, uvindices, colindices)
            else:
                # Fan fill the face
                for j in range(len_ind - 2):
                    add_face(verts, (ind[0], ind[j + 1], ind[j + 2]), uvindices, colindices)

    ply_name = bpy.path.display_name_from_filepath(filepath)

    mesh = bpy.data.meshes.new(name=ply_name)

    mesh.vertices.add(len(obj[b'vertex']))

    mesh.vertices.foreach_set("co", [a for v in obj[b'vertex'] for a in (v[vindices_x], v[vindices_y], v[vindices_z])])

    if mesh_faces:
        mesh.faces.add(len(mesh_faces))
        mesh.faces.foreach_set("vertices_raw", unpack_face_list(mesh_faces))

        if uvindices or colindices:
            if uvindices:
                uvlay = mesh.uv_textures.new()
            if colindices:
                vcol_lay = mesh.vertex_colors.new()

            if uvindices:
                for i, f in enumerate(uvlay.data):
                    ply_uv = mesh_uvs[i]
                    for j, uv in enumerate(f.uv):
                        uv[0], uv[1] = ply_uv[j]

            if colindices:
                for i, f in enumerate(vcol_lay.data):
                    # XXX, colors dont come in right, needs further investigation.
                    ply_col = mesh_colors[i]
                    if len(ply_col) == 4:
                        f_col = f.color1, f.color2, f.color3, f.color4
                    else:
                        f_col = f.color1, f.color2, f.color3

                    for j, col in enumerate(f_col):
                        col.r, col.g, col.b = ply_col[j]

    mesh.validate()
    mesh.update()

    scn = bpy.context.scene
    #scn.objects.selected = [] # XXX25

    obj = bpy.data.objects.new(ply_name, mesh)
    scn.objects.link(obj)
    scn.objects.active = obj
    obj.select = True

    print('\nSuccessfully imported %r in %.3f sec' % (filepath, time.time() - t))
Beispiel #51
0
    def write_mesh_data(self, entities=None, name="", default_material='Material'):
        mesh_key = (name,default_material)
        if mesh_key in self.component_meshes:
            return self.component_meshes[mesh_key]
        verts = []
        faces = []
        mat_index = []
        smooth = []
        mats = keep_offset()
        seen = keep_offset()
        uv_list = []
        alpha = False # We assume object does not need alpha flag
        uvs_used = False # We assume no uvs need to be added


        for f in entities.faces:

            if f.material:
                mat_number = mats[f.material.name]
            else:
                mat_number = mats[default_material]
                if default_material != 'Material':
                    try:
                        f.st_scale = self.materials_scales[default_material]
                    except KeyError as e:
                        pass

            vs, tri, uvs = f.tessfaces

            mapping = {}
            for i, (v, uv) in enumerate(zip(vs, uvs)):
                l = len(seen)
                mapping[i] = seen[v]
                if len(seen) > l:
                    verts.append(v)
                uvs.append(uv)

            smooth_edge = False

            for edge in f.edges:
                if edge.GetSmooth() == True:
                    smooth_edge = True
                    break

            for face in tri:
                f0, f1, f2 = face[0], face[1], face[2]
                if mapping[f2] == 0 : ## eeekadoodle dance
                    faces.append( ( mapping[f2], mapping[f0], mapping[f1] ) )
                    uv_list.append(( uvs[f2][0], uvs[f2][1],
                                     uvs[f0][0], uvs[f0][1],
                                     uvs[f1][0], uvs[f1][1],
                                     0, 0 ) )
                else:
                    faces.append( ( mapping[f0], mapping[f1], mapping[f2] ) )
                    uv_list.append(( uvs[f0][0], uvs[f0][1],
                                     uvs[f1][0], uvs[f1][1],
                                     uvs[f2][0], uvs[f2][1],
                                     0, 0 ) )
                smooth.append(smooth_edge)
                mat_index.append(mat_number)

        # verts, faces, uv_list, mat_index, mats = entities.get__triangles_lists(default_material)

        if len(verts) == 0:
            return None, False

        me = bpy.data.meshes.new(name)

        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))

        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                try:
                    bmat = self.materials[k]
                except KeyError as e:
                    bmat = self.materials["Material"]
                me.materials.append(bmat)
                if bmat.alpha < 1.0:
                    alpha = True
                try:
                    if self.render_engine == 'CYCLES':
                        if 'Image Texture' in bmat.node_tree.nodes.keys():
                            uvs_used = True
                    else:
                        for ts in bmat.texture_slots:
                            if ts is not None and ts.texture_coords is not None:
                                uvs_used = True
                except AttributeError as e:
                    uvs_used = False
        else:
            sketchupLog("WARNING OBJECT {} HAS NO MATERIAL".format(name))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)
        me.tessfaces.foreach_set("use_smooth", smooth)

        print('tessfaces: %i smoothie %i' % (len(faces), len(smooth)))

        if uvs_used:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uv_list[i]

        me.update(calc_edges=True)
        me.validate()
        self.component_meshes[mesh_key] = me, alpha
        return me, alpha