C#+VTK三维开发:快速生成大量球体Sphere的三种方法(之一)

在C#中通过引用vtk的.net版本,也就是ActiViz.net,可以实现桌面三维应用程序开发,比如下面这个博主开发的类似谷歌地球的小应用。在此开发过程中,遇到了各种各样的问题,现在分享给大家。

后面的博客里,博主会上传源代码,请持续关注本人的博客!!

我们知道,通过在场景中增加vtkActor,可以添加各种三维几何体,但如何实现高效的生成vtkActor,并实现快速场景绘制和浏览,则需要很多技巧,我们以球体(点)生成为例,给大家介绍几种生成方法,以下为第一种,直接基于单个位置,生成一个独立的vtkActor。这也是网上最通用,或者说大模型通常给出的方法。

using Kitware.VTK;

class Program
{
    static void Main(string[] args)
    {
        // 创建一个球体
        vtkSphereSource sphereSource = vtkSphereSource.New();
        sphereSource.SetRadius(1.0); // 设置球体半径
        sphereSource.SetThetaResolution(20); // 设置经度分辨率
        sphereSource.SetPhiResolution(20); // 设置纬度分辨率
        sphereSource.SetCenter(1.0, 1.0, 1.0); // 设置球体中心位置 (x, y, z)

        // 创建一个映射器
        vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
        mapper.SetInputConnection(sphereSource.GetOutputPort());

        // 创建一个演员
        vtkActor actor = vtkActor.New();
        actor.SetMapper(mapper);
        actor.GetProperty().SetColor(1, 0, 0); // 设置球体颜色为红色

        // 创建一个渲染器
        vtkRenderer renderer = vtkRenderer.New();
        renderer.AddActor(actor);
        renderer.SetBackground(0.1, 0.2, 0.4); // 设置背景颜色

        // 创建一个渲染窗口
        vtkRenderWindow renderWindow = vtkRenderWindow.New();
        renderWindow.AddRenderer(renderer);

        // 创建一个交互器
        vtkRenderWindowInteractor renderWindowInteractor = vtkRenderWindowInteractor.New();
        renderWindowInteractor.SetRenderWindow(renderWindow);

        // 开始渲染和交互
        renderWindow.Render();
        renderWindowInteractor.Start();
    }
}

运行程序后,你会看到一个红色的球体,其中心位于 (1.0, 1.0, 1.0) 的位置,半径为1.0。

要是按照这个方法,生成100个球,那生成速度和浏览速度都非常慢,非常卡。那么我们看看有没有稍微优化的方法。

先建立一个全局唯一的SphereSource,大家都可以用,像孙悟空72变一样,其它球都从它变出来,这样就省内存了。

        /// <summary>
        /// 球体数据源
        /// </summary>
        private static vtkSphereSource SphereSource = null;

        /// <summary>
        /// 球体数据源的PolyData
        /// </summary>
        private static vtkPolyData SphereSourcePolyData = null;

        /// <summary>
        /// 球体数据源的面数
        /// </summary>
        private static int SphereFace = 10;

        /// <summary>
        /// 更新球体数据源的面数,面数越多,效率越低
        /// 同时初始化球体数据源机及其PolyData
        /// </summary>
        /// <param name="face"></param>
        public static void UpdateSphereSource(int face)
        {
            // 创建球体数据源
            SphereSource = vtkSphereSource.New();
            SphereSource.SetRadius(1);
            SphereSource.SetPhiResolution(face);
            SphereSource.SetThetaResolution(face);
            SphereSource.Update();
            SphereFace=face;
            // 获取单个球体的 vtkPolyData
            SphereSourcePolyData = SphereSource.GetOutput();
        }

现在开始生成一个球

        public static vtkActor CreateSphereActor(X3DVertex position, double radius, Color color)
        {
            if (SphereSource == null) UpdateSphereSource(SphereFace);

            vtkTransform transform = vtkTransform.New();
            transform.Translate(position.x, position.y, position.z); // 将球体平移到position
            transform.Scale(radius, radius, radius); // 将球体放大radius倍

            // 创建 vtkTransformPolyDataFilter 来应用变换
            vtkTransformPolyDataFilter transformFilter = vtkTransformPolyDataFilter.New();
            transformFilter.SetInputConnection(SphereSource.GetOutputPort());
            transformFilter.SetTransform(transform);
            transformFilter.Update();
            vtkPolyDataMapper mapper = vtkPolyDataMapper.New();
            mapper.SetInputData(transformFilter.GetOutput());
            return BuildActor(mapper, color);
        }

大家看到了,这是用transform的方法生成不同位置和大小的球。

通过上述方法也许生成速度快些,内存占用少些,但是也许浏览效果仍然不能令人满意。

请期待下一篇博客,介绍更高效的一种方法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值