C# 从点云到实体网格

C# 从点云到实体网格,c#,.net,graphics,3d,C#,.net,Graphics,3d,我一直在尝试将一组复杂的点渲染成三维可视化。我有一组层,每个层都有一些多边形,每个多边形都有不同数量的点 我已经玩了很多.NET库(OpenGL、DirectX和其他的包装器),最终使用Helix工具箱实现了超级简单的WPF 3D控件,只是为了渲染3D点云可视化。我的超级简单代码如下所示: private void Render3D(List<Layer> layers) { var layerIndex = 0; var pts = new Point3DCollectio

我一直在尝试将一组复杂的点渲染成三维可视化。我有一组层,每个层都有一些多边形,每个多边形都有不同数量的点

我已经玩了很多.NET库(OpenGL、DirectX和其他的包装器),最终使用Helix工具箱实现了超级简单的WPF 3D控件,只是为了渲染3D点云可视化。我的超级简单代码如下所示:

private void Render3D(List<Layer> layers) {
  var layerIndex = 0;
  var pts = new Point3DCollection();

  foreach (var layer in layers) {
    foreach (var shape in layer.Shapes) {
      foreach (var point in shape.Points) {
        pts.Add(new Point3D(point.Item1, point.Item2, layerIndex * .5));
      }
    }
    layerIndex++;
  }

  var vis = new PointsVisual3D() { Points = pts };
  _viewport.Children.Add(vis);
}
private void Render3D(列出图层){
var layerIndex=0;
var pts=new Point3DCollection();
foreach(层中的var层){
foreach(层中的变量形状。形状){
foreach(形状中的变量点。点){
增加(新点3D(点1、点2、层索引*.5));
}
}
layerIndex++;
}
var vis=new Points visual3d(){Points=pts};
_viewport.Children.Add(vis);
}
我的XAML如下所示:

<Window xmlns:h="http://helix-toolkit.org/wpf">
  <h:HelixViewport3D Name="_viewport">
    <h:SunLight />
  </h:HelixViewport3D>
</Window>

此代码的结果以及我安排的数据如下:

<Window xmlns:h="http://helix-toolkit.org/wpf">
  <h:HelixViewport3D Name="_viewport">
    <h:SunLight />
  </h:HelixViewport3D>
</Window>

这太棒了,我非常兴奋能在3D中看到我的数据,但我想更进一步,从我的点数据开始绘制实体形状,有点像这样:

private void Render3D(List<Layer> layers) {
  var layerIndex = 0;
  var pts = new Point3DCollection();

  foreach (var layer in layers) {
    foreach (var shape in layer.Shapes) {
      foreach (var point in shape.Points) {
        pts.Add(new Point3D(point.Item1, point.Item2, layerIndex * .5));
      }
    }
    layerIndex++;
  }

  var vis = new PointsVisual3D() { Points = pts };
  _viewport.Children.Add(vis);
}


我使用的是.NET,如果可能的话,我希望能坚持使用这个平台,但我愿意接受其他想法。希望这是不可知的,足以得到一个明确的答案。

这实际上取决于您拥有的点数据集。 一种稳健的重建方法是ths Marching cubes(或Marching tetras)算法。 但是如果你的数据集已经组织好了,我想是以层的形式,很明显像下面的。

然后可以使用一些更简单的方法。在这种情况下,我会这样做: -从订购图层开始。 -创建一个“for”循环,该循环通过两层两层:

Mesh MyMesh = new Mesh();
for (int i = 0; i< layers.Count -1; i++)
{
 Expand(layers[i+1]);
 Dictionary<int[],Point[]> localMesh = project(layers[i], layers[i+1]
 MyMesh.AddTriangles( Delaunay2D(localMesh));
}
Mesh MyMesh=new Mesh();
对于(int i=0;i
“展开”功能只是垂直于图层法线稀疏数据点。(以避免两个图层之间的重叠点) 投影功能在同一平面上投影两个连续层的点,以便可以执行Delaunay三角剖分。字典允许您跟踪投影层和“真实层”之间的点索引。 最后使用Delaunay算法创建三角形(并使用字典从索引中获取“真实”坐标)

只要稍微改进一下代码,循环就可以非常短,计算时间也可以非常短


希望这对其他人有所帮助。

您获得了体积数据或只是曲面点?一些样本将是一个好主意,可以共享(不必太大,只需一部分)理想的ASCII格式,因此任何人都可以毫无问题地阅读它,也不需要一些lib@Spektre我只有表面点——没有体积数据。我手边没有数据,但下班后我可以把一些放在网上。每个点都只是一组x,y坐标。z坐标是用一个常数乘以图层的索引来设计的。我很乐意一个简化的版本,甚至可能只是一组点的立方体或四面体。不,你需要一个有效的样本,这样你的形状的某些部分就足够了(甚至切割)。这是创建点拓扑图,将邻域映射到一些
u,v
坐标(网格)然后做一个三角形条切片…当你把坐标直接对齐到网格上时,你需要一次处理两个切片,就像这样:但我怀疑你的数据和大多数扫描仪一样具有各向同性点密度,所以可能有更简单的解决方案…据我所知,你的点代表t曲面的样本。如果是这样,您要做的就是曲面重建,这是一个完整的研究领域。只需选择一种适合您的场景和数据的重建方法。例如,泊松曲面重建应用非常广泛(但它需要曲面法线).或者,如果它们不代表表面样本,而您只是想将它们可视化为某种管或球,请查看。