文档章节

OpenNURBS to OpenCASCADE

eryar
 eryar
发布于 2014/11/23 12:34
字数 1584
阅读 149
收藏 0

OpenNURBS to OpenCASCADE

eryar@163.com

Abstract. The OpenNURBS initiative provides CAD/CAM/CAE and computer graphics software developers the tools to accurately transfer 3D geometry between applications. The OpenNURBS C++ source code is clean and fairly simple. The OpenNURBS Toolkit is intended for use by C++ and .NET programmers. The toolkit includes complete source code to create a library that will read and write 3dm files. OpenCASCADE providing services for 3D surface and solid modeling, CAD data exchange, and visulization. Most of OCCT functionality is available in the form of C++ libraries. If can convert OpenNURBS curve/surface to OpenCASCADE, then it will fill the gap of data exchange between OpenNURBS and OpenCASCADE. 

Key Words. OpenCASCADE, OpenNURBS, NURBS, 3DM, DataExchange 

1. Introduction

OpenNURBS 旨在为CAD、CAM、CAE与计算机图形软件开发人员提供一个在不同的软件间精确转换 3D 几何的工具。OpenNURBS 所提供的功能包括: 

v 可以读、写3DM文件格式的C ++原代码库,支持目前的 Microsoft、Apple与 Gnu for Windows、Windows X64、Mac与Linux编绎器... 

v 可以读、写3DM文件格式的.NET 源代码库。 

v 品质保证与版本控制。 

v 技术支持。 

与其他开源产品的开发平台不同之处: 

v 鼓励使用在商业用途。 

v 提供免费的开发工具与技术支持。 

v 无任何约束,不受版权与公共版权(copyleft )条款约束。 

v 鼓励但不强迫用户分享自己的研发成果。 

NURBS是当前流行几何造型系统中通用的曲线曲面表达形式,OpenNURBS开源库提供了NURBS曲线曲面的数据表达,但缺少一些造型算法,而OpenCASCADE中提供了大量的造型算法。通过将OpenNURBS中的曲线曲面转换到OpenCASCADE中,就可以将OpenNURBS和OpenCASCADE结合起来使用了。 

OpenNURBS中的代码简洁,易懂;OpenCASCADE的造型功能强大。所以先将OpenNURBS中的曲线曲面转换到OpenCASCADE中,为OpenCASCADE的3DM格式的数据交换打下基础。 

2.Convert OpenNURBS Curve 

OpenNURBS中统一使用NURBS方式来表达曲线和曲面。OpenCASCADE中对应NURBS曲线的类为Geom_BSplineCurve。因此,可以将OpenNURBS的曲线转换到OpenCASCADE中。转换时需要注意节点矢量Knot Vector的方式有很大的不同。OpenNURBS中的节点矢量是所有的节点值,包括了重节点,而且在节点矢量的首尾还少了两个节点。OpenCASCADE中的节点矢量由不包含重复节点的节点矢量及其重数来构造。其它数据基本相同,将转换曲线的示例代码列出如下: 

/**
* @breif Convert OpenNURBS NURBS curve to OpenCASCADE Geom_BSplineCurve.
* @param [in] theCurve opennurbs nurbs curve;
* @param [in] theBRepFile the curve is in brep file of opencascade;
* @note pay attention to the knots of opennurbs nurbs curve/surface.
*/
void ConvertCurve(const ON_NurbsCurve& theCurve, const std::string& theBRepFile)
{
    TColgp_Array1OfPnt aPoles(1, theCurve.CVCount());
    TColStd_Array1OfReal aWeights(1, theCurve.CVCount());

    TColStd_Array1OfReal aKnotSequence(1, theCurve.KnotCount() + 2);

    bool IsRational = theCurve.IsRational();
    bool IsPeriodic = (theCurve.IsPeriodic()) ? true: false;

    // Control point and its weight.
    for (int i = 0; i < theCurve.CVCount(); ++i)
    {
        if (IsRational)
        {
            ON_4dPoint aPole;

            theCurve.GetCV(i, aPole);

            aPoles.SetValue(i + 1, gp_Pnt(aPole.x / aPole.w, aPole.y / aPole.w, aPole.z / aPole.w));
            aWeights.SetValue(i + 1, aPole.w);
        }
        else
        {
            ON_3dPoint aPole;

            theCurve.GetCV(i, aPole);

            aPoles.SetValue(i + 1, gp_Pnt(aPole.x, aPole.y, aPole.z));
        }
    }

    // Knot vector and its multiplicity.
    for (int i = 0; i < theCurve.KnotCount(); ++i)
    {
        aKnotSequence.SetValue(i + 2, theCurve.Knot(i));
    }

    aKnotSequence.SetValue(aKnotSequence.Lower(), theCurve.Knot(0));
    aKnotSequence.SetValue(aKnotSequence.Upper(), theCurve.Knot(theCurve.KnotCount() - 1));

    TColStd_Array1OfReal aKnots(1, BSplCLib::KnotsLength(aKnotSequence, IsPeriodic));
    TColStd_Array1OfInteger aMultiplicities(1, aKnots.Upper());

    BSplCLib::Knots(aKnotSequence, aKnots, aMultiplicities);

    Handle_Geom_BSplineCurve aBSplineCurve = new Geom_BSplineCurve(
        aPoles, aWeights, aKnots, aMultiplicities,
        theCurve.Degree(), theCurve.IsPeriodic());

    GeomTools_CurveSet::PrintCurve(aBSplineCurve, std::cout);

    TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aBSplineCurve);
    
    BRepTools::Write(anEdge, theBRepFile.c_str());
}

程序先转换控制顶点,若是有理曲线,还要设置控制顶点的权值w。在转换节点矢量时,使用了BSplCLib::Knots()函数将OpenNURBS的节点矢量转换为OpenCASCADE的形式,并补齐了缺少的端部的两个节点。最后为了在OpenCASCADE中显示转换结果,将曲线生成TopoDS_Edge并保存为BRep格式,方便在Draw Test Harness中查看结果如下图所示: 

wps_clip_image-11344

Figure 2.1 OpenNURBS nurbs circle in OpenCASCADE Draw Test Harness 

3.Convert OpenNURBS Surface

OpenNURBS曲面的转换同样也需要注意u, v方向上的节点矢量的问题,和曲线的转换类似。除此之外就是把相同的属性分别赋值即可,列出代码如下所示: 

/**
* @breif Convert OpenNURBS NURBS surface to OpenCASCADE Geom_BSplineSurface.
* @param [in] theSurface opennurbs nurbs surface;
* @param [in] theBRepFile the surface is in the brep file of opencascade;
* @note pay attention to the knots of opennurbs nurbs curve/surface.
*/
void ConvertSurface(const ON_NurbsSurface& theSurface, const std::string& theBRepFile)
{
    TColgp_Array2OfPnt aPoles(1, theSurface.CVCount(0), 1, theSurface.CVCount(1));
    TColStd_Array2OfReal aWeights(1, theSurface.CVCount(0), 1, theSurface.CVCount(1));

    TColStd_Array1OfReal aUKnotSequence(1, theSurface.KnotCount(0) + 2);
    TColStd_Array1OfReal aVKnotSequence(1, theSurface.KnotCount(1) + 2);

    bool IsRational = theSurface.IsRational();
    bool IsUPeriodic = (theSurface.IsPeriodic(0)) ? true: false;
    bool IsVPeriodic = (theSurface.IsPeriodic(1)) ? true: false;

    // control point and its weight.
    for (int i = 0; i < theSurface.CVCount(0); ++i)
    {
        for (int j = 0; j < theSurface.CVCount(1); ++j)
        {
            if (IsRational)
            {
                ON_4dPoint aPole;

                theSurface.GetCV(i, j, aPole);

                aPoles.SetValue(i + 1, j + 1, gp_Pnt(aPole.x / aPole.w, aPole.y / aPole.w, aPole.z / aPole.w));
                aWeights.SetValue(i + 1, j + 1, aPole.w);
            }
            else
            {
                ON_3dPoint aPole;

                theSurface.GetCV(i, j, aPole);

                aPoles.SetValue(i + 1, j + 1, gp_Pnt(aPole.x, aPole.y, aPole.z));
            }
            
        }
    }

    // Knot vector and its multiplicity.
    for (int i = 0; i < theSurface.KnotCount(0); ++i)
    {
        aUKnotSequence.SetValue(i + 2, theSurface.Knot(0, i));
    }

    aUKnotSequence.SetValue(aUKnotSequence.Lower(), theSurface.Knot(0, 0));
    aUKnotSequence.SetValue(aUKnotSequence.Upper(), theSurface.Knot(0, theSurface.KnotCount(0) - 1));

    TColStd_Array1OfReal aUKnots(1, BSplCLib::KnotsLength(aUKnotSequence, IsUPeriodic));
    TColStd_Array1OfInteger aUMults(1, aUKnots.Upper());

    BSplCLib::Knots(aUKnotSequence, aUKnots, aUMults);

    for (int j = 0; j < theSurface.KnotCount(1); ++j)
    {
        aVKnotSequence.SetValue(j + 2, theSurface.Knot(1, j));
    }

    aVKnotSequence.SetValue(aVKnotSequence.Lower(), theSurface.Knot(1, 0));
    aVKnotSequence.SetValue(aVKnotSequence.Upper(), theSurface.Knot(1, theSurface.KnotCount(1) - 1));

    TColStd_Array1OfReal aVKnots(1, BSplCLib::KnotsLength(aVKnotSequence, IsVPeriodic));
    TColStd_Array1OfInteger aVMults(1, aVKnots.Upper());

    BSplCLib::Knots(aVKnotSequence, aVKnots, aVMults);

    Handle_Geom_BSplineSurface aBSplineSurface = new Geom_BSplineSurface(aPoles,
        aWeights, aUKnots, aVKnots, aUMults, aVMults,
        theSurface.Degree(0), theSurface.Degree(1),
        IsUPeriodic, IsVPeriodic);

    GeomTools_SurfaceSet::PrintSurface(aBSplineSurface, std::cout);

  TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aBSplineSurface, Precision::Confusion());
  
    BRepTools::Write(aFace, theBRepFile.c_str());
}

转换过程与曲线的类似,只是多了v方向上的处理。以上两个函数分别实现曲线曲面的转换,完整程序可以在本文后面的链接中下载。以圆柱面和球面为例,测试了一下转换效果,在Draw Test Harness中显示结果如下图所示: 

wps_clip_image-7205

Figure 3.1 OpenNURBS nurbs sphere in OpenCASCADE Draw Test Harness 

wps_clip_image-6073

Figure 3.2 OpenNURBS nurbs cylinder in OpenCASCADE Draw Test Harness 

由上图可知,OpenCASCADE中的Geom_BSplineCurve/Geom_BSplineSurface可以完美表示OpenNURBS中的曲线曲面,不过有最高次数为25次的限制。 

4.Conclusion

现可看出,OpenNURBS中的曲线曲面可以转换成OpenCASCADE中。不过在转换时需要注意OpenNURBS的节点矢量数据与教科书中及OpenCASCADE中不同,需要做些处理。还有需要注意的事项就是OpenNURBS中数组是从0开始的,而在OpenCASCADE中可以指定为从1开始。 

将OpenNURBS的曲线曲面转换成OpenCASCADE的曲线曲面后,下一步准备将OpenNURBS中的BRep体也转换到OpenCASCADE中,从而对BRep表示形式做进一步的学习。 

5. References

1. OpenNURBS Web: http://www.rhino3d.com/opennurbs

2. Les Piegl, Wayne Tiller. The NURBS Book. Springer-Verlag. 1997 

3. 赵罡,穆国旺,王拉柱译. 非均匀有理B样条. 清华大学出版社. 2010 

 

PDF Version and Code: OpenNURBS to OpenCASCADE

© 著作权归作者所有

共有 人打赏支持
eryar
粉丝 21
博文 127
码字总数 227012
作品 0
武汉
私信 提问
OpenCASCADE Make Primitives-Box

OpenCASCADE Make Primitives-Box eryar@163.com Abstract. By making a simple box to demonstrate the BRep data structure of the OpenCASCADE. The construction method is different fr......

eryar
2014/11/23
0
0
FreeCAD 0.16 发布,开源 CAD/CAE 工具

FreeCAD 0.16 发布了,FreeCAD是一个基于OpenCASCADE的开源CAD/CAE工具。 OpenCASCADE是一套开源的CAD/CAM/CAE几何模型核心,来自法国Matra Datavision公司,是著名的CAD软件EUCLID的开发平台...

oschina
2016/04/21
2.9K
2
Building OpenCascade on Windows with Visual Studio

Building OpenCascade on Windows with Visual Studio eryar@163.com 摘要Abstract:详细说明OpenCascade的编译配置过程,希望对你编译OpenCascacde有所帮助。本文内容来自OCCT的Overview文档...

eryar
2013/09/23
0
0
如何将openCASCADE和c++结合起来,哪位牛人能不能给我指点指点啊.

如何将openCASCADE和c++结合起来,哪位牛人能不能给我指点指点啊.我现在正想用openCASCADE和c++结合起来做一个像cad软件的东西。

chenchenxixi
2012/07/09
1K
2
FreeCAD 0.17Pre 发布,开源 CAD/CAE 工具

FreeCAD 0.17Pre 发布了。 FreeCAD是一个基于OpenCASCADE的开源CAD/CAE工具。 OpenCASCADE是一套开源的CAD/CAM/CAE几何模型核心,来自法国Matra Datavision公司,是著名的CAD软件EUCLID的开发...

达尔文
2016/10/10
2.3K
3

没有更多内容

加载失败,请刷新页面

加载更多

大数据剖析热点新闻:996、巴黎圣母院、奔驰维权为什么成为本周热搜

智能大数据专家表示:每一段重要的时期都会有一串隐秘的数字密码,请往下看: 本周共有50条新闻,作为嗅嗅的样本进行数据分析,得出以下统计图: 1.新闻热词折线统计图 在新闻标题及正文中,...

forespider
37分钟前
1
0
Coding and Paper Letter(六十四)

资源整理。 1 Coding: 1.交互式瓦片编辑器。 tile playground 2.R语言包autokeras,autokeras的R接口。autokeras是一个开源的自动机器学习的软件。 autokeras 3.斯坦福网络分析平台,用于网络...

胖胖雕
今天
1
0
最简单的cd命令是个大坑!

BASH Shell 是大多 Linux 发行版的默认 shell,BASH 有一些自己的内置命令,cd 就是其中的一个。 在centos6里面,系统中不存在 cd 的二进制文件。但是你仍然可以运行该命令,这是因为 cd 是 ...

gaolongquan
今天
1
0
spring获取bean的几种方式

使用jdk:1.8、maven:3.3.3 spring获取Bean的方式 pom.xml文件内容: <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="......

Vincent-Duan
今天
3
0
一段话系列-Linux中IO的同步、异步、阻塞、非阻塞

首先我们框定一下背景,我们探讨的是Linux系统下的IO模型。 同步和异步是针对内核操作数据而言的,同步是指内核串行顺序操作数据,异步是指内核并行(或并发)操作数据,然后通过回调的方式通...

EasyProgramming
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部