我的编程空间,编程开发者的网络收藏夹
学习永远不晚

WPF实现绘制3D图形的示例代码

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

WPF实现绘制3D图形的示例代码

WPF的3D功能可以在不编写任何c#代码的情况下进行绘制,只需要使用xaml即可完成3D图形的渲染。本文主要讲述了WPF-3D中的关键概念, 以及常用到的命中测试、2d控件如何在3D对象中进行渲染,除此之外,还演示了如何导入外部3D模型。

关键概念

视口

视口指的是图像要展示在哪里,可以理解为展示图形的舞台。在WPF中视口使用Viewport3D标签表示。

相机

如果把视口比作舞台,那相机就可以理解为观众的眼睛,不同的眼睛位置会看到不同的角度。

<Viewport3D>
    <!--相机-->
    <Viewport3D.Camera>
        <!--透视相机-->
        <PerspectiveCamera Position="8,5,10"
                           LookDirection="-7,-2,-10"
                           FarPlaneDistance="40"
                           NearPlaneDistance="10"
                           FieldOfView="60"> 
            <PerspectiveCamera.Transform>
                <RotateTransform3D CenterX="1.5" CenterY="1" CenterZ="0.5">
                    <RotateTransform3D.Rotation>
                        <AxisAngleRotation3D Angle="45" Axis="0,1,0"/>
                    </RotateTransform3D.Rotation>
                </RotateTransform3D>
            </PerspectiveCamera.Transform>
        </PerspectiveCamera>
        <!--正交相机,用法类似-->
        <!--<OrthographicCamera/>-->
</Viewport3D.Camera>

光源

没有光源也就看不到3D对象

<!--光线-->
<ModelVisual3D>
    <ModelVisual3D.Content>
        <Model3DGroup>
            <!--散射光线-->
            <AmbientLight Color="#FFF"/>
            <!--平行光-->
            <!--<DirectionalLight Color="#FFF" Direction="0,-1,0"/>-->
            <!--点光源-->
            <!--<PointLight Position="0,0,0"/>-->
            <!--锥形辐射光:手电筒-->
            <!--<SpotLight Position="0,0,0" Direction="0,0,-3"/>-->
        </Model3DGroup>
    </ModelVisual3D.Content>
</ModelVisual3D>

材质

3D几何对象只是将轮廓定义出来,表面是没有定义的,所以需要使用材质来展现出不同的物体表面。也可以理解为3D几何对象只是勾勒出物体的轮廓,而材质则是上颜色。

<ModelUIElement3D >
    <ModelUIElement3D.Model>
        <GeometryModel3D>
            <!--材质-->
            <GeometryModel3D.Material>
                <!--散射材质-->
                <DiffuseMaterial Brush="Blue"/>
                <!--镜面材质-->
                <!--<SpecularMaterial SpecularPower="1" Brush="Blue"/>-->
                <!--自发光材质-->
                <!--<EmissiveMaterial Color="Green" />-->
            </GeometryModel3D.Material>
            <GeometryModel3D.Geometry>
                <MeshGeometry3D Positions="0,0,1 0,2,1 3,2,1 3,0,1
                                           0,0,0 0,2,0 3,2,0 3,0,0"
                                TriangleIndices="2,3,7 7,6,2 1,5,4 0,1,4"/>
            </GeometryModel3D.Geometry>
        </GeometryModel3D>
    </ModelUIElement3D.Model>
</ModelUIElement3D>

3D对象

3D对象则是具体的对象,在WPF中视口使用<ModelUIElement3D>标签表示。在WPF中,图形是以三角面片作为最基本的展示单元,因为三角形是最稳定的即三个点可以确定出唯一的一个平面,任何复杂的图形都是由多个三角面片组成的。在给TriangleIndices属性赋值时,一定注意三个点的顺序。

命中测试(鼠标交互)

想要使用鼠标点击得到某个图形,可以在具体的某个3D对象中,增加MouseLeftButtonDown事件

<ModelUIElement3D MouseLeftButtonDown="ModelUIElement3D_MouseLeftButtonDown">事件中可以进行改变颜色等操作

private void ModelUIElement3D_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    ModelUIElement3D mui3d = sender as ModelUIElement3D;
    var model = mui3d.Model as GeometryModel3D;
    (model.Material as DiffuseMaterial).Brush = Brushes.Orange;
}

如果有很多3D对象,在每个具体的对象上面增加事件会很麻烦,也可以直接在Viewport3D中增加事件

<Viewport3D MouseLeftButtonDown="Viewport3D_MouseLeftButtonDown">在时间中急性转换处理

private void Viewport3D_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Viewport3D viewport3D=sender as Viewport3D; 
    Point location=e.GetPosition(viewport3D);
    HitTestResult hitTestResult=VisualTreeHelper.HitTest(viewport3D, location);
    if (hitTestResult != null)
    {
        ...//具体操作
    }
}

3D对象中2D控件渲染

如果要在3D对象中增加控件,可以使用Viewport2DVisual3D标签,实现如下图所示的效果。

<Viewport3D>
 <Viewport2DVisual3D>
    <Viewport2DVisual3D.Geometry>
        <MeshGeometry3D Positions="0,0,1 0,2,1 3,2,1 3,0,1
                       0,0,0 0,2,0 3,2,0 3,0,0"
            TriangleIndices="0,2,1 0,3,2 6,4,5 6,7,4"
            TextureCoordinates="0,1 0,0 1,0 1,1"/>
        <!--TextureCoordinates:表示的二维平面坐标,原点:左上角-->
    </Viewport2DVisual3D.Geometry>

    <Viewport2DVisual3D.Material>
        <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
    </Viewport2DVisual3D.Material>
    <Viewport2DVisual3D.Visual>
    <Border BorderThickness="1" BorderBrush="Yellow">
        <StackPanel>
            <TextBlock Text="Hello World" Foreground="Green" />
            <Button Content="Button" Click="Button_Click"/>
        </StackPanel>
    </Border>
    </Viewport2DVisual3D.Visual>
 </Viewport2DVisual3D>
<Viewport3D>

外部导入3D模型

在wpf中绘制3D模型还是非常麻烦的,在实际工作中用的比较多的是从外部导入已有的3d模型。推荐一个比较好的第三方库HelixToolKit

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        xmlns:helix="http://helix-toolkit.org/wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <helix:HelixViewport3D  Name="viewPort3d"
                                ShowViewCube="True"
            ViewCubeBackText="后" ViewCubeFrontText="前" ViewCubeHeight="100" ViewCubeWidth="100" 
            ViewCubeVerticalPosition="Bottom"
            ViewCubeHorizontalPosition="Right"
            
            ShowCoordinateSystem="True"
            CoordinateSystemLabelForeground="Red"
            CoordinateSystemHorizontalPosition="Left"
            CoordinateSystemVerticalPosition="Bottom"
            
            ShowFrameRate="True"
            
            IsViewCubeEdgeClicksEnabled="False">


            <helix:HelixViewport3D.Camera>
                <PerspectiveCamera FieldOfView="45"  
                                   LookDirection="0,0,-414.387754871885" 
                                   FarPlaneDistance="30000"
                                   NearPlaneDistance="0.1" 
                                   Position="9.9475983006414E-14,91.037123633789,414.387754871885" 
                                   UpDirection="0,1,0"/>
            </helix:HelixViewport3D.Camera>

            <helix:HelixViewport3D.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#444" Offset="0"/>
                    <GradientStop Color="#EEE" Offset="1"/>
                </LinearGradientBrush>
            </helix:HelixViewport3D.Background>
            <helix:GridLinesVisual3D Width="16000" Length="16000" Thickness="2" MinorDistance="500" MajorDistance="500" Fill="Gray" />

            <!--很重要,没有灯光场景是黑的-->
            <helix:DefaultLights/>

            <ModelVisual3D x:Name="model"></ModelVisual3D>

        </helix:HelixViewport3D>
    </Grid>
</Window>
namespace WpfApp2
{
    public partial class MainWindow : Window
    {
        List<string> modelPaths = new List<string>();
        string basePath = AppDomain.CurrentDomain.BaseDirectory + "\\ModelFiles\\";
        public MainWindow()
        {
            InitializeComponent();
            modelPaths.Add("IRB4600_20kg-250_LINK1_CAD_rev04.stl");
            modelPaths.Add("IRB4600_20kg-250_LINK2_CAD_rev04.stl");
            modelPaths.Add("IRB4600_20kg-250_LINK3_CAD_rev005.stl");
            modelPaths.Add("IRB4600_20kg-250_LINK4_CAD_rev04.stl");
            modelPaths.Add("IRB4600_20kg-250_LINK5_CAD_rev04.stl");
            modelPaths.Add("IRB4600_20kg-250_LINK6_CAD_rev04.stl");
            modelPaths.Add("IRB4600_20kg-250_LINK3_CAD_rev04.stl");
            modelPaths.Add("IRB4600_20kg-250_CABLES_LINK1_rev03.stl");
            modelPaths.Add("IRB4600_20kg-250_CABLES_LINK2_rev03.stl");
            modelPaths.Add("IRB4600_20kg-250_CABLES_LINK3_rev03.stl");
            modelPaths.Add("IRB4600_20kg-250_BASE_CAD_rev04.stl");

            this.Loaded += MainWindow_Loaded;

            viewPort3d.RotateGesture = new MouseGesture(MouseAction.RightClick);
            viewPort3d.PanGesture = new MouseGesture(MouseAction.LeftClick);
        }
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            viewPort3d.Camera.LookDirection = new Vector3D(2038, -5200, -2930);
            viewPort3d.Camera.UpDirection = new Vector3D(-0.145, 0.372, 0.917);
            viewPort3d.Camera.Position = new Point3D(-1571, 4801, 3774);

            this.model.Content = InitializeModels(this.modelPaths);
        }

        private Model3DGroup InitializeModels(List<string> modelsNames)
        {
            Model3DGroup group = new Model3DGroup();
            try
            {
                ModelImporter import = new ModelImporter();

                foreach (string modelName in modelsNames)
                {
                    var materialGroup = new MaterialGroup();
                    Color mainColor = Colors.White;
                    //EmissiveMaterial emissMat = new EmissiveMaterial(new SolidColorBrush(mainColor));
                    DiffuseMaterial diffMat = new DiffuseMaterial(new SolidColorBrush(mainColor));
                    //SpecularMaterial specMat = new SpecularMaterial(new SolidColorBrush(mainColor), 2000);
                    //materialGroup.Children.Add(emissMat);
                    materialGroup.Children.Add(diffMat);
                    //materialGroup.Children.Add(specMat);

                    var link = import.Load(basePath + modelName);
                    GeometryModel3D model = link.Children[0] as GeometryModel3D;
                    model.Material = materialGroup;
                    model.BackMaterial = materialGroup;

                    group.Children.Add(link);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("未知异常:" + e.StackTrace);
            }
            return group;
        }
    }
}

HelixToolKit使用文档

以上就是WPF实现绘制3D图形的示例代码的详细内容,更多关于WPF 3D图形的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

WPF实现绘制3D图形的示例代码

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

WPF实现绘制3D图形的示例代码

WPF的3D功能可以在不编写任何c#代码的情况下进行绘制,只需要使用xaml即可完成3D图形的渲染。本文主要讲述了WPF-3D中的关键概念,以及常用到的命中测试、2d控件如何在3D对象中进行渲染,希望大家有所帮助
2023-03-02

WPF如何实现绘制3D图形

今天小编给大家分享一下WPF如何实现绘制3D图形的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。关键概念视口视口指的是图像要展
2023-07-05

Android实现绘制LocationMarkerView图的示例代码

LocationMarker是运动轨迹上Start、End,以及整公里点上笔者自定义绘制的一个MarkerView。这篇文章主要介绍了Android实现绘制LocationMarkerView图的示例代码,希望对大家有所帮助
2023-02-10

WPF实现圆形进度条的示例代码

这篇文章主要为大家详细介绍了WPF如何实现圆形的进度条,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
2023-01-04

Android开发 OpenGL ES绘制3D 图形实例详解

OpenGL ES是 OpenGL三维图形API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。 Ophone目前支持OpenGL ES 1.0 ,OpenGL ES 1.0 是以 OpenGL 1.3 规范为基础的,OpenGL
2022-06-06

基于WPF实现3D画廊动画效果的示例代码

这篇文章主要为大家详细介绍了如何基于WPF实现简单的3D画廊动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
2023-02-28

CSS绘制:如何实现简单的3D图形效果

CSS绘制:如何实现简单的3D图形效果在现代网页设计中,要给页面增加一些动态和立体感,常常需要用到3D图形效果。虽然在过去,实现3D效果可能需要使用JavaScript或者专业的3D引擎,但是现在CSS已经足够强大,可以实现一些简单的3D图
CSS绘制:如何实现简单的3D图形效果
2023-11-21

Python实现绘制凸包的示例代码

凸包(ConvexHull)是一个计算几何(图形学)中的概念。这篇文章主要为大家详细介绍了Python绘制凸包的示例代码,感兴趣的小伙伴可以了解一下
2023-05-18

C#实现绘制鼠标的示例代码

这篇文章主要为大家详细介绍了如何利用C#实现绘制鼠标的效果,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
2022-12-23

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录