OpenCascade面片导出网格的纹理坐标的计算

通过BRepMesh_IncrementalMesh得到OCC的Solid的各个Face的三角网格, 可以通过

TopLoc_Location loc;
Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(aFace, loc);
const TColgp_Array1OfPnt2d& uvNodes = triFace->UVNodes();

得到三角网格顶点的每个uv坐标,但是这个uv坐标其实是aFace的曲面方程的自变量F(u,v),如果将这个值设置给OSG,Ogre或者OpenGL
的纹理坐标,一般显示的曲面是扭曲的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NQpZA9Rw-1722128179703)(https://i-blog.csdnimg.cn/direct/358e73ea46f3403296f9d3f531c316af.png)]

下面计算曲面的纹理使得均匀贴敷,要通过uv算点Vi在曲面曲纹坐标网上的实际的u_s, v_s
经常matplot画的曲面上的黑色的网格就是曲纹坐标网
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ajz23Pma-1722128179705)(https://i-blog.csdnimg.cn/direct/420f124456014f4c874ec7642eae202e.png)]

const TColgp_Array1OfPnt2d& uvNodes = triFace->UVNodes();
int nNodes = aFace的顶点个数
for (Standard_Integer i = 1; i <= nNodes; i++)
{
    gp_Pnt2d uv = uvNodes.Value(i); // 得到顶点Vi的uv
    float unitscale = 0.1; // 单位缩放, 纹理尺寸和曲面尺度比例
    if (adasurf.GetType() == GeomAbs_SurfaceType::GeomAbs_Plane) // 如果是平面就用uv做纹理坐标
    {
         vertUVs->push_back(osg::Vec2(uv.X() * unitscale, uv.Y() * unitscale));
    }
    else // 否则计算Vi的两条曲面上的
    {
         // 得到u值(或者v值)固定的沿着v(或u)走势的曲面上的曲线, 计算出曲面上相对原点的路径u_s和v_s
         // 作为纹理
         auto ucurve = adasurf.Surface().Surface()->UIso(uv.X());
         GeomAdaptor_Curve adacurve_u(ucurve);
         double v_s = CPnts_AbscissaPoint::Length(adacurve_u, 0.0, uv.Y());

         auto vcurve = adasurf.Surface().Surface()->VIso(uv.Y());
         GeomAdaptor_Curve adacurve_v(vcurve);
         double u_s = CPnts_AbscissaPoint::Length(adacurve_v, 0.0, uv.X());

         vertUVs->push_back(osg::Vec2(u_s * unitscale, v_s * unitscale));
    }
    

这样结果就是正确了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RozYlvWC-1722128179706)(https://i-blog.csdnimg.cn/direct/1bda21a7a6794940875fb09b2a56a1a4.png)]

说明:圆柱体的纹理看起来“均匀”,是因为圆柱曲面参数方程是:
f_x(u, v)=rcos(u)
f_y(u, v)=r
sin(u)
f_z(u, v)=v
所以如果纹理直接用u,它的取值范围是[0.0,2PI]
贴出来就感觉圆周方向纹理被收缩了,所以它的UIso曲线是个圆,这样就得到了实际的us,相当于us=ur
其它二次曲面纹理要铺成什么样子要具体分析,例如圆环曲面tour有两个半径它的us=R
u vs=r*v

### OpenCASCADE 网格生成及处理教程 #### 创建三角形网格 为了利用OpenCASCADE库进行网格处理,首先需要创建一个基础的三角形网格。这可以通过调用`BRepMesh_IncrementalMesh`类来完成。该类提供了多种参数设置选项,允许用户控制网格的质量和密度[^1]。 ```cpp TopoDS_Shape myShape; // 假设这是要离散化的形状 Standard_Real linearDeflection = 0.01; Standard_Real angularDeflection = 0.5 * M_PI / 180.; Handle(BRepTools_ReShape) reshape = new BRepTools_ReShape(); BRepMesh_IncrementalMesh mesh(myShape, linearDeflection); mesh.Perform(angularDeflection); // 执行网格划分 ``` 这段代码展示了如何基于给定的几何体对象`myShape`构建增量式的三角剖分,并设置了线性和角度偏转作为精度指标[^2]。 #### 操作网格元素 一旦有了基本的三角网之后,则可进一步对其进行编辑。具体来说就是修改其构成要素——即顶点、边以及面片的信息。这些操作通常涉及到访问并调整内部的数据结构,在某些情况下可能还需要重新计算相邻关系以保持拓扑一致性。 对于更复杂的变换需求,比如拉伸某个特定区域内的所有节点位置或是旋转整个表面朝向,可以借助于专门设计好的算法工具包来进行高效稳定的更改[^4]。 #### 输出至文件格式 当完成了所有的预处理步骤后,最终形成的高质量三维模型往往会被导出成标准交换形式以便后续应用。在这方面,OpenCASCADE支持两种主要途径: - **VRML**: 支持将实体映射到由一系列多边形单元组成的视觉描述中去;可以选择仅保留轮廓线条(线框模式),也可以填充完整的色彩贴图(阴影模式)[^3]。 - **STL**: 主要用作增材制造行业的输入规格之一;由于只记录外表面边界上的坐标集合,因此非常适合用来指导打印机逐层堆积材料成型过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值