C# OCCT Winform 界面搭建

目录

1.创建一个WInform项目

2.代码总览

代码解析

3.添加模型到场景

4.鼠标交互


1.创建一个WInform项目

2.代码总览

using Macad.Occt.Helper;
using Macad.Occt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Kitware.VTK;
using static System.Net.Mime.MediaTypeNames;

namespace OCCTTestProject
{
    public class OCCTView : Form
    {
        private V3d_Viewer _viewer;
        private AIS_InteractiveContext _context;
        private WNT_Window _window;
        private V3d_View _view;

        protected int myXmin;
        protected int myYmin;
        protected int myXmax;
        protected int myYmax;
        public OCCTView( )
        {
            //InitWindow();
        }

        public void InitWindow()
        {
            // 创建 OpenGL 驱动
            var ocGraphicDriver = Graphic3d.CreateOpenGlDriver();

            // 初始化 Viewer
            _viewer = new V3d_Viewer(ocGraphicDriver);
            _viewer.SetDefaultViewSize(1000.0);
            _viewer.SetDefaultLights();
            _viewer.SetDefaultViewProj(V3d_TypeOfOrientation.XnegYposZpos);
            _viewer.SetDefaultBackgroundColor(new Quantity_Color(Quantity_NameOfColor.BLACK));
            _viewer.SetDefaultVisualization(V3d_TypeOfVisualization.ZBUFFER);
            _viewer.SetLightOn();

            // 创建 WNT_Window 并绑定到 Panel 控件
            _window = new WNT_Window(this.Handle);
            _window.SetBackground(new Quantity_Color(Quantity_NameOfColor.BLACK));
            _window.Map();

            // 创建 View
            _view = _viewer.CreateView();
            _view.SetWindow(_window);
            //AIS_AnimationCamera AisAnimationCamera = new AIS_AnimationCamera(new TCollection_AsciiString("ViewCamera"), _view);
            // 设置视图属性
             
            // 设置小坐标轴 1.位置左下角 2.xyz 字体颜色 3.大小 4.箭头粗细
            _view.TriedronDisplay(Aspect_TypeOfTriedronPosition.LEFT_LOWER, new Quantity_Color(Quantity_NameOfColor.RED), 0.2, V3d_TypeOfVisualization.WIREFRAME);
            _view.SetBackgroundColor(new Quantity_Color(Quantity_NameOfColor.RED4));
            _view.SetBgGradientColors(new Quantity_Color(Quantity_NameOfColor.SKYBLUE), new Quantity_Color(Quantity_NameOfColor.WHEAT), Aspect_GradientFillMethod.Vertical, false);

            // 配置渲染参数
            var renderParams = _view.ChangeRenderingParams();
            renderParams.NbMsaaSamples = 4;
            renderParams.IsAntialiasingEnabled = true;
            renderParams.TransparencyMethod = Graphic3d_RenderTransparentMethod.BLEND_OIT;
            renderParams.Method = Graphic3d_RenderingMode.RASTERIZATION;
            renderParams.RaytracingDepth = 3;
            renderParams.IsShadowEnabled = true;
            renderParams.IsReflectionEnabled = true;
            renderParams.IsTransparentShadowEnabled = true;

            // 关闭计算模式并更新视图
            _view.SetComputedMode(false);
            _view.Update();
            _view.MustBeResized();
            _view.SetImmediateUpdate(false);
            _view.Redraw();

            // 创建交互上下文
            _context = new AIS_InteractiveContext(_viewer);
            _context.UpdateCurrentViewer();
    
            _view.MustBeResized();
            _view.Redraw();
        }

        private void RenderShape()
        {
            // 创建一个简单的立方体
            var box = new BRepPrimAPI_MakeBox(100.0, 100.0, 100.0).Shape();
            var aisShape = new AIS_Shape(box);

            // 显示形状

            _context.Display(aisShape, 1, 1, true); // 实体
            // _context.Display(aisShape, true); // 线框
            var sphere = new BRepPrimAPI_MakeSphere(new Pnt(100,100,150),30).Shape();
            var aissphere = new AIS_Shape(sphere);

            // 显示形状
            _context.Display(aissphere,1, 1,true); // 实体
            // _context.Display(aissphere, true); // 线框

            // 调整视图
            _view.FitAll();
            _view.MustBeResized();
            _view.Redraw();
        }



        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (_view != null)
            {
                _view.MustBeResized();
                _view.Redraw();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if(e.Button ==MouseButtons.Left)
            {
                
            }
            else if(e.Button == MouseButtons.Right)
            {
                SetDegenerateModeOn();
                StartRotation(e.X, e.Y);
            }

            myXmin = e.X; myYmin = e.Y;
            myXmax = e.X; myYmax = e.Y;
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
          
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            
            if(e.Button == MouseButtons.Left)
            {
                Zoom(myXmax, myYmax, e.X, e.Y);
                myXmax = e.X; myYmax = e.Y;
            }
            else if(e.Button == MouseButtons.Right)
            {
                Rotation(e.X, e.Y);
            }
            else if(e.Button == MouseButtons.Middle)
            {
                Pan(e.X - myXmax, myYmax - e.Y);
                myXmax = e.X; myYmax = e.Y;
            }
            else
            {
                Move(e.X, e.Y);
            }
            _view.Redraw();

        }

        protected void Move(int x, int y)
        {
            _context.MoveTo(x, y, _view, true);
        }

        protected void Zoom(int x1, int y1, int x2, int y2)
        {
            _view.Zoom(x1, y1, x2,y2);
        }

        protected void Rotation(int x, int y)
        {
            _view.Rotation(x, y);
        }

        protected void StartRotation(int x, int y)
        {
            _view.StartRotation(x, y);
        }

        protected void SetDegenerateModeOn()
        {
            _view.SetComputedMode(false);
            _view.Redraw();

        }

        protected void Pan(int x, int y)
        {
            _view.Pan(x,y);
        }
    }
}

代码解析

1.OCCT 与 Winform控件建立联系 是通过 WNT_Window  

_window = new WNT_Window(this.Handle);

因为this 是继承了 Form 所以相当于把Form 做为显示界面,和vtk 使用panel 的方式不同。Form 想要作为子控件使用需要通过MDI 方式嵌入到主Form中。

  public Form1()
  {
      InitializeComponent();

      oCCTView = new OCCTView();
      oCCTView.MdiParent = this;
      oCCTView.Show();

      this.WindowState = FormWindowState.Maximized;
      oCCTView.WindowState = FormWindowState.Maximized;
  }

  private void Form1_Load(object sender, EventArgs e)
  {
      oCCTView.InitWindow();
  }

  oCCTView.InitWindow(); 这里不放在Load 会报错,原因未知。

2.V3d_Viewer

①SetDefaultViewProj 当前视角

SetDefaultViewProj(V3d_TypeOfOrientation.XnegZpos)

SetDefaultViewProj(V3d_TypeOfOrientation.XnegYposZpos)

②SetLightOn 设置平行光、点光源或聚光灯 

关闭光源时

 _viewer.SetLightOff();

③V3d_View

TriedronDisplay:小坐标轴设置

参数:1.坐标轴位置  2.xyz 字体颜色  3.坐标轴大小  4.箭头粗细

SetBackgroundColor:在不使用SetBgGradientColors情况下设置单一背景色

 _view.SetBackgroundColor(new Quantity_Color(Quantity_NameOfColor.YELLOW));

SetBgGradientColors:创建渐变色背景。

1.渐变起点色

2.渐变终点色

3.渐变方向:水平,垂直,对角线,中心扩散

中心渐变

 renderParams.NbMsaaSamples 抗锯齿 MSAA 是一种抗锯齿技术,用于减少图像中的锯齿边缘。较高的采样数会提供更好的图像质量,但也会增加计算负担。

 renderParams.NbMsaaSamples = 0;             renderParams.NbMsaaSamples = 4;

RaytracingDepth:光线追踪的递归深度。光线追踪是一种渲染技术,通过模拟光线的传播路径来生成图像。较高的深度可以生成更真实的图像,但会增加计算复杂度。

Redraw:更新场景。

MustBeResized:标记视图需要调整大小,并在下次更新时重新计算视图的投影矩阵和其他尺寸相关的参数

3.添加模型到场景

 // 创建一个简单的立方体
 var box = new BRepPrimAPI_MakeBox(100.0, 100.0, 100.0).Shape();
 var aisShape = new AIS_Shape(box);

 // 显示形状
 _context.Display(aisShape, 1, 1, true); // 实体
 // _context.Display(aisShape, true); // 线框

 var sphere = new BRepPrimAPI_MakeSphere(new Pnt(100,100,150),30).Shape();
 var aissphere = new AIS_Shape(sphere);

 // 显示形状
 _context.Display(aissphere,1, 1,true); // 实体
 // _context.Display(aissphere, true); // 线框

 // 调整视图
 _view.FitAll();
 _view.MustBeResized();
 _view.Redraw();

线框:

 _view.FitAll(); 调整模型在场景合适位置。

4.鼠标交互

因为 OCCTView  是一个Form 因此直接使用Form的鼠标交互

   protected override void OnResize(EventArgs e)
   {
       base.OnResize(e);
       if (_view != null)
       {
           _view.MustBeResized();
           _view.Redraw();
       }
   }

   protected override void OnMouseDown(MouseEventArgs e)
   {
       if(e.Button ==MouseButtons.Left)
       {
           
       }
       else if(e.Button == MouseButtons.Right)
       {
           SetDegenerateModeOn();
           StartRotation(e.X, e.Y);
       }

       myXmin = e.X; myYmin = e.Y;
       myXmax = e.X; myYmax = e.Y;
   }

   protected override void OnMouseUp(MouseEventArgs e)
   {
     
   }

   protected override void OnMouseMove(MouseEventArgs e)
   {
       
       if(e.Button == MouseButtons.Left)
       {
           Zoom(myXmax, myYmax, e.X, e.Y);
           myXmax = e.X; myYmax = e.Y;
       }
       else if(e.Button == MouseButtons.Right)
       {
           Rotation(e.X, e.Y);
       }
       else if(e.Button == MouseButtons.Middle)
       {
           Pan(e.X - myXmax, myYmax - e.Y);
           myXmax = e.X; myYmax = e.Y;
       }
       else
       {
           Move(e.X, e.Y);
       }
       _view.Redraw();

   }

   protected void Move(int x, int y)
   {
       _context.MoveTo(x, y, _view, true);
   }

   protected void Zoom(int x1, int y1, int x2, int y2)
   {
       _view.Zoom(x1, y1, x2,y2);
   }

   protected void Rotation(int x, int y)
   {
       _view.Rotation(x, y);
   }

   protected void StartRotation(int x, int y)
   {
       _view.StartRotation(x, y);
   }

   protected void SetDegenerateModeOn()
   {
       _view.SetComputedMode(false);
       _view.Redraw();

   }

   protected void Pan(int x, int y)
   {
       _view.Pan(x,y);
   }

我也刚刚接触 OCCT 也在学习中,希望互相交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/735243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

现在的Android程序员为什么会感到焦虑?焦虑的源头在哪里?该怎么去缓解焦虑呢?——没有无中生有的贩卖焦虑,只有你的挣扎和不甘。

二、知识为何产生焦虑 先说两个世界,知识的世界和现实的世界。 知识的世界,由承载知识的那些载体组成,比如图书、音视频、报刊、自媒体等。 现实的世界,就是我们每天生活的、做出各种行为的世界。 学习的目的是什么呢&#xff1…

将WIN10的wifi上网分享给以太网接口

目录 打开网络设置设置属性点这里的设置将wlan主机的以太网接口IP设为自动获取 如果连接不成功,拔网线重连一次 打开网络设置 设置属性 点这里的设置 将wlan主机的以太网接口IP设为自动获取 如果连接不成功,拔网线重连一次

【八股系列】说一下mobx和redux有什么区别?(React)

🎉 博客主页:【剑九 六千里-CSDN博客】 🎨 上一篇文章:【介绍React高阶组件,适用于什么场景?】 🎠 系列专栏:【面试题-八股系列】 💖 感谢大家点赞👍收藏⭐评…

论文《Geom-GCN:Geometric Graph Convolutional Networks》笔记

【Geom-GCN】现有的MPNNs方法具有两个基本弱点:①丢失邻域节点的结构信息;②缺乏捕获非同配性图的长距离依赖的能力。本文从经典神经网络和网络几何学的观察出发,提出了一种新的几何聚合方案,该方案利用图背后的连续空间进行聚合&…

Python爬虫技术:动态JavaScript加载音频的解析

在当今的互联网世界中,JavaScript已成为构建丰富交互体验不可或缺的技术。然而,对于网络爬虫开发者来说,JavaScript动态生成的内容却带来了不小的挑战。音频内容的动态加载尤其如此,因为它们往往涉及到复杂的用户交互和异步数据加…

游戏高度可配置化(二)用“模型抽象”化解游戏策划和程序员的江湖恩怨

游戏高度可配置化(二)用“模型抽象”化解游戏策划和程序员的江湖恩怨 码客 卢益贵 ygluu 关键词:模型抽象、功能抽象、抽象工厂模式、游戏服务端引擎、高度可配置化、恩怨情仇、游戏策划、数据引擎、生产消费模型、订阅-通知模型 一、前言…

Day11 —— 大数据技术之Spark

Spark快速入门系列 Spark的概述什么是Spark?Spark的主要特点Spark的主要组件 Spark安装Spark三种运行模式Spark Standalone架构Spark Standalone的两种提交方式Spark On YARN架构 RDD算子转化算子行动算子 Spark RDDRDD的创建从对象集合创建RDD从外部存储创建RDD Sp…

基于SpringBoot+vue闲置物品交易网站详细设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…

系统架构师概述

引言 系统架构设计师是项目开发活动中的众多角色之一,它可以是一个小组或者一个人或者是一个团队,架构师包含建筑师,设计师,创造者,缔造者,可以说架构师就是我们社会各个领域的创造者和缔造者。从组织上划分…

【深度学习系列】全面指南:安装TensorFlow的CPU和GPU版本

本博客旨在为初学者提供一份全面的指南,介绍如何根据个人电脑的配置选择并安装适合的TensorFlow版本。内容涵盖了如何查看电脑显卡型号以确定是安装CPU还是GPU版本的TensorFlow,创建Python虚拟环境,以及使用conda命令查找可用的TensorFlow版本…

使用Vercel 搭建自己的Dashy导航页

背景 Dashy 是一个开源的自托管导航页面配置服务,它具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。用户可以利用 Dashy 将自己常用的一些网站聚合起来,形成一个个性化的导航页面。 同类的竞品还有Heimdall, Flare 等。 可以通过Docker 等…

DAMA学习笔记(二)-数据治理

1.引言 数据治理(Data Governance,DG)的定义是在管理数据资产过程中行使权力和管控,包括计划、监控和实施。在所有组织中,无论是否有正式的数据治理职能,都需要对数据进行决策。建立了正式的数据治理规程及…

深入学习Java1213新特性

一、关于Java生态圈 二、Java老矣,尚能饭否? 三、JDK各版本主要特性 四、JDK与IDE的下载与安装 五、Java12新特性 1.switch表达式(预览)

以太坊==MetaMask获取测试币最新网址

估算分数https://community.infura.io/t/unable-to-receive-sepolia-eth-from-faucet/7715 Gitcoin Passport 水龙头地址,填入自己的测试地址 水龙头项目地址 GitHub - pk910/PoWFaucet: Modularized faucet for EVM chains with different protection methods (…

DNF手游攻略:云手机辅助流光星陨刀详细攻略大全!

DNF手游中,流光星陨刀是鬼剑士的专属神器之一,拥有快速的攻击速度和优秀的物理与法术攻击属性,因其出色的性能和未来升级的潜力,成为广大玩家关注的焦点。 流光星陨刀的背景与起源 流光星陨刀作为鬼剑士的标志性武器之一&#xf…

Go 语言学习笔记之数组与切片

大家好,我是码农先森。 数组与切片的区别 在 Go 语言中,数组和切片是两种不同的数据结构,它们之间有以下主要区别。 参数长度: 数组(Array):数组的长度是固定的,在创建时就需要指…

CMMM Plus+ Calculus Update 超级游戏大作 游戏说明

资源链接 关卡编辑器 ◽️使用 WASD 移动视图。 ◽️LMB 放置单元格。 ◽️Space LMB 删除单元格。Ctrl Space LMB 删除所有相同类型的单元格。 ◽️Q / E 旋转单元格。 ◽️Z / X 在单元格类别之间切换。 ◽️键 1-9 快速选择单元格。 ◽️按 F 显示可拖动的图块。 ⌨️控…

机器学习好神奇,来看看Lasso的超参数调整与模型选择

目录 一、什么是机器学习?二、稀疏建模介绍三、Lasso回归简介四、Lasso超参数调整与模型选择 一、什么是机器学习? 机器学习是一种人工智能技术,它使计算机系统能够从数据中学习并做出预测或决策,而无需明确编程。它涉及到使用算…

贪心算法——最少跳跃步数(C++)

未来,未来。 ——2024年6月17日 题目描述 给定一个含n(1≤n≤1000)个非负整数数组nums(0≤nums[i]≤1000),数组中的每个元素表示在该位置可以跳跃的最大长度,假设总是可以从初始位置0到达最后一…

【C++】————类和对象(中)

作者主页: 作者主页 本篇博客专栏:C 创作时间 :2024年6月22日 一、类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情 况下&#x…