def readMesh(filename, objName): file = open(filename, "rb") def line_to_face(line): # Each triplet is an xyz float line_split = [] try: line_split = list(map(float, line.split())) except: return None if len(line_split) == 9: # Tri f1, f2, f3, f4, f5, f6, f7, f8, f9 = line_split return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9)] elif len(line_split) == 12: # Quad f1, f2, f3, f4, f5, f6, f7, f8, f9, A, B, C = line_split return [(f1, f2, f3), (f4, f5, f6), (f7, f8, f9), (A, B, C)] else: return None faces = [] for line in file.readlines(): face = line_to_face(line) if face: faces.append(face) file.close() # Generate verts and faces lists, without duplicates verts = [] coords = {} index_tot = 0 for f in faces: for i, v in enumerate(f): index = coords.get(v) if index is None: index = coords[v] = index_tot index_tot += 1 verts.append(v) fi[i] = index mesh = bpy.data.meshes.new(objName) mesh.vertices.add(len(verts)) mesh.faces.add(len(faces)) mesh.vertices.foreach_set("co", unpack_list(verts)) mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces)) return mesh
def read_shape(data,use_subsurf,use_hidden): read_tuple_header(data) skip_token(data) #object shape_name = read_token(data) print ("shape: ",shape_name) read_tuple_header(data) skip_token(data) #winged #read mesh data edge_table = read_array(data,read_edge_set) print("edge_table: ",edge_table) face_props = read_array(data,read_array_as_dict) print("face_mats: ",face_props) verts = read_array(data,read_vertex_array) print("verts: ",verts) hard_edges = read_array(data) print("hard_edges: ",hard_edges) props = read_array_as_dict(data,read_prop) print("props: ",props) # if we are ignoring hidden objects # we can stop now if use_hidden == True and b'state' in props: state = props[b'state'] if state == b'hidden' or state == b'hidden_locked': return # make a list of edges with just the vert part # of the list eg [(v0,v1),(v0,v1)...] edges = get_edges(edge_table) print("edges: ",edges) # build a list of faces from edge data, # also vertex colors, face_uvs and a few other bits # and pieces faces,face_cols,face_uvs,hide_edges,mirror_face = faces_from_edge_table(edge_table,verts,props,face_props,edges) print("edges: ",edges) print("faces: ",faces) print("colors: ",face_cols) print("uvs: ",face_uvs) print("hide edges: ",hide_edges) #create bleneder mesh me = bpy.data.meshes.new(shape_name) ob = bpy.data.objects.new(shape_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)) me.edges.add(len(edges)) me.edges.foreach_set("vertices",unpack_list(edges)) me.validate() # me.update(calc_edges=True) #add edges to blender mesh, mark special edges #b_edges = me.edges #for i in range(len(b_edges)): #(v0,v1) = b_edges[i].vertices #print("edge ", i, " ",v0,"-",v1) build_hard_edges(me,hard_edges) hide_fgon_edges(me,hide_edges) if len(face_cols) > 0: build_face_colors(me,face_cols) if len(face_uvs) > 0: build_face_uvs(me,face_uvs) for i in range(len(faces)): me.faces[i].use_smooth = True add_material_indices(me,face_props) mods = ob.modifiers if use_subsurf == True: mod = mods.new("subsurf",'SUBSURF') mod.levels = 2 if mirror_face != None: pivot = build_mirror_pivot(mirror_face,verts,ob) mirror = mods.new("mirror",'MIRROR') mirror.mirror_object = pivot mirror.use_clip = True mirror.use_mirror_merge = True #ob.parent = pivot if b'state' in props: state = props[b'state'] if state == b'locked' or state == b'hidden_locked': ob.hide_select = True if state == b'hidden' or state == b'hidden_locked': ob.hide = True ob.hide_render = True if b'plugin_states' in props: plugin_states = props[b'plugin_states'] if b'wings_shape' in plugin_states: folder = plugin_states[b'wings_shape'] if folder != b'no_folder': dummy = bpy.data.objects.get(folder) if dummy == None: dummy = bpy.data.objects.new(folder,None) bpy.context.scene.objects.link(dummy) ob.parent = dummy
def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_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 fgons, sharp edges and assigning materials ''' if not has_ngons: CREATE_FGONS = 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 fgons into tri's fgon_edges = {} # Used for storing fgon keys if CREATE_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 CREATE_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 # FGons into triangles if has_ngons and len_face_vert_loc_indices > 4: ngon_face_indices = BPyMesh_ngon(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 fgons if CREATE_FGONS: 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[key] = None # 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.faces.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.faces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces])) if verts_tex and me.faces: me.uv_textures.new() context_material_old = -1 # avoid a dict lookup mat = 0 # rare case it may be un-initialized. me_faces = me.faces for i, face in enumerate(faces): if len(face[0]) < 2: pass # raise "bad face" elif len(face[0]) == 2: if CREATE_EDGES: edges.append(face[0]) else: blender_face = me.faces[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.uv_textures[0].data[i] if context_material: image, has_data = unique_material_images[context_material] if image: # Can be none if the material dosnt have an image. blender_tface.image = image blender_tface.use_image = True if has_data and image.depth == 32: blender_tface.blend_type = 'ALPHA' # 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 CREATE_EDGES and not edges: CREATE_EDGES = False if CREATE_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]) # XXX slow # if CREATE_FGONS and fgon_edges: # for fgon_edge in fgon_edges.keys(): # for ed in me.edges: # if edges_match(fgon_edge, ed.vertices): # ed.is_fgon = True # if CREATE_FGONS and fgon_edges: # FGON= Mesh.EdgeFlags.FGON # for ed in me.findEdges( fgon_edges.keys() ): # if ed is not None: # me_edges[ed].flag |= FGON # del FGON # 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 me.validate() me.update(calc_edges=CREATE_EDGES) ob = bpy.data.objects.new("Mesh", 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) group.add(group_indices, 1.0, 'REPLACE')
def read_shape(data, use_subsurf, use_hidden): read_tuple_header(data) skip_token(data) #object shape_name = read_token(data) print("shape: ", shape_name) read_tuple_header(data) skip_token(data) #winged #read mesh data edge_table = read_array(data, read_edge_set) print("edge_table: ", edge_table) face_props = read_array(data, read_array_as_dict) print("face_mats: ", face_props) verts = read_array(data, read_vertex_array) print("verts: ", verts) hard_edges = read_array(data) print("hard_edges: ", hard_edges) props = read_array_as_dict(data, read_prop) print("props: ", props) # if we are ignoring hidden objects # we can stop now if use_hidden == True and b'state' in props: state = props[b'state'] if state == b'hidden' or state == b'hidden_locked': return # make a list of edges with just the vert part # of the list eg [(v0,v1),(v0,v1)...] edges = get_edges(edge_table) print("edges: ", edges) # build a list of faces from edge data, # also vertex colors, face_uvs and a few other bits # and pieces faces, face_cols, face_uvs, hide_edges, mirror_face = faces_from_edge_table( edge_table, verts, props, face_props, edges) print("edges: ", edges) print("faces: ", faces) print("colors: ", face_cols) print("uvs: ", face_uvs) print("hide edges: ", hide_edges) #create bleneder mesh me = bpy.data.meshes.new(shape_name) ob = bpy.data.objects.new(shape_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)) me.edges.add(len(edges)) me.edges.foreach_set("vertices", unpack_list(edges)) me.validate() # me.update(calc_edges=True) #add edges to blender mesh, mark special edges #b_edges = me.edges #for i in range(len(b_edges)): #(v0,v1) = b_edges[i].vertices #print("edge ", i, " ",v0,"-",v1) build_hard_edges(me, hard_edges) hide_fgon_edges(me, hide_edges) if len(face_cols) > 0: build_face_colors(me, face_cols) if len(face_uvs) > 0: build_face_uvs(me, face_uvs) for i in range(len(faces)): me.faces[i].use_smooth = True add_material_indices(me, face_props) mods = ob.modifiers if use_subsurf == True: mod = mods.new("subsurf", 'SUBSURF') mod.levels = 2 if mirror_face != None: pivot = build_mirror_pivot(mirror_face, verts, ob) mirror = mods.new("mirror", 'MIRROR') mirror.mirror_object = pivot mirror.use_clip = True mirror.use_mirror_merge = True #ob.parent = pivot if b'state' in props: state = props[b'state'] if state == b'locked' or state == b'hidden_locked': ob.hide_select = True if state == b'hidden' or state == b'hidden_locked': ob.hide = True ob.hide_render = True if b'plugin_states' in props: plugin_states = props[b'plugin_states'] if b'wings_shape' in plugin_states: folder = plugin_states[b'wings_shape'] if folder != b'no_folder': dummy = bpy.data.objects.get(folder) if dummy == None: dummy = bpy.data.objects.new(folder, None) bpy.context.scene.objects.link(dummy) ob.parent = dummy
def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_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 fgons, sharp edges and assigning materials ''' if not has_ngons: CREATE_FGONS = 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 fgons into tri's fgon_edges = {} # Used for storing fgon keys if CREATE_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 CREATE_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 # FGons into triangles if has_ngons and len_face_vert_loc_indices > 4: ngon_face_indices = BPyMesh_ngon(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 fgons if CREATE_FGONS: 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[key] = None # 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.faces.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.faces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces])) if verts_tex and me.faces: me.uv_textures.new() context_material_old = -1 # avoid a dict lookup mat = 0 # rare case it may be un-initialized. me_faces = me.faces for i, face in enumerate(faces): if len(face[0]) < 2: pass # raise "bad face" elif len(face[0]) == 2: if CREATE_EDGES: edges.append(face[0]) else: blender_face = me.faces[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.uv_textures[0].data[i] if context_material: image, has_data = unique_material_images[context_material] if image: # Can be none if the material dosnt have an image. blender_tface.image = image blender_tface.use_image = True if has_data and image.depth == 32: blender_tface.blend_type = 'ALPHA' # 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 CREATE_EDGES and not edges: CREATE_EDGES = False if CREATE_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]) # XXX slow # if CREATE_FGONS and fgon_edges: # for fgon_edge in fgon_edges.keys(): # for ed in me.edges: # if edges_match(fgon_edge, ed.vertices): # ed.is_fgon = True # if CREATE_FGONS and fgon_edges: # FGON= Mesh.EdgeFlags.FGON # for ed in me.findEdges( fgon_edges.keys() ): # if ed is not None: # me_edges[ed].flag |= FGON # del FGON # 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 me.update(calc_edges=CREATE_EDGES) # me.calcNormals() ob = bpy.data.objects.new("Mesh", 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) group.add(group_indices, 1.0, 'REPLACE')