Java 解析立体光刻(STL)文件时验证标记顺序

Java 解析立体光刻(STL)文件时验证标记顺序,java,parsing,Java,Parsing,我想解析ASCII格式的立体光刻文件(STL),但我在这方面有一些问题 现在,文件必须遵循某种格式: solid [NAME] facet normal [NX] [NY] [NZ] outer loop vertex [P1X] [P1Y] [P1Z] vertex [P2X] [P2Y] [P2Z] vertex [P3X] [P3Y] [P3Z] endloop end

我想解析ASCII格式的立体光刻文件(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]
我可以使用
Scanner
plus
BufferedReader
读取这些文件。我还可以确定给定的参数(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();
}
根据STL规则判断,这非常简单,您只需要检查标记父项

有几种方法:

  • 设置映射以存储有效的父级
  • 使用类似于
    isValidParent(标记名)
  • 简单的if-else方法
Map似乎是最简单的一个(至少我们只有一个允许的父项):


你的代码怎么了?您正在循环中检查遇到的每个结束标记是否与开始标记堆栈的顶部匹配。这是验证标记顺序的正确算法。例如:实体顶点顶点顶点刻面法线端面外环endloop endsolid这将是有效的,尽管标记完全混乱。是否有一个规则列表,可以将哪些标记包括在其他标记中?像?我不知道。我所拥有的只是维基百科告诉我的:现在这很有趣,谢谢!事实上,我想知道为什么我没有想出这样的想法,因为我已经做了类似的事情。。。你知道的。。。看森林里的树…:(啊,我看到第一个元素(SOLID)实际上没有父元素(null)仍然存在某种问题。因为它是第一个标记,堆栈是空的,所以
String parent=openingTags.peek();
将无法工作。哦,我想peek()将为空堆栈返回null。在这种情况下,您需要额外检查实体。是的,使用一个简单的if语句进行检查。但还有一个问题:)实际上它确实识别实体刻面外部的第一个“圆”,但在此之后(当另一个刻面开始时),堆栈顶部的最后一个项目是“外部”(我省略了顶点)而且,由于outer不能是facet的父级,因此该方法返回false.sry,从而忽略了您的注释。您需要在相应的
closingTag
之后删除
openingTag
的顶部元素以保持有效状态。
solid
vertex
vertex 
vertex 
    facet normal
    endfacet
    outer loop 
    endloop
endsolid
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));
}