【OCCT+ImGUI系列】011-Poly-Poly_Triangle三角形面片

news2025/7/22 5:59:14

在这里插入图片描述

Poly_Triangle 是什么?

Poly_Triangle 是一个非常轻量的类,用于表示一个三角网格中的单个三角形面片。它是构成 Poly_Triangulation(三角网格对象)的基本单位之一。之后会写关于碰撞检测的相关文章,三角面片是非常重要的一部分。

每个 Poly_Triangle 包含三个整数索引,它们是指向一个节点列表的索引(通常是 Poly_Triangulation::Nodes() 中的点)。这些节点是三角形的三个顶点。


🔹 数据成员

Standard_Integer myNodes[3];
  • 存储三个节点的索引,索引范围通常是 [1, NbNodes()](注意:OpenCascade 中使用 1-based 索引)。
  • 每个索引指向的是一个顶点坐标,坐标存储在 Poly_Triangulation 中的节点数组里。

🔹 构造函数

Poly_Triangle()
  • 默认构造函数,三个索引值初始化为 0(无效状态)。

请添加图片描述

如图为从点击选择三个点的索引来构造Poly_Triangle并显示。

Poly_Triangle(Standard_Integer theN1, Standard_Integer theN2, Standard_Integer theN3)
  • 构造函数,直接设置三个顶点索引。

🔹 成员函数

设置节点索引

void Set(Standard_Integer theN1, Standard_Integer theN2, Standard_Integer theN3)
  • 一次性设置所有三个节点索引。
void Set(Standard_Integer theIndex, Standard_Integer theNode)
  • 设置指定位置(1~3)的单个索引值。
  • 如果 theIndex 不在 1~3,抛出 Standard_OutOfRange 异常。

访问节点索引

void Get(Standard_Integer& theN1, Standard_Integer& theN2, Standard_Integer& theN3) const
  • 返回三个节点索引的值(通过引用)。
Standard_Integer Value(Standard_Integer theIndex) const
  • 返回指定位置(1~3)的节点索引值,超出范围抛异常。
Standard_Integer operator()(Standard_Integer theIndex) const
Standard_Integer& operator()(Standard_Integer theIndex)
  • 函数调用操作符的重载,提供类似数组访问的方式。
  • 返回索引值(常量或引用)。
Standard_Integer& ChangeValue(Standard_Integer theIndex)
  • 返回对某个节点索引的引用,可以进行原地修改。

注意点

  1. 索引范围是 1~NbNodes(),不是从0开始
  2. 三角形只保存的是节点索引,不保存具体的几何位置,顶点坐标保存在 Poly_Triangulation 中。
  3. 修改 Poly_Triangle 不会自动更新 Poly_Triangulation,需要你在使用时保持一致性。

总结

功能方法简述
构造Poly_Triangle()空三角形
构造Poly_Triangle(n1,n2,n3)初始化三角形索引
访问Get()获取3个顶点索引
访问Value(index) / operator()获取某个索引值
修改Set(n1,n2,n3) / Set(index, node)设置索引
修改ChangeValue(index)引用访问可直接修改

代码

#pragma once

#include "pch.h"
#include <Poly_Triangulation.hxx>
#include <AIS_Triangulation.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include "BaseScene.h"
#include "VisSceneComponents.h"
#include "TutorialWindow.h"

class PolyTriangle011 : public BaseScene, public VisSceneComponents, public TutorialWindow {
public:
    PolyTriangle011() {
        openTutorialWindow();
        initAllNodes();
    }

    void displayScene(const Handle(V3d_View)& view, const Handle(AIS_InteractiveContext)& context) override {
        if (!bIsSceneInit) {
            sceneInit(view, context);
            bIsSceneInit = true;
        }
        renderTutorialWindow(context);
    }

    void customInitTutorialWindow(const Handle(AIS_InteractiveContext)&) override {}

private:
    std::vector<TColgp_Array1OfPnt> allNodes;
    int currentNodeSetIndex = 0;

    Handle(Poly_Triangulation) triangulation;
    Handle(AIS_Triangulation) aisTriangulation;
    std::vector<Handle(AIS_Shape)> vertexMarkers;

    int triIndices[3] = { 1, 2, 3 };
    bool needsUpdate = true;

    void initAllNodes() {
        allNodes.clear();

        // 节点集 1: 正三角形
        TColgp_Array1OfPnt nodes1(1, 3);
        nodes1.SetValue(1, gp_Pnt(0, 0, 0));
        nodes1.SetValue(2, gp_Pnt(100, 0, 0));
        nodes1.SetValue(3, gp_Pnt(50, 100, 0));
        allNodes.push_back(nodes1);

        // 节点集 2: 矩形
        TColgp_Array1OfPnt nodes2(1, 4);
        nodes2.SetValue(1, gp_Pnt(0, 0, 0));
        nodes2.SetValue(2, gp_Pnt(100, 0, 0));
        nodes2.SetValue(3, gp_Pnt(100, 100, 0));
        nodes2.SetValue(4, gp_Pnt(0, 100, 0));
        allNodes.push_back(nodes2);

        // 节点集 3: 10 个点(圆形分布)
        TColgp_Array1OfPnt nodes3(1, 10);
        for (int i = 0; i < 10; ++i) {
            double angle = 2.0 * M_PI * i / 10.0;
            nodes3.SetValue(i + 1, gp_Pnt(100 * cos(angle), 100 * sin(angle), 0));
        }
        allNodes.push_back(nodes3);
    }

    void sceneInit(const Handle(V3d_View)&, const Handle(AIS_InteractiveContext)& context) override {
        updateVisualization(context);
    }

    void renderTutorialContent(const Handle(AIS_InteractiveContext)& context) override {
        ImGui::TextColored(ImVec4(1, 1, 0, 1), "Poly_Triangulation Multi-point Construct Example");

        // 点集选择 UI(非 CollapsingHeader)
        ImGui::SeparatorText("Point Set Selection");
        const char* labels[] = { "Equilateral Triangle (3 pts)", "Rectangle (4 pts)", "Circle (10 pts)" };
        if (ImGui::Combo("Current Point Set", &currentNodeSetIndex, labels, IM_ARRAYSIZE(labels))) {
            needsUpdate = true;

            // 重置三角形索引在合法范围内
            int lower = allNodes[currentNodeSetIndex].Lower();
            int upper = allNodes[currentNodeSetIndex].Upper();
            for (int i = 0; i < 3; ++i) {
                triIndices[i] = std::clamp(lower + i, lower, upper);
            }
        }

        if (triIndices[0] == triIndices[1] ||
            triIndices[0] == triIndices[2] ||
            triIndices[1] == triIndices[2]) {
            ImGui::TextColored(ImVec4(1, 0, 0, 1), "Three vertices must be unique!");
        }

        // 三角形顶点选择 UI(默认展开)
        if (ImGui::CollapsingHeader("Triangle Index Selection", ImGuiTreeNodeFlags_DefaultOpen)) {
            int lower = allNodes[currentNodeSetIndex].Lower();
            int upper = allNodes[currentNodeSetIndex].Upper();
            for (int i = 0; i < 3; ++i) {
                std::string label = "Vertex Index " + std::to_string(i + 1);
                if (ImGui::SliderInt(label.c_str(), &triIndices[i], lower, upper)) {
                    needsUpdate = true; // 用户拖动滑块后设置更新标志
                }
            }
        }

        if (needsUpdate) {
            updateVisualization(context);
            needsUpdate = false;
        }
    }

    void updateVisualization(const Handle(AIS_InteractiveContext)& context) {
        // 清理之前的显示
        for (auto& v : vertexMarkers)
            context->Remove(v, false);
        vertexMarkers.clear();

        if (!triangulation.IsNull())
            context->Remove(aisTriangulation, false);

        // 当前节点集
        const auto& nodes = allNodes[currentNodeSetIndex];
        int n = nodes.Length();

        triangulation = new Poly_Triangulation(n, 1, false);
        for (int i = nodes.Lower(); i <= nodes.Upper(); ++i)
            triangulation->SetNode(i, nodes(i));

        triangulation->SetTriangle(1, Poly_Triangle(triIndices[0], triIndices[1], triIndices[2]));

        for (int i = nodes.Lower(); i <= nodes.Upper(); ++i) {
            TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(nodes(i));
            auto ais = new AIS_Shape(v);
            ais->SetColor(Quantity_NOC_RED1);
            context->Display(ais, false);
            vertexMarkers.push_back(ais);
        }

        aisTriangulation = new AIS_Triangulation(triangulation);
        aisTriangulation->SetTransparency(0.4f);
        context->Display(aisTriangulation, true);
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习基础】机器学习入门核心算法:Mini-Batch K-Means算法

机器学习入门核心算法&#xff1a;Mini-Batch K-Means算法 一、算法逻辑工作流程与传统K-Means对比 二、算法原理与数学推导1. 目标函数2. Mini-Batch更新规则3. 学习率衰减机制4. 伪代码 三、模型评估1. 内部评估指标2. 收敛性判断3. 超参数调优 四、应用案例1. 图像处理 - 颜…

机器学习实战36-基于遗传算法的水泵调度优化项目研究与代码实现

大家好,我是微学AI,今天给大家介绍一下机器学习实战36-基于遗传算法的水泵调度优化项目研究与代码实现。 文章目录 一、项目介绍二、项目背景三、数学原理与算法分析动态规划模型遗传算法设计编码方案适应度函数约束处理算法参数能量消耗模型一泵房能耗二泵房能耗效率计算模…

【仿muduo库实现并发服务器】使用正则表达式提取HTTP元素

使用正则表达式提取HTTP元素 1.正则表达式2.正则库的使用3.使用正则表达式提取HTTP请求行 1.正则表达式 正则表达式它其实是描述了一种字符串匹配的模式&#xff0c;它可以用来在一个字符串中检测一个特定格式的字串&#xff0c;以及可以将符合特定规则的字串进行替换或者提取…

核心机制:流量控制

搭配滑动窗口使用的 窗口大小 窗口越大,传输速度就越快,但是也不能无限大,太大了,对于可靠性会有影响 比如发生方以非常快的速度,发送,接收方的处理速度跟不上,也就会导致有效数据被接受方丢弃(又得重传) 流量控制,就是根据接收方的处理能力(如何衡量?),干预到发送方的发送…

极智项目 | 基于PyQT实现的YOLOv12行人目标检测软件设计

基于YOLOv12的专业级行人目标检测软件应用 开发者: 极智视界 软件下载&#xff1a;链接 &#x1f31f; 项目特色 专业检测: 基于最新YOLOv12模型&#xff0c;专门针对行人检测优化现代界面: 采用PyQt5构建的美观、直观的图形用户界面高性能: 支持GPU加速&#xff0c;检测速…

vscode不满足先决条件问题的解决——vscode的老版本安装与禁止更新(附安装包)

目录 起因 vscode更新设置的关闭 安装包 结语 起因 由于主包用的系统是centos的&#xff0c;且版本有点老了&#xff0c;再加上vscode现在不支持老版本的&#xff0c;这对主包来说更是雪上加霜啊 但是主包看了网上很多教程&#xff0c;眼花缭乱&#xff0c;好多配置要改&…

RustDesk 搭建自建服务器并设置服务自启动

目录 0. 介绍 1. 事前准备 1.1 有公网 ip 的云服务器一台 1.2 服务端部署包 1.3 客户端安装包 2. 部署 2.1 服务器环境准备 2.2 上传服务端部署包 2.3 运行 pm2 3. 客户端使用 3.1 安装 3.2 配置 3.2.1 解锁网络设置 3.2.2 ID / 中级服务器 3.3 启动效果 > …

【数据库】数据库恢复技术

数据库恢复技术 实现恢复的核心是使用冗余&#xff0c;也就是根据冗余数据重建不正确数据。 事务 事务是一个数据库操作序列&#xff0c;是一个不可分割的工作单位&#xff0c;是恢复和并发的基本单位。 在关系数据库中&#xff0c;一个事务是一条或多条SQL语句&#xff0c…

力扣HOT100之动态规划:32. 最长有效括号

这道题放在动态规划里属实是有点难为人了&#xff0c;感觉用动态规划来做反而更难理解了&#xff0c;这道题用索引栈来做相当好理解&#xff0c;这里先讲下索引栈的思路。 索引栈做法 我们定义一个存放整数的栈&#xff0c;定义一个全局变量result来记录最长有效子串的长度&a…

Unity UI 性能优化终极指南 — Image篇

&#x1f3af; Unity UI 性能优化终极指南 — Image篇 &#x1f9e9; Image 是什么&#xff1f; Image 是UGUI中最常用的基本绘制组件支持显示 Sprite&#xff0c;可以用于背景、按钮图标、装饰等是UI性能瓶颈的头号来源之一&#xff0c;直接影响Draw Call和Overdraw &#x1…

Nginx + Tomcat 负载均衡、动静分离群集

一、 nginx 简介 Nginx 是一款轻量级的高性能 Web 服务器、反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在 BSD-like 协议下发行。其特点是占有内存少&#xff0c;并发能力强&#xff0c;在同类型的网页服务器中表现优异&#xff0c;常用…

c++ algorithm

cheatsheet&#xff1a;https://hackingcpp.com transform 元素变换 https://blog.csdn.net/qq_44961737/article/details/146011174 #include <iostream> #include <vector> #include <algorithm>int main() {std::vector<int> a {1, 2, 3, 4, 5};…

安全-JAVA开发-第一天

目标&#xff1a; 安装环境 了解基础架构 了解代码执行顺序 与数据库进行连接 准备&#xff1a; 安装 下载IDEA并下载tomcat&#xff08;后续出教程&#xff09; 之后新建项目 注意点如下 1.应用程序服务器选择Web开发 2.新建Tomcat的服务器配置文件 并使用 Hello…

6月2日上午思维训练题解

好好反思一下&#xff0c;自己在学什么&#xff0c;自己怎么在做训练赛的&#xff0c;真有这么难吗 &#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; A - Need More Arrays 题解 想尽可能多的拆出新数组的个数&#xff0c;只需要从原本的数组中提取出最长的一…

【CF】Day69——⭐Codeforces Round 897 (Div. 2) D (图论 | 思维 | DFS | 环)

D. Cyclic Operations 题目&#xff1a; 思路&#xff1a; 非常好的一题 对于这题我们要学会转换和提取条件&#xff0c;从特殊到一般 我们可以考虑特殊情况先&#xff0c;即 k n 和 k 1时&#xff0c;对于 k 1&#xff0c;我们可以显然发现必须满足 b[i] i&#xff0c;而…

前端八股之Vue

目录 有使用过vue吗&#xff1f;说说你对vue的理解 你对SPA单页面的理解&#xff0c;它的优缺点分别是什么&#xff1f;如何实现SPA应用呢 一、SPA 是什么 二、SPA 和 MPA 的区别 三、SPA 的优缺点 四、实现 SPA 五、给 SPA 做 SEO 的方式&#xff08;基于 Vue&#xff…

谷歌地图高清卫星地图2026中文版下载|谷歌地图3D卫星高清版 V7.3.6.9796 最新免费版下载 - 前端工具导航

谷歌地图高清卫星地图2024中文版是一款非常专业的世界地图查看工具。通过使用该软件&#xff0c;你就可以在这里看到外太空星系、大洋峡谷等场景&#xff0c;通过高清的卫星地图&#xff0c;可以清晰查看地图、地形、3D建筑、卫星图像等信息&#xff0c;让你可以更轻松的探索世…

条形进度条

组件 <template><view class"pk-detail-con"><i class"lightning" :style"{ left: line % }"></i><i class"acimgs" :style"{ left: line % }"></i><view class"progress&quo…

IBM DB2分布式数据库架构

一、什么是分布式数据库架构 分布式数据库架构是现代数据库系统的重要发展方向&#xff0c;特别适合处理大规模数据、高并发访问和高可用性需求的应用场景。下面我们从原理、架构模式、关键技术、实现方式和常见产品几个方面来系统讲 1、分布式数据库的基本概念与原理 1. 什…

Android Studio 向模拟器手机添加照片、视频、音乐

Android Studio 向模拟器手机添加照片、视频、音乐(其实都是一样的&#xff0c;只是添加到不同的文件夹&#xff09;&#xff0c;例如我们在很多程序中功能例如&#xff1a;选择头像&#xff0c;跳转到手机相册选择头像&#xff0c;此时相册为空&#xff0c;即模拟器没有图片资…