WinForm显示3D图(Sharpgl)

2023-11-06

总述

Sharpgl是.NET平台的Opengl,可以用来绘画、展示3D图,本文将介绍如何显示SOlidWorks等软件制作的3D模型。

安装Sharpgl

下载SharpGL.vsix文件并点击安装,VS中就会有相应的项目出现了,之后创建工程时选择这个项目建立即可。

解析模型

在网上不难找到个人写的3DS解析库,直接使用即可。一般这些解析库针对的是3ds或者obj文件,对于SolidWorks创建的模型就需要一些转换工作了。

  1. 保存模型为STL类型
  2. 使用Spin3D软件转换为3ds/obj

解析器代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpGL;
using System.IO;
using System.Collections;

namespace _3D绘图
{
    class read_obj
    {
        public class POINT3
        {
            public double X;
            public double Y;
            public double Z;
        };
        public class WenLi
        {
            public double TU;
            public double TV;
        };
        public class FaXiangLiang
        {
            public double NX;
            public double NY;
            public double NZ;
        };
        public class Mian
        {
            public int[] V = new int[3];
            public int[] T = new int[3];
            public int[] N = new int[3];
        };
        public class Model
        {
         public List<POINT3> V = new List<POINT3>();//V:代表顶点。格式为V X Y Z,V后面的X Y Z表示三个顶点坐标。浮点型
            public List<WenLi> VT = new List<WenLi>();//表示纹理坐标。格式为VT TU TV。浮点型
            public List<FaXiangLiang> VN = new List<FaXiangLiang>();//VN:法向量。每个三角形的三个顶点都要指定一个法向量。格式为VN NX NY NZ。浮点型
            public List<Mian> F = new List<Mian>();//F:面。面后面跟着的整型值分别是属于这个面的顶点、纹理坐标、法向量的索引。
            //面的格式为:f Vertex1/Texture1/Normal1 Vertex2/Texture2/Normal2 Vertex3/Texture3/Normal3
        }

        public Model mesh = new Model();
        public float movX;
        public float movY;
        public float movZ;
        public float xRotate;
        public float yRotate;
        public float x;
        public float y;

        //放缩参数
        public static float scale;
        //显示列表
        public uint showFaceList;

        public int YU = 1;

        public void loadFile(String fileName)
        {
            // Mian[] f;
            //POINT3[] v;
            //FaXiangLiang[] vn;
            //WenLi[] vt;

            StreamReader objReader = new StreamReader(fileName);
            ArrayList al = new ArrayList();
            string texLineTem = "";
            while (objReader.Peek() != -1)
            {
                texLineTem = objReader.ReadLine();
                if (texLineTem.Length < 2) continue;
                if (texLineTem.IndexOf("v") == 0)
                {
                    if (texLineTem.IndexOf("t") == 1)//vt 0.581151 0.979929 纹理
                    {
                        string[] tempArray = texLineTem.Split(' ');
                        WenLi vt = new WenLi();
                        vt.TU = double.Parse(tempArray[1]);
                        vt.TV = double.Parse(tempArray[2]);
                        mesh.VT.Add(vt);
                    }
                    else if (texLineTem.IndexOf("n") == 1)//vn 0.637005 -0.0421857 0.769705 法向量
                    {
                        string[] tempArray = texLineTem.Split(new char[] { '/', ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
                        FaXiangLiang vn = new FaXiangLiang();
                        vn.NX = double.Parse(tempArray[1]);
                        vn.NY = double.Parse(tempArray[2]);
                        if (tempArray[3] == "\\")
                        {
                            texLineTem = objReader.ReadLine();
                            vn.NZ = double.Parse(texLineTem);
                        }
                        else vn.NZ = double.Parse(tempArray[3]);

                        mesh.VN.Add(vn);
                    }
                    else
                    {//v -53.0413 158.84 -135.806 点
                        string[] tempArray = texLineTem.Split(' ');
                        POINT3 v = new POINT3();
                        v.X = double.Parse(tempArray[1]);
                        v.Y = double.Parse(tempArray[2]);
                        v.Z = double.Parse(tempArray[3]);
                        mesh.V.Add(v);
                    }
                }
                else if (texLineTem.IndexOf("f") == 0)
                {
                    //f 2443//2656 2442//2656 2444//2656 面
                    string[] tempArray = texLineTem.Split(new char[] { '/', ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
                    Mian f = new Mian();
                    int i = 0;
                    int k = 1;
                    while (i < 3)
                    {
                        if (mesh.V.Count() != 0)
                        {
                            f.V[i] = int.Parse(tempArray[k]) - 1;
                            k++;
                        }
                        if (mesh.VT.Count() != 0)
                        {
                            f.T[i] = int.Parse(tempArray[k]) - 1;
                            k++;
                        }
                        if (mesh.VN.Count() != 0)
                        {
                            f.N[i] = int.Parse(tempArray[k]) - 1;
                            k++;
                        }
                        i++;
                    }
                    mesh.F.Add(f);

                }
            }


        }

        public uint createListFace(ref SharpGL.OpenGL gl)
        {
            gl.NewList(showFaceList, OpenGL.GL_COMPILE);
            if (mesh.V.Count() == 0) return 119;
            for (int i = 0; i < mesh.F.Count(); i++)
            {
                gl.Begin(OpenGL.GL_TRIANGLES);                          // 绘制三角形
                if (mesh.VT.Count() != 0) gl.TexCoord(mesh.VT[mesh.F[i].T[0]].TU, mesh.VT[mesh.F[i].T[0]].TV);  //纹理    
                if (mesh.VN.Count() != 0) gl.Normal(mesh.VN[mesh.F[i].N[0]].NX, mesh.VN[mesh.F[i].N[0]].NY, mesh.VN[mesh.F[i].N[0]].NZ);//法向量
                gl.Vertex(mesh.V[mesh.F[i].V[0]].X / YU, mesh.V[mesh.F[i].V[0]].Y / YU, mesh.V[mesh.F[i].V[0]].Z / YU);        // 上顶点

                if (mesh.VT.Count() != 0) gl.TexCoord(mesh.VT[mesh.F[i].T[1]].TU, mesh.VT[mesh.F[i].T[1]].TV);  //纹理
                if (mesh.VN.Count() != 0) gl.Normal(mesh.VN[mesh.F[i].N[1]].NX, mesh.VN[mesh.F[i].N[1]].NY, mesh.VN[mesh.F[i].N[1]].NZ);//法向量
                gl.Vertex(mesh.V[mesh.F[i].V[1]].X / YU, mesh.V[mesh.F[i].V[1]].Y / YU, mesh.V[mesh.F[i].V[1]].Z / YU);        // 左下

                if (mesh.VT.Count() != 0) gl.TexCoord(mesh.VT[mesh.F[i].T[2]].TU, mesh.VT[mesh.F[i].T[2]].TV);  //纹理
                if (mesh.VN.Count() != 0) gl.Normal(mesh.VN[mesh.F[i].N[2]].NX, mesh.VN[mesh.F[i].N[2]].NY, mesh.VN[mesh.F[i].N[2]].NZ);//法向量
                gl.Vertex(mesh.V[mesh.F[i].V[2]].X / YU, mesh.V[mesh.F[i].V[2]].Y / YU, mesh.V[mesh.F[i].V[2]].Z / YU);        // 右下
                gl.End();                                        // 三角形绘制结束    
            }
            gl.EndList();
            return showFaceList;
        }

    }
}

整个资料下载

关注微信公众号,发送 sharpgl
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WinForm显示3D图(Sharpgl) 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 基础实验篇

    PX4控制器的外部通信 01 实验名称及目的 PX4控制器的外部通信 在进行硬件在环仿真时 我们常常需要向设计的Simulink控制器中发送数据 传感器数据 故障触发 控制指令 参数调整等 同时接收一些感兴趣的数据 RflySim平台的Si
  • Java学习笔记-锁

    Java学习笔记 锁 Lock 锁 从JDK5 0开始 Java提供了更强大的线程同步机制 通过显式定义同步锁对象来实现同步 同步锁使用Lock对象充当 java util concurrent locks Lock接口是个控制多线程对共享
  • linux磁盘空间不足的实用技巧

    1 删除日志 rm rf var log 安装了Anaconda后 发现这个文件越来越大 以下列一些删除不需要文件的方法 2 Anaconda 删除没有被硬依赖到其他地方的包 conda clean p 3 Anaconda 清理缓存的压缩
  • MySQL中视图与表的区别

    1 MySQL中视图和表的区别以及联系 1 视图是已经编译好的SQL语句 是基于SQL语句的结果集的可视化的表 而表不是 2 视图没有实际的物理记录 而表有 3 表是内存 视图是窗口 4 表占用物理存储空间而视图不占用物理存储空间 视图只是
  • undefined reference to ‘mysql_init@4‘ error: ld returned 1 exit status<-报错信息,用codeblocks连接MySQL时的报错

    解决方案 本文引用的是别人的文章 我自己总结一下 你能走到这一步出错说明你前面看了其他博主的文章 那么你只用利用文中提供网盘资源来代替你本来需要添加的include头文件的引用和lib库文件的链接即可 剩下的参考其他文章实现会更简单易懂 由
  • React组件之间如何通信?

    父组件向子组件传递 父组件在调用子组件的时候 在子组件标签内传递参数 子组件通过props属性就能接收父组件传递过来的参数 子组件向父组件传递 父组件向子组件传一个函数 然后通过这个函数的回调 拿到子组件传过来的值 兄弟组件之间的通信 父组
  • Spring源码分析(四)Bean生命周期源码分析2:合并BeanDefinition、FactoryBean

    Spring容器启动 扫描得到所有BeanDefinition之后 就会先实例化所有非懒加载的单例Bean的 入口 Spring容器启动刷新的方法里 org springframework context support AbstractA
  • 烂怂if-else代码优化方案

    0 问题概述 代码可读性是衡量代码质量的重要标准 可读性也是可维护性 可扩展性的保证 因为代码是连接程序员和机器的中间桥梁 要对双边友好 Quora 上有一个帖子 What are some of the most basic things
  • 【神经网络】图解LSTM和GRU

    图解LSTM和GRU 1 问题 循环神经网络 RNN Recurrent Neural Network 受到短期记忆的影响 如果一个序列足够长 就很难将早期产生的信息带到后续的步骤中来 因此 如果试图处理一段文字来做预测 RNN可能会从一开
  • 使用rke搭建k8s集群

    1 下载rke 选择合适的版本 https github com rancher rke 下载后上传到服务器 修改为rke 且移动号可执行目录 mv rke linux amd64 usr local bin rke 修改为可执行权限 ch
  • markdown+CSDN+Typora+知乎+微信公众号最佳偷懒写作方法

    目录 markdown 思想 适用范畴 基本语法 重点语法 高级语法 Typora 补充工具 公式编辑 保存和导出 导入 定制化主题 图片拖拽 超链接 列表 LaTex 公式 表格 生成目录 编辑模式 导出与公众号 md与CSDN 导入 导
  • 用户留存分析—SQL

    SELECT log day 日期 count user id day0 新增数量 count user id day1 count user id day0 次日留存率 count user id day3 count user id d
  • 星罗棋布:关于VPS测试脚本集锦内容

    2021 09 25 更新 优化排版 引言 莫忧世事兼身事 须著人间比梦间 勿埋我心 当我们获得一个服务器后 会想知道它的性能如何 宝塔自带跑分的应用 但是测试的数据比较片面 所以就有了各种各样的测试脚本 勿埋我心带你了解一下有哪些常用的V
  • VMware安装win10系统的心路历程

    友情提示 尽量使用原版或别人用过的 很早之前使用VMware装过win2008和centos7 都是傻瓜安装 没想到这次安装win10一点都不傻瓜 软件版本 VMware Workstation 15 Pro 1 按照常识先下载iso文件
  • hive建表

    https blog csdn net wgyzzzz article details 107446435 一 hive建表语法 二 hive外部表 1 准备测试数据 放入虚拟机 data目录下 2 创建外部表 3 装载数据 4 查询tes
  • unity使用setTrigger需注意地方

    使用上可以参考另一篇文章 RPG游戏主角状态机 Trigger触发器 注意都是从Any State开始的 否则你在使用Aniamtor的Trigger参数触发时没反应
  • 网页开发基础常见html、css

    目录 HTML基础 一 段落 行内和换行标签 二 文本样式标签 三 表格标签 四 表单标签 五 多行文本标签 六 列表标签 七 超链接标签 八 图像标签 HTML基础 html语言基本格式 常用的HTML标签 一 段落 行内和换行标签 二
  • 我为什么不在乎人工智能

    有人听说我想创业 给我提出了一些 忽悠 的办法 他们说 既然你是程序语言专家 而现在人工智能 AI 又非常热 那你其实可以搞一个 自动编程系统 号称可以自动生成程序 取代程序员的工作 节省许许多多的人力支出 这样就可以趁着 AI 热 拉到投
  • 记录一下:使用 python -m SimpleHTTPServer 快速搭建http服务

    为什么80 的码农都做不了架构师 gt gt gt 在 Linux 服务器上或安装了 Python 的机器上 Python自带了一个WEB服务器 SimpleHTTPServer 我们可以很简单的使用 python m SimpleHTTP
  • WinForm显示3D图(Sharpgl)

    总述 Sharpgl是 NET平台的Opengl 可以用来绘画 展示3D图 本文将介绍如何显示SOlidWorks等软件制作的3D模型 安装Sharpgl 下载SharpGL vsix文件并点击安装 VS中就会有相应的项目出现了 之后创建工