WPF 使用WavefrontObjLoader类显示obj格式的三维图元
前言:毕业设计中需要用WPF展示三维图元,不适合使用XAML也不方便用Blend。于是在网上搜索相关内容找到一些资料,主要参考以下两位的博客:
http://www.cnblogs.com/enjoyeclipse/archive/2012/03/21/2410439.html
http://blog.sina.com.cn/s/blog_633d0e170100yte3.html
总结如下(18::2—20:00):
1.环境:vs2010,使用pro/e生成的obj模型,网上下载的WavefrontObjLoader.cs代码(前面给出的第一个文章中有下载http://www.cnblogs.com/enjoyeclipse/archive/2012/03/21/2410439.html)。
2.步骤:
vs2010中创建wpf项目,MainWindow.xaml的XAML代码如下
MainWindow。xaml
1 <Window x:Class="TestWpfObjLoader.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="445" Width="678"> 5 <Grid x:Name="lay"> 6 <Viewport3D x:Name="vp" Margin="0,0,12,0"> 7 </Viewport3D> 8 <Slider Height="23" HorizontalAlignment="Left" Margin="220,288,0,0" Name="slider1" VerticalAlignment="Top" Width="100" Maximum="2000" /> 9 <Slider Height="23" HorizontalAlignment="Left" Margin="49,288,0,0" Name="slider2" VerticalAlignment="Top" Width="100" Maximum="1000" /> 10 <Slider Height="23" HorizontalAlignment="Left" Margin="367,288,0,0" Name="slider3" VerticalAlignment="Top" Width="100" Minimum="200" Maximum="2000" /> 11 <Slider Height="23" HorizontalAlignment="Left" Margin="528,288,0,0" Name="slider4" VerticalAlignment="Top" Width="100" Minimum="200" Maximum="2000" /> 12 </Grid> 13 </Window>
解决方案中加入下载的WavefrontObjLoader.cs文件。
打开WavefrontObjLoader,在WavefrontObjLoader类之前定义类:
ModelVisual3DWithName
public class ModelVisual3DWithName : ModelVisual3D { public string Name { get; set; } public object Tag { get; set; } }
在MainWindow.xaml.cs中增加几个命名空间的引用:如下图所示分别是三维、动画、和WavefrontObjLoader的名称空间。
MainWindow.xaml.cs完整代码:
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; 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.Navigation; using System.Windows.Shapes; using System.Windows.Media.Media3D; using System.Windows.Media.Animation; using Bridge_WPF.UserControls; namespace TestWpfObjLoader { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> /// public partial class MainWindow : Window { PerspectiveCamera myPCamera; DirectionalLight myDirectionalLight; Model3DGroup myModel3DGroup; WavefrontObjLoader wfl; ModelVisual3DWithName mv3dw; public MainWindow() { InitializeComponent(); wfl = new WavefrontObjLoader(); slider1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider1_ValueChanged); slider2.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider2_ValueChanged); slider3.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider3_ValueChanged); slider4.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider4_ValueChanged); createCamera(); createLight(); createModel3D(); create360(); //createAnimation(); } #region //光源 private void createLight() { myDirectionalLight = new DirectionalLight(); myDirectionalLight.Color = Colors.White; myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61); } #endregion #region //摄像机 private void createCamera() { myPCamera = new PerspectiveCamera(); //myPCamera.Position = new Point3D(0,-1743,-4000);//看的方向 myPCamera.Position = new Point3D(0, 0, 1000); myPCamera.LookDirection = new Vector3D(0, 0, -1000);//摄影机看的方向 myPCamera.UpDirection = new Vector3D(0, 1, -0); myPCamera.FieldOfView = 45;//法向量摄影机上下颠倒,左转右转 myPCamera.NearPlaneDistance = 0.1; myPCamera.FarPlaneDistance = 11050; vp.Camera = myPCamera; } #endregion #region //模型 private void createModel3D() { myModel3DGroup = new Model3DGroup(); myModel3DGroup.Children.Add(myDirectionalLight); var m = wfl.LoadObjFile(@"D:prt0006.obj");//此处为obj文件的路径 m.Content = myModel3DGroup; vp.Children.Add(m); } #endregion #region //360旋转动作 RotateTransform3D rtf3D; AxisAngleRotation3D aar; private void create360() { rtf3D = new RotateTransform3D(); aar = new AxisAngleRotation3D(); this.RegisterName("myAngleRotation", aar); aar.Angle = 0; aar.Axis = new Vector3D(0, 3, 0); rtf3D.Rotation = aar; myModel3DGroup.Transform = rtf3D; myPCamera.Transform = rtf3D; } Storyboard sbd; DoubleAnimation dan; private void createAnimation() { sbd = new Storyboard(); dan = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(10))); dan.RepeatBehavior = RepeatBehavior.Forever; Storyboard.SetTargetName(dan, "myAngleRotation"); Storyboard.SetTargetProperty(dan, new PropertyPath(AxisAngleRotation3D.AngleProperty)); sbd.Children.Add(dan); sbd.BeginTime = TimeSpan.FromSeconds(5);//开始时间 sbd.Begin(this); } #endregion void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value); } void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value); } void slider3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value); } void slider4_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { aar.Angle = slider4.Value; } } }
运行效果:
后记:任务完成,接下来研究一下代码。