C# 检查stl文件是否包含两个模型

C# 检查stl文件是否包含两个模型,c#,3d,computational-geometry,C#,3d,Computational Geometry,stl文件可能包含2个三维模型。是否有任何方法可以检测一个stl文件中是否存储了2个或多个模型 在我当前的代码中,它可以检测到示例中有2个模型,但也有一些实例,它检测到很多模型,即使它只有一个 三角形类结构具有包含3个点(x、y、z)的顶点 示例STL文件: 编辑:使用@Gebb的答案我就是这样实现的: private int GetNumberOfModels(列出顶点) { 顶点[][]三角形=新顶点[顶点数()/3]]; int vertIdx=0; 对于(int i=0;it)); i

stl文件可能包含2个三维模型。是否有任何方法可以检测一个stl文件中是否存储了2个或多个模型

在我当前的代码中,它可以检测到示例中有2个模型,但也有一些实例,它检测到很多模型,即使它只有一个

三角形类结构具有包含3个点(x、y、z)的顶点

示例STL文件:

编辑:使用@Gebb的答案我就是这样实现的:

private int GetNumberOfModels(列出顶点)
{
顶点[][]三角形=新顶点[顶点数()/3]];
int vertIdx=0;
对于(int i=0;it));
int vertexCount=唯一顶点计数;
//DisjointionSets类处理整数,所以我们需要一个来自顶点的映射
//到整数(其id)。
字典索引dverties=唯一顶点
Zip先生(
可枚举范围(0,vertexCount),
(v,i)=>新的{v,i})
.ToDictionary(vi=>vi.v,vi=>vi.i);
int[][]索引三角形=
三角形
.Select(t=>t.Select(v=>indexeddverties[v]).ToArray()
.ToArray();
var du=新的XYZ.view.wpf.disjointionSets(vertexCount);
//迭代由顶点ID组成的“三角形”。
foreach(indexedTriangles中的int[]三角形)
{
int vertex0=三角形[0];
//将连接组件的第0个顶点标记为连接到所有其他顶点的顶点。
foreach(三角形中的int v.Skip(1))
{
du.并集(顶点0,v);
}
}
var连接组件=
新的HashSet(Enumerable.Range(0,vertexCount).Select(x=>du.Find(x));
返回已连接的组件。计数;
}
在某些情况下,它会生成正确的输出,但对于上面的示例图像,它会输出3,而不是2。我现在正试图优化@Gebb的代码片段以使用浮点值,因为我相信浮点对于比较是必要的。有人也有办法做到这一点吗?也许我需要另一个视角


可以通过将顶点和它们之间的连接表示为一个图,并在数据结构的帮助下查找图中连接组件的数量来实现这一点

使用系统;
使用System.Collections.Generic;
利用制度全球化;
使用System.IO;
使用System.Linq;
使用System.Text.RegularExpressions;
使用Vertex=System.ValueTuple;
名称空间UnionFindSample
{
内部类析取集
{
私有只读int;
私有只读int[]\u秩;
私有只读int[]\u父级;
公共断开连接集(int n)
{
_秩=新整数[n];
_父项=新整数[n];
_n=n;
MakeSet();
}
//创建n个集合,每个集合中有单个项
公共void生成集()
{
对于(变量i=0;i<\n;i++)
//最初,所有元素都处于
//他们自己的一套。
_父[i]=i;
}
//查找集合的代表
//x是的一个元素。
公共整数查找(整数x)
{
如果(_parent[x]!=x)
{
//如果x不是它自己的父,那么x就不是它自己的代表
//他的布景。
//我们通过将x的节点直接移动到代表下来进行路径压缩
//这一套的。
_父项[x]=查找(_父项[x]);
}
返回_父项[x];
}
//统一包含x和x的集合
//包含x的集合
公共无效联合(整数x,整数y)
{
//找到两组的代表。
int xRoot=Find(x),yRoot=Find(y);
//元素在同一个集合中,不需要将任何东西联合起来。
if(xRoot==yRoot)
{
返回;
}
if(_秩[xRoot]<_秩[yRoot])
{
//然后将x移到y下,使树的深度保持等于_秩[yRoot]。
_父[xRoot]=yRoot;
}
else if(_秩[yRoot]<_秩[xRoot])
{
//然后将y移到x下,使树的深度保持等于_秩[xRoot]。
_父[yRoot]=xRoot;
}
其他的
{
//如果等级相同
//然后将y移到x下(无论哪个方向)。
_父[yRoot]=xRoot;
//并增加结果树的
//排名1
_秩[xRoot]=\u秩[xRoot]+1;
}
}
}
内部课程计划
{
私有静态void Main(字符串[]args)
{
字符串文件=args[0];
顶点[][]三角形=ParseStl(文件);
var uniqueVertices=newhashset(triangles.SelectMany(t=>t));
int vertexCount=唯一顶点计数;
//DisjointionSets类处理整数,所以我们需要一个来自顶点的映射
//到整数(其id)。
字典索引dverties=唯一顶点
Zip先生(
可枚举范围(0)
private int GetNumberOfModels(List<TopoVertex> vertices)
    {
        Vertex[][] triangles = new Vertex[vertices.Count() / 3][];

        int vertIdx = 0;
        for(int i = 0; i < vertices.Count() / 3; i++)
        {
            Vertex v1 = new Vertex(vertices[vertIdx].pos.x, vertices[vertIdx].pos.y, vertices[vertIdx].pos.z);
            Vertex v2 = new Vertex(vertices[vertIdx + 1].pos.x, vertices[vertIdx + 1].pos.y, vertices[vertIdx + 1].pos.z);
            Vertex v3 = new Vertex(vertices[vertIdx + 2].pos.x, vertices[vertIdx + 2].pos.y, vertices[vertIdx + 2].pos.z);

            triangles[i] = new Vertex[] { v1, v2, v3 };
            vertIdx += 3;
        }
        var uniqueVertices = new HashSet<Vertex>(triangles.SelectMany(t => t));
        int vertexCount = uniqueVertices.Count;
        // The DisjointUnionSets class works with integers, so we need a map from vertex
        // to integer (its id).

        Dictionary<Vertex, int> indexedVertices = uniqueVertices
            .Zip(
                Enumerable.Range(0, vertexCount),
                (v, i) => new { v, i })
            .ToDictionary(vi => vi.v, vi => vi.i);

        int[][] indexedTriangles =
            triangles
            .Select(t => t.Select(v => indexedVertices[v]).ToArray())
            .ToArray();

        var du = new XYZ.view.wpf.DisjointUnionSets(vertexCount);

        // Iterate over the "triangles" consisting of vertex ids.
        foreach (int[] triangle in indexedTriangles)
        {
            int vertex0 = triangle[0];
            // Mark 0-th vertexes connected component as connected to those of all other vertices.
            foreach (int v in triangle.Skip(1))
            {
                du.Union(vertex0, v);
            }
        }

        var connectedComponents =
            new HashSet<int>(Enumerable.Range(0, vertexCount).Select(x => du.Find(x)));
        return connectedComponents.Count;
    }