예제 #1
0
    def convert_mesh(self, vtx_model: VTX_DATA.SourceVtxModel, lod_index, model: MDL_DATA.SourceMdlModel,
                     material_indexes):
        vtx_meshes = vtx_model.vtx_model_lods[lod_index].vtx_meshes  # type: List[VTX_DATA.SourceVtxMesh]
        indexes = []
        vertex_normals = []
        # small speedup
        i_ex = indexes.append
        m_ex = material_indexes.append
        vn_ex = vertex_normals.extend

        for mesh_index, vtx_mesh in enumerate(vtx_meshes):  # type: int,VTX_DATA.SourceVtxMesh
            material_index = model.meshes[mesh_index].material_index
            mesh_vertex_start = model.meshes[mesh_index].vertex_index_start
            if vtx_mesh.vtx_strip_groups:
                for group_index, strip_group in enumerate(
                        vtx_mesh.vtx_strip_groups):  # type: VTX_DATA.SourceVtxStripGroup
                    if strip_group.vtx_strips and strip_group.vtx_indexes and strip_group.vtx_vertexes:
                        field = progressBar.Progress_bar('Converting mesh_data', len(strip_group.vtx_indexes), 20)
                        for vtx_index in range(0, len(strip_group.vtx_indexes), 3):
                            if not vtx_index % 3 * 10:
                                field.increment(3)
                            f, vn = self.get_polygon(strip_group, vtx_index, lod_index, mesh_vertex_start)
                            if not f and not vn:
                                break
                            i_ex(f)
                            vn_ex(vn)
                            m_ex(material_index)
                        field.is_done = True
                        field.draw()
                    else:
                        pass

            else:
                pass
        return indexes, material_indexes, vertex_normals
예제 #2
0
 def import_texture(self):
     # from PIL import Image
     a = time.time()
     acc = []
     rows = converter.split(self.IMAGE,
                            self.vtf_header.width * len(self.MODE))[::-1]
     for row in rows:
         acc.extend(row)
     print('Dims', self.vtf_header.width, 'x', self.vtf_header.height)
     print((time.time() - a) * 1000, 'ms')
     # IMAGE = Image.frombytes(self.MODE, (self.vtf_header.width, self.vtf_header.height), bytes(self.IMAGE))
     # IMAGE.save(
     #     '{}_{}.png'.format(self.file_name, VTF_DATA.VTF_FORMATS(self.vtf_header.highResImageFormat).name))
     image = bpy.data.images.new(self.file_name,
                                 width=self.vtf_header.width,
                                 height=self.vtf_header.height)
     size = len(image.pixels) // 8
     field = progressBar.Progress_bar(
         'Importing {} texture'.format(self.file_name), 8, 20)
     for n in range(0, len(image.pixels), size):
         image.pixels[n:n + size] = converter.convert_pixels(acc[n:n +
                                                                 size])
         field.increment(1)
         field.draw()
     image.pack(as_png=True)
     return image
예제 #3
0
        def WriteMesh_fallback(VtxModel: VTX_DATA.SourceVtxModel, lodIndex,
                               aModel: MDL_DATA.SourceMdlModel,
                               bodyPartVertexIndexStart, mat_indexes, VVD):
            aVtxLod = VtxModel.theVtxModelLods[
                lodIndex]  # type: VTX_DATA.SourceVtxModelLod
            indexes = []
            vertex_idexes = []
            for meshIndex, aVtxMesh in enumerate(
                    aVtxLod.theVtxMeshes):  # type: VTX_DATA.SourceVtxMesh
                # print('meshIndex',meshIndex,len(Model.theMeshes))
                materialIndex = aModel.theMeshes[meshIndex].materialIndex
                meshVertexIndexStart = aModel.theMeshes[
                    meshIndex].vertexIndexStart
                # print('stripGroupCount',VtxMesh.stripGroupCount)
                if aVtxMesh.theVtxStripGroups.__len__() > 0:
                    for groupIndex, aStripGroup in enumerate(
                            aVtxMesh.theVtxStripGroups
                    ):  # type: VTX_DATA.SourceVtxStripGroup
                        # print('StripGroup.stripCount',StripGroup.stripCount,'StripGroup.indexCount',StripGroup.indexCount,'StripGroup.vertexCount',StripGroup.vertexCount)
                        if aStripGroup.theVtxStrips.__len__(
                        ) > 0 and aStripGroup.theVtxIndexes.__len__(
                        ) > 0 and aStripGroup.theVtxVertexes.__len__() > 0:
                            field = progressBar.Progress_bar(
                                'Generating mesh',
                                aStripGroup.theVtxIndexes.__len__(), 20)

                            for vtxIndexIndex in range(
                                    0, aStripGroup.theVtxIndexes.__len__(), 3):
                                field.increment(3)
                                field.draw()
                                f, fv = getPoly(aStripGroup, vtxIndexIndex,
                                                lodIndex, meshVertexIndexStart,
                                                bodyPartVertexIndexStart, VVD)
                                s, sv = getPoly(aStripGroup, vtxIndexIndex + 2,
                                                lodIndex, meshVertexIndexStart,
                                                bodyPartVertexIndexStart, VVD)
                                t, tv = getPoly(aStripGroup, vtxIndexIndex + 1,
                                                lodIndex, meshVertexIndexStart,
                                                bodyPartVertexIndexStart, VVD)
                                mat_indexes.append(materialIndex)
                                if vtxIndexIndex not in vertex_idexes:
                                    vertex_idexes.append(vtxIndexIndex)
                                if vtxIndexIndex + 2 not in vertex_idexes:
                                    vertex_idexes.append(vtxIndexIndex + 2)
                                if vtxIndexIndex + 1 not in vertex_idexes:
                                    vertex_idexes.append(vtxIndexIndex + 1)
                                indexes.append((f, s, t))
                        else:
                            print('ERROR in getPoly')
                else:
                    print('ERROR in theVtxStripGroups')
            return indexes, mat_indexes, vertex_idexes
예제 #4
0
    def generate_model(self, base_name, i, types, model):
        print('Importing map geometry:', base_name)
        for type_, faces_ in types.items():
            faces = []
            mat_ind = []
            mats = []
            uvs = [None for _ in self.BSP.BSP.LUMPS[3]]
            field = progressBar.Progress_bar(
                'Generating {} mesh'.format('{}_{}'.format(base_name, type_)),
                len(faces_), 20)
            for face in faces_:

                faceindexes = []
                firstedge = face.firstedge
                numedges = face.numedges
                texInfo = self.BSP.BSP.LUMPS[6][face.texinfo]
                texdata = self.BSP.BSP.LUMPS[2][texInfo.texdata]
                mat_name = self.BSP.BSP.LUMPS[43][texdata.nameStringTableID]
                mat_ind.append((texInfo.texdata, mat_name))

                edge_indexs = [
                    self.BSP.BSP.LUMPS[13][firstedge + ind].surfedge
                    for ind in range(numedges)
                ]
                for edge_index in edge_indexs:
                    edges = self.BSP.BSP.LUMPS[12][abs(edge_index)].v
                    if edge_index < 0:
                        if edges[1] not in faceindexes:
                            faceindexes.append(edges[1])
                        if edges[0] not in faceindexes:
                            faceindexes.append(edges[0])
                    else:
                        if edges[0] not in faceindexes:
                            faceindexes.append(edges[0])
                        if edges[1] not in faceindexes:
                            faceindexes.append(edges[1])

                    for v in edges:
                        x, y, z = self.vets[v]
                        tv = texInfo.textureVecs
                        u = tv[0].x * x + tv[0].y * y + tv[0].z * z + tv[
                            0].offset
                        v = tv[1].x * x + tv[1].y * y + tv[1].z * z + tv[
                            1].offset
                        uvs.append((u, v))
                faces.append(tuple(faceindexes))
                field.increment(1)
                field.draw()
            name = '{}_{}_{}'.format(base_name, type_, i)

            model_mesh = bpy.data.objects.new(name, bpy.data.meshes.new(name))
            model_mesh.location = (model.origin.x, model.origin.y,
                                   model.origin.z)
            model_mesh.parent = self.armature_object
            bpy.context.scene.objects.link(model_mesh)
            md = model_mesh.data
            md.from_pydata(self.vets, [], faces)
            md.update()

            # try:
            #     print('NORMS', len(vert_n), len(md.loops))
            #     md.create_normals_split()
            #     md.use_auto_smooth = True
            #     md.normals_split_custom_set_from_vertices(vert_n)
            # except Exception as E:
            #     print(E)
            #     print('FAILED TO SET CUSTOM NORMALS')
            try:
                vert_n = list([(-self.BSP.BSP.LUMPS[30][vert_n].x,
                                -self.BSP.BSP.LUMPS[30][vert_n].y,
                                -self.BSP.BSP.LUMPS[30][vert_n].z)
                               for vert_n in self.BSP.BSP.LUMPS[31].indexes])
                md.create_normals_split()
                md.use_auto_smooth = True
                md.normals_split_custom_set_from_vertices(vert_n)

            except Exception as Ex:
                print(Ex)

            for _, mat_name in mat_ind:

                if mat_name.startswith('maps/'):
                    mat_name = mat_name.split('/')[-1]
                    mat_name = '_'.join(mat_name.split('_')[:-3])

                mat, mat_ind_ = self.getMeshMaterial(mat_name, model_mesh)
                mats.append(mat_ind_)
            md.uv_textures.new()
            uv_data = md.uv_layers[0].data
            for i in range(len(uv_data)):
                if uvs[md.loops[i].vertex_index] is None:
                    continue
                uv_data[i].uv = uvs[md.loops[i].vertex_index]
            for poly, mat_index in zip(model_mesh.data.polygons, mats):
                poly.material_index = mat_index
            bpy.ops.object.select_all(action="DESELECT")
            model_mesh.select = True
            bpy.context.scene.objects.active = model_mesh
            with redirect_stdout(stdout):
                bpy.ops.object.mode_set(mode='EDIT')
                bpy.ops.mesh.delete_loose()
                bpy.ops.mesh.remove_doubles()
                bpy.context.scene.objects.active.data.validate()
                bpy.ops.mesh.normals_make_consistent(inside=False)
                bpy.ops.mesh.delete_loose()
                bpy.ops.mesh.remove_doubles(threshold=0.0002)
                bpy.context.scene.objects.active.data.validate()
                bpy.ops.mesh.remove_doubles(threshold=0.0001)
                bpy.ops.mesh.normals_make_consistent(inside=False)
                bpy.ops.object.mode_set(mode='OBJECT')

                bpy.ops.object.shade_smooth()
            model_mesh.data.use_auto_smooth = True
            if type_ == 'TRIGGER':
                model_mesh.layers[1] = True
                for i in range(20):
                    model_mesh.layers[i] = (i == 1)
            if type_ == 'MESH':
                model_mesh.layers[0] = True
                for i in range(20):
                    model_mesh.layers[i] = (i == 0)
            if type_ in ['SKY', 'SKY2D']:
                model_mesh.layers[4] = True
                for i in range(20):
                    model_mesh.layers[i] = (i == 4)
예제 #5
0
    def create_model2(self, model: MDL_DATA.SourceMdlModel, vtx_model: VTX_DATA.SourceVtxModel):
        name = model.name.replace('.smd', '').replace('.dmx', '')
        if '/' in name or '\\' in name:
            name = os.path.basename(name)
        if len(vtx_model.vtx_model_lods[0].vtx_meshes) < 1:
            print('No meshes in vtx model_path')
            return
        self.mesh_obj = bpy.data.objects.new(name, bpy.data.meshes.new(name))
        self.mesh_obj.parent = self.armature_obj
        bpy.context.scene.objects.link(self.mesh_obj)

        modifier = self.mesh_obj.modifiers.new(type="ARMATURE", name="Armature")
        modifier.object = self.armature_obj

        self.mesh_data = self.mesh_obj.data
        [self.get_material(mat.path_file_name, self.mesh_obj) for mat in self.MDL.file_data.textures]
        weight_groups = {bone.name: self.mesh_obj.vertex_groups.new(bone.name) for bone in self.MDL.file_data.bones}

        vtx_model_lod = vtx_model.vtx_model_lods[0]
        vvd_verts = self.VVD.file_data.vertexes
        indices = []
        vertex_global_ids = []
        vtx_vertexes = []
        vertexes = []
        normals = []
        weights = []  # type: List[GLOBALS.SourceBoneWeight]
        uvs = []
        for vtx_mesh, mdl_mesh in zip(vtx_model_lod.vtx_meshes, model.meshes):
            # mdl_mesh.vertex_index_start
            for strip_group in vtx_mesh.vtx_strip_groups:
                # indices.extend(split(strip_group.vtx_indexes, 3))
                # vertex_offset = self.vertex_offset
                # vtx_vertexes.extend(strip_group.vtx_vertexes)
                # vertexes.extend(vvd_verts[vertex_offset:vertex_offset + strip_group.vertex_count])

                for i, vertex_id in enumerate(strip_group.vtx_indexes):  # type: int
                    vertex = strip_group.vtx_vertexes[vertex_id]
                    vertex_global_ids.append(
                        vertex.original_mesh_vertex_index + self.vertex_offset + mdl_mesh.vertex_index_start)
                    # indices.append(vertex_id)
                    vtx_vertexes.append(vertex)
                    # field.increment(1000)
                indices.extend(list(map(lambda a: a[::-1], split(strip_group.vtx_indexes, 3))))

                # self.index_offset+=strip_group.index_count

        self.vertex_offset += model.vertex_count
        field = progressBar.Progress_bar('Converting mesh_data', len(vertex_global_ids), 20)
        for i, vertex_id in enumerate(set(vertex_global_ids)):
            v, uv, n, w = self.convert_vertex2(
                vvd_verts[vertex_id])
            vertexes.append(v)
            normals.append(n)
            uvs.append(uv)
            weights.append(w)
            if not i % 1000:
                field.increment(1000)
        field.is_done = True
        field.draw()
        self.mesh_data.from_pydata(vertexes, [], indices)
        self.mesh_data.update()
        bpy.ops.object.shade_smooth()
        self.mesh_data.use_auto_smooth = True
        # self.mesh_data.normals_split_custom_set(normals)
        # self.mesh_data.uv_textures.new()
        # uv_data = self.mesh_data.uv_layers[0].data
        # for i in range(len(uv_data)):
        #     u = uvs[self.mesh_data.loops[i].vertex_index]
        #     uv_data[i].uv = u
        for n, vertex_weight in enumerate(weights):
            for bone_index, weight in zip(vertex_weight.bone, vertex_weight.weight):
                if weight == 0.0:
                    continue
                weight_groups[self.MDL.file_data.bones[bone_index].name].add([n], weight, 'REPLACE')