Opencascade之STL可视化与选取渲染风格

2023-11-11

在Opencascade中,STL模型可以的可视化有两种方式:

一、STL模型加载为Shape对象,再可视化

1.1 STL模型加载为Shape对象

TopoDS_Shape  aShape;
try
{
	StlAPI_Reader reader;
	reader.Read(aShape, theFile);
}
return aShape;

这种渲染STL模型的方式,优点是与Shape的可视化、Shape对象的选取方式保持了一致;缺点时,加载STL模型比较慢,尤其时模型数据比较大时尤其明显。

STL模型加载为Shape渲染,并选取三角面的效果:

 

二、STL模型使用MeshVS_Mesh可视化

STL模型使用MeshVS_Mesh渲染时,优点是加载速度快、缺点是渲染、选取逻辑与Shape是不一致的。

2.1 加载STL模型为Poly_Triangulation

Handle(Poly_Triangulation) aMesh;
try
{
    aMesh = RWStl::ReadFile(utfFile.c_str());
}catch(...){}
return aMesh;

2.2 为MehsVS_Mesh对象准备数据源类

#include <MeshVS_DataSource.hxx>
#include <Poly_Triangulation.hxx>
#include <TColStd_HArray2OfInteger.hxx>
#include <TColStd_HArray2OfReal.hxx>

class AMeshVS_DataSource : public MeshVS_DataSource
{
    DEFINE_STANDARD_RTTIEXT(AMeshVS_DataSource, MeshVS_DataSource)
    public:
        AMeshVS_DataSource(const Handle(Poly_Triangulation)& plyTri);
        Standard_Boolean GetGeom(
                    const Standard_Integer ID,
                    const Standard_Boolean IsElement,
                    TColStd_Array1OfReal& Coords,
                    Standard_Integer& NbNodes,
                    MeshVS_EntityType& Type) const Standard_OVERRIDE;
        Standard_Boolean GetGeomType(
                    const Standard_Integer ID,
                    const Standard_Boolean IsElement,
                    MeshVS_EntityType& Type) const Standard_OVERRIDE;
        Standard_Address GetAddr(
                    const Standard_Integer ID,
                    const Standard_Boolean IsElement) const Standard_OVERRIDE;
        Standard_Boolean GetNodesByElement(
                    const Standard_Integer ID,
                    TColStd_Array1OfInteger& NodeIDs,
                    Standard_Integer& NbNodes) const Standard_OVERRIDE;
        const TColStd_PackedMapOfInteger& GetAllNodes() const Standard_OVERRIDE;
        const TColStd_PackedMapOfInteger& GetAllElements() const Standard_OVERRIDE;
        Standard_Boolean GetNormal(
                    const Standard_Integer Id,
                    const Standard_Integer Max,
                    Standard_Real& nx,
                    Standard_Real& ny,
                    Standard_Real& nz) const Standard_OVERRIDE;

        private:
            TColStd_PackedMapOfInteger myNodes;
            TColStd_PackedMapOfInteger myElements;
            Handle(TColStd_HArray2OfInteger) myElemNodes;
            Handle(TColStd_HArray2OfReal) myNodeCoords;
            Handle(TColStd_HArray2OfReal) myElemNormals;
    };
#include "ameshvs_datasource.h"

#include <Precision.hxx>


IMPLEMENT_STANDARD_RTTIEXT(AMeshVS_DataSource, MeshVS_DataSource)

AMeshVS_DataSource::SinnMeshVS_DataSource(const Handle(Poly_Triangulation)& plyTri)
{
    if( !plyTri.IsNull() )
    {
        const Standard_Integer aNbNodes = plyTri->NbNodes();
        myNodeCoords = new TColStd_HArray2OfReal (1, aNbNodes, 1, 3);

        for (Standard_Integer i = 1; i <= aNbNodes; i++)
        {
            myNodes.Add( i );
            gp_Pnt xyz = plyTri->Node (i);

            myNodeCoords->SetValue(i, 1, xyz.X());
            myNodeCoords->SetValue(i, 2, xyz.Y());
            myNodeCoords->SetValue(i, 3, xyz.Z());
        }

        const Standard_Integer aNbTris = plyTri->NbTriangles();
        myElemNormals = new TColStd_HArray2OfReal(1, aNbTris, 1, 3);
        myElemNodes = new TColStd_HArray2OfInteger(1, aNbTris, 1, 3);

        for (Standard_Integer i = 1; i <= aNbTris; i++)
        {
            myElements.Add( i );

            const Poly_Triangle aTri = plyTri->Triangle (i);

            Standard_Integer V[3];
            aTri.Get (V[0], V[1], V[2]);

            const gp_Pnt aP1 = plyTri->Node (V[0]);
            const gp_Pnt aP2 = plyTri->Node (V[1]);
            const gp_Pnt aP3 = plyTri->Node (V[2]);

            gp_Vec aV1(aP1, aP2);
            gp_Vec aV2(aP2, aP3);

            gp_Vec aN = aV1.Crossed(aV2);
            if (aN.SquareMagnitude() > Precision::SquareConfusion())
                aN.Normalize();
            else
                aN.SetCoord(0.0, 0.0, 0.0);

            for (Standard_Integer j = 0; j < 3; j++)
            {
                myElemNodes->SetValue(i, j+1, V[j]);
            }

            myElemNormals->SetValue (i, 1, aN.X());
            myElemNormals->SetValue (i, 2, aN.Y());
            myElemNormals->SetValue (i, 3, aN.Z());
        }
      }
}

Standard_Boolean AMeshVS_DataSource::GetGeom(
        const Standard_Integer ID,
        const Standard_Boolean IsElement,
        TColStd_Array1OfReal&  Coords,
        Standard_Integer&      NbNodes,
        MeshVS_EntityType&     Type) const
{
    if( myNodes.Extent() == 0 )
        return Standard_False;

    if( IsElement )
    {//三角面
        if( ID>=1 && ID<=myElements.Extent() )
        {
            Type = MeshVS_ET_Face;
            NbNodes = 3;

            for( Standard_Integer i = 1, k = 1; i <= 3; i++ )
            {
                Standard_Integer IdxNode = myElemNodes->Value(ID, i);
                for(Standard_Integer j = 1; j <= 3; j++, k++ )
                    Coords(k) = myNodeCoords->Value(IdxNode, j);
            }

            return Standard_True;
        }
        else
            return Standard_False;
    }
    else if( ID>=1 && ID<=myNodes.Extent() )
    {//点
        Type = MeshVS_ET_Node;
        NbNodes = 1;

        Coords( 1 ) = myNodeCoords->Value(ID, 1);
        Coords( 2 ) = myNodeCoords->Value(ID, 2);
        Coords( 3 ) = myNodeCoords->Value(ID, 3);
        return Standard_True;
    }
    else
        return Standard_False;
}

Standard_Boolean AMeshVS_DataSource::GetGeomType(
        const Standard_Integer theID,
        const Standard_Boolean IsElement,
        MeshVS_EntityType& theType) const
{
    if( myNodes.Extent() == 0 )
        return Standard_False;

    if (IsElement)
    {
        if (theID >= 1 && theID <= myElements.Extent())
        {
            theType = MeshVS_ET_Face;
            return Standard_True;
        }
    }
    else if (theID >= 1 && theID <= myNodes.Extent())
    {
        theType = MeshVS_ET_Node;
        return Standard_True;
    }
    return Standard_False;
}

Standard_Address AMeshVS_DataSource::GetAddr(
        const Standard_Integer /*ID*/,
        const Standard_Boolean /*IsElement*/) const
{
    return NULL;
}

Standard_Boolean AMeshVS_DataSource::GetNodesByElement(
        const Standard_Integer ID,
        TColStd_Array1OfInteger& theNodeIDs,
        Standard_Integer& /*theNbNodes*/) const
{
    if( myNodes.Extent() == 0 )
        return Standard_False;

    if (ID >= 1 && ID <= myElements.Extent() && theNodeIDs.Length() >= 3)
    {
        Standard_Integer aLow = theNodeIDs.Lower();
        theNodeIDs(aLow) = myElemNodes->Value(ID, 1);
        theNodeIDs(aLow + 1) = myElemNodes->Value(ID, 2);
        theNodeIDs(aLow + 2) = myElemNodes->Value(ID, 3);
        return Standard_True;
    }
    return Standard_False;
}

const TColStd_PackedMapOfInteger& AMeshVS_DataSource::GetAllNodes() const
{
    return myNodes;
}

const TColStd_PackedMapOfInteger& AMeshVS_DataSource::GetAllElements() const
{
    return myElements;
}

Standard_Boolean AMeshVS_DataSource::GetNormal(
        const Standard_Integer Id,
        const Standard_Integer Max,
        Standard_Real& nx,
        Standard_Real& ny,
        Standard_Real& nz) const
{
    if( myNodes.Extent() == 0 )
        return Standard_False;

    if (Id >= 1 && Id <= myElements.Extent() && Max >= 3)
    {
            nx = myElemNormals->Value(Id, 1);
            ny = myElemNormals->Value(Id, 2);
            nz = myElemNormals->Value(Id, 3);
            return Standard_True;
    }
    else
        return Standard_False;
}

2.3 渲染Poly_Triangulation

Handle(AMeshVS_Mesh) myAisObj = new AMeshVS_Mesh();
Handle(AMeshVS_DataSource) aDS = new AMeshVS_DataSource(myPlyTri/*Poly_Triangulation*/);    
myAisObj->SetDataSource(aDS);
Handle(MeshVS_MeshPrsBuilder) aMeshPrsBuilder = new MeshVS_MeshPrsBuilder(myAisObj.operator->());
myAisObj->AddBuilder(aMeshPrsBuilder,Standard_True);

//点加入可选集
Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
const Standard_Integer aLen = aDS->GetAllNodes().Extent();
for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
    aNodes->ChangeMap().Add( anIndex );
myAisObj->SetSelectableNodes ( aNodes );
//显示模式
myAisObj->SetDisplayMode(MeshVS_DMF_Shading);
myAisObj->SetMeshSelMethod(MeshVS_MSM_PRECISE);
myAisObj->SetHilightMode(MeshVS_DMF_Shading);
myAisObj->SetTransparency(0.4);
//设置颜色
myAisObj->GetDrawer()->SetColor(MeshVS_DA_InteriorColor, Quantity_NOC_GOLD);
myAisObj->GetDrawer()->SetColor(MeshVS_DA_EdgeColor, Quantity_NOC_BROWN4);
//不显示点
myAisObj->GetDrawer()->SetBoolean(MeshVS_DA_DisplayNodes, Standard_False);
//显示边
myAisObj->GetDrawer()->SetBoolean(MeshVS_DA_ShowEdges, Standard_True);

2.4 设置三角网拾取渲染风格

AMeshVS_Mesh::AMeshVS_Mesh(const Standard_Boolean theIsAllowOverlapped)
    :MeshVS_Mesh(theIsAllowOverlapped)
{    
    //点被选中的风格
    mySelectionDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_BALL );
    mySelectionDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_RED );
    mySelectionDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 5.0 );
    //三角面被选中的风格
    mySelectionDrawer->SetColor ( MeshVS_DA_BeamColor,Quantity_NOC_RED);
    mySelectionDrawer->SetDouble( MeshVS_DA_BeamWidth, 1.5 );
    //设置整体拾取时的颜色
    this->HilightAttributes()->SetTransparency(0.6);
    this->HilightAttributes()->SetColor(Quantity_NOC_BLUE);
    //点被检测到的风格
    myHilightDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_BALL );
    myHilightDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_GRAY80 );
    myHilightDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 5.0 );
    //设置整体被检测到时的透明度
    this->myDynHilightDrawer->SetTransparency(0.6);

}

整体选择时的风格:

点被选取时的风格

三角面被选取的风格:

 

 

 

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

Opencascade之STL可视化与选取渲染风格 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile

随机推荐