在解析Stereolithography(STL)文件时验证标签顺序

时间:2015-05-25 11:39:52

标签: java parsing

我想解析以ASCII格式提供的Stereolithography-Files(STL),但我遇到了一些问题。

现在,文件必须遵循某种格式:

solid [NAME]
    facet normal [NX] [NY] [NZ]
        outer loop 
            vertex [P1X] [P1Y] [P1Z]
            vertex [P2X] [P2Y] [P2Z]
            vertex [P3X] [P3Y] [P3Z]
        endloop
    endfacet
    ... + more facet-endfacet blocks
endsolid [NAME]

我可以使用ScannerBufferedReader来阅读这些文件。我也没有问题来确定给定的参数(P1X,P1Y等)是否存在以及它们是否有效或者甚至它是否是STL文件。

我的主要问题是我真的不知道如何确定标签的顺序是否正确。现在,我只能确定所有标签是否正确关闭(每个开口标签都有一个结束标签)。这是代码:

private static boolean areTagsBalanced()
{
    HashMap<String, String> tagPairs = new HashMap<String, String>();
    tagPairs.put(SOLID, ENDSOLID);
    tagPairs.put(FACET, ENDFACET);
    tagPairs.put(OUTER, ENDLOOP);

    Stack<String> openingTags = new Stack<String>();
    HashSet<String> closingTags = new HashSet<String>(tagPairs.values());

    for (int i=0; i<fileContent.size(); i++)
    {
        if (tagPairs.containsKey(fileContent.get(i)))
        {
            openingTags.push(fileContent.get(i));
        }
        else if (closingTags.contains(fileContent.get(i)))
        {
            if (openingTags.isEmpty() || !fileContent.get(i).equals(tagPairs.get(openingTags.pop())))
            {
                return false;
            }
        }
    }
    return openingTags.isEmpty();
}

如您所见,代码不关心在文件中找到标记的顺序。也许某人对我有一些意见。谢谢!

P.S:

我需要检查标签的正确顺序,我的代码会将此代码标记为有效,尽管标签的顺序完全搞砸了:

solid
vertex
vertex 
vertex 
    facet normal
    endfacet
    outer loop 
    endloop
endsolid

1 个答案:

答案 0 :(得分:1)

根据wiki判断STL规则非常简单,只需要检查标记为父级。

有几种方法:

  • 设置地图以存储有效的父母
  • 使用isValidParent(Tag name)
  • 等方法将标记类型设为枚举
  • 直截了当的if-else方法。

地图似乎是最简单的(至少在我们只有一个允许的父项时):

Map<String, String> parents = new HashMap<>();
parents.put(SOLID, null);
parents.put(FACET, SOLID);
parents.put(OUTER, FACET);
parents.put(VERTEX, OUTER);

然后在循环中检查每个新开始标记的父级:

if (tagPairs.containsKey(fileContent.get(i))) {
    // current top of the stack is a parent for new opening tag 
    String parent = openingTags.peek(); 
    if (!parents.get(fileContent.get(i)).equals(parent)) {
        return false;
    }
    openingTags.push(fileContent.get(i));
}