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
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
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
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)
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')