使用Python按块解析文件,并从每个块中提取信息

2024-10-04 07:32:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解析vrml文件中的一些文本块。具体地说,我对indexedfaceset中包含的信息感兴趣,它表示由其坐标点(field points)和点之间的连通性(field coordIndex)定义的一系列三角形。在

我已经成功地创建了一个函数来解析文本的单个indexedFaceSet(第一个),但是我无法理解如何修改代码,以便可以为每个indexedFaceSet存储以下列表[translate,verts,facets,normals]。在

我的职能是:

def extractDataFromVRML(root):
    #Lists to be populated
    translate=[]
    verts=[]
    facets=[]
    normals=[]
    #Parsing the vrml file
    f=open(root+'.wrl')
    while 1:# skip through initial stuff
      linney=str.split(f.readline())
    # print linney
      if len(linney) == 4:
        if linney[0] == 'translation': #Not shown in th vrml example
          transx = float(linney[1])
          transy = float(linney[2])
          transz = float(linney[3])
          t=[transx,transy,transz]
          translate.append(t)
      if linney == ['point', '[']:
        break
    #print 'Reading vertex coordinates.'
    while 1:
      xyz = f.readline()
      i = str.find(xyz,',')
      if i < 0:    # end of vertex coordinates
        break
      verts.append(xyz[:i]) # building a list of xyz strings
    print ('We have',len(verts)-1,'vertices.')
    #for v in verts: print v
    print ('Reading triangles.')
    while 1:
      linney=f.readline()
      if linney == '}\n':
        break     # end of file
      abc = str.split(str.replace(linney,',',' ')) # l of vertex ids
      if len(abc) < 3:
        continue   # separation between groups of triangles
      # look up a vertex in the list to generate a triangle tuple
      xyz = str.split(verts[int(abc[0])])
      p1=[float(xyz[0]),float(xyz[1]),float(xyz[2])]     
      xyz = str.split(verts[int(abc[1])])
      p2=[float(xyz[0]),float(xyz[1]),float(xyz[2])]     
      xyz = str.split(verts[int(abc[2])])
      p3=[float(xyz[0]),float(xyz[1]),float(xyz[2])]     
      tri=[p1,p2,p3]
      facets.append(tri)
      #n=getNormals(p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],p3[0],p3[1],p3[2])
      #normals.append(n)
    print ('END')
    return [translate,verts,facets,normals]

vrml中的立方体示例如下:

^{pr2}$

Tags: ofiffloattranslatesplitabcprintp2
1条回答
网友
1楼 · 发布于 2024-10-04 07:32:18

这是一个非常重要的解析问题。如果您能找到一些Python包进行解析,那就最好了。我的方法是:逐行扫描文件。如果我看到我理解的东西,那么将剩余的行传递给该块的解析器。例如,我有解析器来解析以“geometry IndexedFaceSet”行开头的块。在

import itertools
import json
import logging
from pprint import pprint
import os

# For the next line, use logging.WARN to turn off debug print, use
# logging.DEBUG to turn on
logging.basicConfig(level=os.getenv('LOGLEVEL', logging.WARN))
logger = logging.getLogger(__name__)


def skip_pass(marker, lines):
    """
    Skip until reach the line which contains the marker, then also skip
    the marker line
    """
    result = itertools.dropwhile(
        lambda line: marker not in line,  # Condition
        lines)                            # The lines
    next(result)                          # skip pass the marker
    return result

def take(marker, lines):
    """
    Take and return those lines which contains a marker
    """
    result = itertools.takewhile(
        lambda line: marker in line,      # Condition
        lines)                            # The lines
    return result

def parse_indexed_face_set(translate, lines):
    """
    Parse one block of 'geometry IndexedFaceSet'
    """
    # lines = skip_pass('geometry IndexedFaceSet', lines)

    # Parse the "point" structure
    lines = skip_pass('point', lines)
    point_lines = take(',', lines)
    verts = [[float(token) for token in line.strip(',\n').split()] for line in point_lines]
    logger.debug('verts: %r', verts)

    # parse the coordIndex structure
    lines = skip_pass('coordIndex', lines)
    coor_lines = take(',', lines)
    coord_index = [tuple(int(token) for token in line.strip(',\n').split(',')) for line in coor_lines]
    logger.debug('coord_index: %r', coord_index)

    facets = [[verts[i] for i in indices[:3]] for indices in coord_index]
    logger.debug('facets: %r', facets)

    return dict(vert=verts, facets=facets, translate=translate, normals=[])

def parse_translate(line):
    """
    Given a line such as: "translate 5 6 7", return [5.0, 6.0, 7.0]
    """
    translate = [float(x) for x in line.split()[1:4]]
    return translate

def extractDataFromVRML(root):
    indexed_face_sets = []
    translate = []
    with open(root + '.wrl') as infile:
        for line in infile:
            if 'geometry IndexedFaceSet' in line:
                a_set = parse_indexed_face_set(translate=translate, lines=infile)
                indexed_face_sets.append(a_set)
            elif 'translation' in line and line.split()[0] == 'translation':
                translate = parse_translate(line)

    return indexed_face_sets


# main
indexed_face_sets = extractDataFromVRML('root')
for a_set in indexed_face_sets:
    print('vert:', a_set['vert'])
    print('facets:', a_set['facets'])
    print(' -')

输出

^{pr2}$

注释

  • 在开发过程中,为了调试,我经常需要打印一些值。为此,我使用logger对象,它是从logging库创建的
  • 我使用itertools.takewhile()itertools.dropwhile()函数来简化一些任务

相关问题 更多 >