[WPF VTK]三维图形开发基础(二)
0.虚空假面
下面是本人学习的一些资源链接,有一些资源在前面文章已经提供下载,如果已经下载请筛选后再选择下载。
WPF 3D 模型实例
http://download.csdn.net/detail/csucyb/4991634
百度云资源
http://pan.baidu.com/share/link?shareid=233388&uk=3859191502
1.积点成型
前面介绍了Camera、Lighting、Materials,现在介绍一下Geometry。
Geometry控制了我们说要显示的物体,对于一个三维显示的嵌套结构我们可以从前面介绍的XAML来了解。
因为一个XAML如果完整地呈现了一个物体那么其所具有的元素就都是存在的。
先来介绍决定说显示模型的点、三角两个元素。
Positions:三维点序列
TriangleIndices:三维点序列中用来构成三角形的点组合,比如有
(1,1,1)(2,2,2)(3,3,3)(4,4,4)四个点以及(0 1 2)(1 0 4)两组点序列那么就代表由0 1 3三个点构成一个三角形元素以及1 3 4构成另外一个三角形元素。
那么为什么是要三角形元素呢?
因为在三维显示中三角形是其组成基本元素,也就是说所有图形不管你是圆是方式大是小是康熙还是韦小宝都需要一刀刀切割成三角形才可以崭露头角。
而三角序列中的点顺序就代表了点组成三角形的方向。
例如下图就是一个点、三角序列的示意图。
再比如现在有:(Point3DCollection是存储点元素的类型)
Point3DCollection npc = new Point3DCollection();
npc.Add(new Point3D(0, 0, 0));
npc.Add(new Point3D(2, 0, 0));
npc.Add(new Point3D(0, 2, 0));
三个点,你可以用0,1,2组成一个面(逆时针为正面),x轴为向右,y轴向上,z轴正对屏幕朝向用户
用0,2,1组成
这里体现出了2个同样的面但是不同颜色,因为在这里我设置了界面的材质,正面为red背面为black
DiffuseMaterial dm = new DiffuseMaterial();
dm.Brush = Brushes.Red;
gm.Geometry = meshg;
gm.Material = dm;
gm.BackMaterial = new DiffuseMaterial(Brushes.Black);
因此相同的点不同顺序构成说反映的效果是不同的.
2. XAML实例解析
请阅读下面XAML并根据前面说掌握知识观察下面实例,由于XAML的嵌套关系明显因此不难理解,所以如果自己也设置模型可以根据实例来拼凑元素。
// 通过x:Name可以对元素进行标记用于选取或者设置
// 第一层一个Viewport3D
<Viewport3D x:Name="Rectangle">
// ModelVisual3D <ModelVisual3D>
// ModelVisual3D的content,注意一个元素通常只能拥有一个content <ModelVisual3D.Content>
// 注意这里有一个Model3DGroup说明里面可以添加一系列的平行的元素 <Model3DGroup>
// 重点到了 GeometryModel3D <GeometryModel3D>
// 拥有一个Geometry元素 <GeometryModel3D.Geometry> <!--Positions="0 1 -4, 0 0 -4, 0 1 0, 0 0 0"--> <!-- Rectangle. -->
// 一个Mesh拥有Positions以及TriangleIndices
// Positions代表了组成模型的点元素,TriangleIndices代表由这里面的点组成的三角的点序列
// 比如0 1 2代表由0、1、2三个点来组成一个三角形,如果这里没有出现的点元素那么就不会显示 <MeshGeometry3D Positions="0 0 0, 2 0 0, 0 2 0, 2 2 0" TriangleIndices=" 0 1 2" /> </GeometryModel3D.Geometry> // 材质属于GeometryModel3D <GeometryModel3D.Material> <DiffuseMaterial Brush="Cyan" /> </GeometryModel3D.Material> <GeometryModel3D.BackMaterial> <DiffuseMaterial Brush="Red" /> </GeometryModel3D.BackMaterial> </GeometryModel3D> <GeometryModel3D> <GeometryModel3D.Geometry> <!--Positions="0 1 -4, 0 0 -4, 0 1 0, 0 0 0"--> <!-- Rectangle. --> <MeshGeometry3D Positions="-2 -2 -2, 0 -2 -2, -2 0 -2, 0 0 -2" TriangleIndices=" 0 1 2" /> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial Brush="Cyan" /> </GeometryModel3D.Material> <GeometryModel3D.BackMaterial> <DiffuseMaterial Brush="Red" /> </GeometryModel3D.BackMaterial> </GeometryModel3D> <!-- Light source. --> <AmbientLight Color="White" /> </Model3DGroup> </ModelVisual3D.Content> </ModelVisual3D> <!-- Camera. --> <!--Position="-1 0.5 4" LookDirection="0 0 -1"--> <Viewport3D.Camera> <PerspectiveCamera Position="0 0 4" LookDirection="0 0 -1" UpDirection="15 5 1" FieldOfView="60" /> </Viewport3D.Camera> </Viewport3D>
3.C#代码示例
上面用XAML介绍了示例,现在用C#代码来实现,其实使用C#实现原理是一样的,只不过嵌套关系、元素的值需要自己手动设置而已。
实例简单这里就不做多余的注解了。相信通过这个简单的实例要自己手动编写一个三维模型是轻而易举了,不过复杂的图像要成功编写还需要注意各种层次嵌套以及
相应元素的添加,这里就是入门易深入难。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; using System.Windows.Navigation; using System.Windows.Shapes; namespace _3DUI { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { // 定义个viewPort Viewport3D vp = new Viewport3D(); public MainWindow() { InitializeComponent(); //some s = new some(); //Content = vp; SetUpCamera(); SetModelVisual3D(); } private void SetUpCamera() { PerspectiveCamera camera = new PerspectiveCamera(); camera.Position = new Point3D(-40, 40, 40); camera.UpDirection = new Vector3D(0, 0, 1); camera.LookDirection = new Vector3D(40, -40, -40); camera.FieldOfView = 90; vp.Camera = camera; } private void SetModelVisual3D() { MeshGeometry3D mesh = new MeshGeometry3D(); Point3DCollection pc = new Point3DCollection(); pc.Add(new Point3D(0, 0, 0)); pc.Add(new Point3D(10, 0, 0)); pc.Add(new Point3D(10, 10, 0)); pc.Add(new Point3D(0, 10, 0)); pc.Add(new Point3D(0, 0, 10)); pc.Add(new Point3D(10, 0, 10)); pc.Add(new Point3D(10, 10, 10)); pc.Add(new Point3D(0, 10, 10)); mesh.Positions = pc; Int32Collection ic = new Int32Collection(); ic.Add(0); ic.Add(1); ic.Add(3); ic.Add(1); ic.Add(2); ic.Add(3); ic.Add(0); ic.Add(4); ic.Add(3); ic.Add(4); ic.Add(7); ic.Add(3); ic.Add(4); ic.Add(6); ic.Add(7); ic.Add(4); ic.Add(5); ic.Add(6); ic.Add(0); ic.Add(4); ic.Add(1); ic.Add(1); ic.Add(4); ic.Add(5); ic.Add(1); ic.Add(2); ic.Add(6); ic.Add(6); ic.Add(5); ic.Add(1); ic.Add(2); ic.Add(3); ic.Add(7); ic.Add(7); ic.Add(6); ic.Add(2); mesh.TriangleIndices = ic; DiffuseMaterial dm = new DiffuseMaterial(); dm.Brush = Brushes.Red; GeometryModel3D gm = new GeometryModel3D(); gm.Geometry = mesh; gm.Material = dm; gm.BackMaterial = new DiffuseMaterial(Brushes.Cyan); DirectionalLight dl = new DirectionalLight(); dl.Color = Colors.White; dl.Direction = new Vector3D(-1, -1, -3); Model3DGroup mg = new Model3DGroup(); mg.Children.Add(dl); mg.Children.Add(gm); ModelVisual3D mv = new ModelVisual3D(); mv.Content = mg; vp.Children.Add(mv); } } }