c# – 使用wpf 3D图形将3D模型显示为3D网格对象

c# – 使用wpf 3D图形将3D模型显示为3D网格对象,第1张

概述我正在使用3D Wpf Graphics开发C#.Net平台. 以下是代码流程如下: 1)我从kinect获取深度数据并将其赋予一个计算3d点的函数. private void display3DView() { while(loop_run) { using ( DepthImageFrame depthFrame = sensor.DepthStream.Open 我正在使用3D Wpf Graphics开发C#.Net平台.
以下是代码流程如下:

1)我从kinect获取深度数据并将其赋予一个计算3d点的函数.

private voID display3DVIEw()

{    while(loop_run)    {       using ( DepthImageFrame depthFrame = sensor.DepthStream.OpenNextFrame(1000))      {             if (depthFrame  == null)  continue;            Point3DCollection PointCloud ;            depthFrame.copyDepthImagePixelDataTo(this.depthImagePixels);            float[,] ImageArray = new float[320,240];            short [,] depth = new short[240,320];             for (int i = 0; i < 240; i++)            {              for (int j = 0; j <320; j++)              {                depth[i,j]= depthImagePixels[j+i *320].Depth;                 ImageArray[i,j] =(float)depth[i,j]/(float)1000;             }           }          PointCloud =Calculate_PointCloud(ImageArray);           viewmodel(PointCloud);           }      }     }</i>

2)我用Kinect Camera的摄像机参数和深度数据计算了3D点

  

private Point3DCollection Calculate_PointCloud(float [,] ImageArray)
   {

Point3DCollection PointCloud = new Point3DCollection();    float x_coodinate;``    float y_coordinate;    float z_coordinate;    float thresholdvalue = 2.0f;    for (int i = 0; i < 239; ++i)    {        for (int j = 0; j < 319; ++j)        {            if (Math.Abs(ImageArray[i,j] - ImageArray[i,j + 1]) < thresholdvalue && Math.Abs(ImageArray[i,j] - ImageArray[i + 1,j]) < thresholdvalue && Math.Abs(ImageArray[i,j + 1] - ImageArray[i + 1,j]) < thresholdvalue)            {                z_coordinate = ImageArray[i,j];                x_coodinate = ((j - this.PrincipalPointX) * z_coordinate) / FocalLengthX;                y_coordinate = ((i - this.PrincipalPointY) * z_coordinate) / FocalLengthY;                Point3D point1 = new Point3D(x_coodinate,y_coordinate,z_coordinate);                PointCloud.Add(point1);                z_coordinate = ImageArray[i,j + 1];                x_coodinate = (((j + 1) - this.PrincipalPointX) * z_coordinate) / FocalLengthX;                y_coordinate = ((i - this.PrincipalPointY) * z_coordinate) / FocalLengthY;                Point3D point2 = new Point3D(x_coodinate,z_coordinate);                PointCloud.Add(point2);                z_coordinate = ImageArray[i + 1,j];                x_coodinate = ((j - this.PrincipalPointX) * z_coordinate) / FocalLengthX;                y_coordinate = (((i + 1) - this.PrincipalPointY) * z_coordinate) / FocalLengthY;                Point3D point3 = new Point3D(x_coodinate,z_coordinate);                PointCloud.Add(point3);              }            }        }    return PointCloud;}</i>

3)在这里,我转换为具有每个3D点的法线信息的三角形集合,并将这些三角形给予3D网格对象并使用vIEwport3D控件渲染3d网格对象

         private voID viewmodel(Point3DCollection points)

{               Directionallight Dirlight1 = new Directionallight();            Dirlight1.color = colors.White;            Dirlight1.Direction = new Vector3D(1,1,1);           PerspectiveCamera Camera1 = new PerspectiveCamera();           Camera1.FarPlanedistance = 8000;          Camera1.NearPlanedistance = 100;          Camera1.FIEldOfVIEw = 10;          Camera1.position = new Point3D(0,1);          Camera1.LookDirection = new Vector3D(-1,-1,-1);          Camera1.UpDirection = new Vector3D(0,0);           bool combinedvertices = true;          TriangleModel Triatomesh = new TriangleModel();          MeshGeometry3D tmesh = new MeshGeometry3D();          GeometryModel3D msheet = new GeometryModel3D();          Model3DGroup modelGroup = new Model3DGroup();          ModelVisual3D modelsVisual = new ModelVisual3D();          VIEwport3D myVIEwport = new VIEwport3D();         for(int i =0; i<points.Count; i+=3)        {            Triatomesh.addTriangletoMesh(points[i],points[i + 1],points[i + 2],tmesh,combinedvertices);         }        msheet.Geometry = tmesh;       msheet.Material = new DiffuseMaterial(new SolIDcolorBrush(colors.White));       modelGroup.Children.Add(msheet);       modelGroup.Children.Add(Dirlight1);       modelsVisual.Content = modelGroup;       myVIEwport.IsHitTestVisible = false;      myVIEwport.Camera = Camera1;       myVIEwport.Children.Add(modelsVisual);       canvas1.Children.Add(myVIEwport);       myVIEwport.Height = canvas1.Height;       myVIEwport.WIDth = canvas1.WIDth;       Canvas.Settop(myVIEwport,0);       Canvas.Setleft(myVIEwport,0); } </i>

4)这是一个函数,它通过计算每个3D点的法线来获取三个3D点并将三维网格对象添加为三角形

public  voID addTriangletoMesh(Point3D p0,Point3D p1,Point3D p2,MeshGeometry3D mesh,bool combine_vertices)      {        Vector3D normal = Calculatenormal(p0,p1,p2);        if (combine_vertices)        {            addPointCombined(p0,mesh,normal);            addPointCombined(p1,normal);            addPointCombined(p2,normal);        }        else        {            mesh.positions.Add(p0);            mesh.positions.Add(p1);            mesh.positions.Add(p2);              //mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);           // mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);           // mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);            mesh.normals.Add(normal);            mesh.normals.Add(normal);            mesh.normals.Add(normal);        }    }public  Vector3D Calculatenormal(Point3D P0,Point3D P1,Point3D P2)   //static    {        Vector3D v0 = new Vector3D(P1.X - P0.X,P1.Y - P0.Y,P1.Z - P0.Z);        Vector3D v1 = new Vector3D(P2.X - P1.X,P2.Y - P1.Y,P2.Z - P1.Z);        return Vector3D.Crossproduct(v0,v1);    } public  voID addPointCombined(Point3D point,Vector3D normal)      {        bool found = false;        int i = 0;        foreach (Point3D p in mesh.positions)        {            if (p.Equals(point))            {                found = true;                mesh.TriangleIndices.Add(i);                mesh.positions.Add(point);                mesh.normals.Add(normal);                break;            }            i++;        }        if (!found)        {            mesh.positions.Add(point);            mesh.TriangleIndices.Add(mesh.TriangleIndices.Count);            mesh.normals.Add(normal);        }}

5)这是我的XAML代码

<Window x:Class="PointCloud3DVIEw.MainWindow"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    title="PointCloud" Height="653" WIDth="993" Background="Black" Loaded="Window_Loaded"><GrID Height="1130" WIDth="1626">    <Canvas Height="611" HorizontalAlignment="left" name="canvas1" VerticalAlignment="top"

宽度=“967”背景=“黑色”/>

</GrID>

问题是我无法在Wpf Screen中显示3D模型.请问任何人都可以浏览整个代码吗?并让我明白我哪里出错了?并建议我纠正.
提前致谢

解决方法 我已经在几周内尝试了WPF 3D并且学到了一些难以理解的东西:)
我现在没有时间检查并尝试整个代码.但是我会尝试三件事:

>我不确定你的相机的方向.它在(0,0),
使用矢量(-1,-1)查找,这意味着它专注于中心
点(-1,-1).这有点奇怪……尝试定位相机
进一步(取决于您的模型的规模),如(0,10,0)或甚至
进一步将其集中在(0,0)或你的中心点的任何地方
模型是:

Camera1.position = new Point3D(0,0);
Camera1.LookDirection = new Point3D(0,0) – Camera1.position;
>同时移除定向灯(因为它使用法线,如果它们出错则不会显示任何内容)并尝试环境光.和你的
    定向闪电与您的外观正好相反
    方向(-1,-1)和(1,1).
>尝试在三角形索引中交换点的顺序(WPF仅渲染网格的一侧,因此模型可能在那里但内部/外部) –
    而不是0,2尝试0,2,1;

如果没有任何帮助,我会在回家后尝试你的代码.

/稍后编辑/
在简单的三角形上编写你的代码并根据我的提示重写它并且它有效.有一些评论和两个提示如何清理你的代码:)

private voID viewmodel(Point3DCollection points)    {        Directionallight Dirlight1 = new Directionallight();        Dirlight1.color = colors.White;        Dirlight1.Direction = new Vector3D(1,1);        PerspectiveCamera Camera1 = new PerspectiveCamera();        Camera1.FarPlanedistance = 8000;        //Camera1.NearPlanedistance = 100; //close object will not be displayed with this option        Camera1.FIEldOfVIEw = 10;           //Camera1.position = new Point3D(0,1);        //Camera1.LookDirection = new Vector3D(-1,-1);        Camera1.position = new Point3D(0,10);        Camera1.LookDirection = new Point3D(0,0) - Camera1.position; //focus camera on real center of your model (0,0) in this case        Camera1.UpDirection = new Vector3D(0,0);        //you can use constructor to create Camera instead of assigning its propertIEs like:        //PerspectiveCamera Camera1 = new PerspectiveCamera(new Point3D(0,10),new Vector3D(0,-1),10);        bool combinedvertices = true;        TriangleModel Triatomesh = new TriangleModel();        MeshGeometry3D tmesh = new MeshGeometry3D();        GeometryModel3D msheet = new GeometryModel3D();        Model3DGroup modelGroup = new Model3DGroup();        ModelVisual3D modelsVisual = new ModelVisual3D();        VIEwport3D myVIEwport = new VIEwport3D();        for (int i = 0; i < points.Count; i += 3)        {            Triatomesh.addTriangletoMesh(points[i + 2],points[i],combinedvertices);                            //I dID swap order of vertexes you may try both options with your model                       }        msheet.Geometry = tmesh;        msheet.Material = new DiffuseMaterial(new SolIDcolorBrush(colors.White));        //you can use constructor to create GeometryModel3D instead of assigning its propertIEs like:        //msheet = new GeometryModel3D(tmesh,new DiffuseMaterial(new SolIDcolorBrush(colors.White)));                     modelGroup.Children.Add(msheet);        //use AMbIEntlight instead of directional        modelGroup.Children.Add(new AmbIEntlight(colors.White));        modelsVisual.Content =  modelGroup;        myVIEwport.IsHitTestVisible = false;        myVIEwport.Camera = Camera1;        myVIEwport.Children.Add(modelsVisual);        canvas1.Children.Add(myVIEwport);        myVIEwport.Height = canvas1.Height;        myVIEwport.WIDth = canvas1.WIDth;        Canvas.Settop(myVIEwport,0);        Canvas.Setleft(myVIEwport,0);    }

我使用Points3DCollection作为参数(而不是Kinect输入):

Point3DCollection points = new Point3DCollection();    points.Add(new Point3D(0.5,0.5));    points.Add(new Point3D(0.5,-0.5,-0.5));    points.Add(new Point3D(-0.5,-0.1,-0.5));    viewmodel(points);
总结

以上是内存溢出为你收集整理的c# – 使用wpf 3D图形将3D模型显示为3D网格对象全部内容,希望文章能够帮你解决c# – 使用wpf 3D图形将3D模型显示为3D网格对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1230487.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存