首页 > 其他分享 >VTK+OCC显示CAD模型

VTK+OCC显示CAD模型

时间:2023-07-22 13:55:47浏览次数:45  
标签:VTK iren Shape CAD renWin include OCC vtkNew

VTK是一款十分优秀的可视化套件,开源且功能强大,基本上可以满足有限元领域的全部可视化需求。遗憾的是,VTK不支持CAD模型(如igs、stp格式的模型)的显示。

在网上搜索后可以发现,在不花钱的情况下,想要显示和处理CAD模型,基本上都得使用OpenCasCade,即OCC。OCC有自己的可视化系统,也可以集成在Qt中,网上也有相关的Demo。但对我而已,OCC自己的可视化系统还是太复杂了。为了一个简单的显示功能,专门去深入学习OCC的可视化系统还是太难为人了。如果能直接用VTK显示OCC的模型就好了。

万幸,OCC也知道很多人和我有一样的需求,在6.8版本开发了VIS(VTK Integration Services)功能,之后的版本就可以使用VTK进行模型的可视化了。

为了使用VIS功能,编译OCC的时候需要选择USE_VTK的选项,编译完成后,将生成TKIVtk、TKIVtkDraw的动态库和静态库。如果编译路径下有这两个库,说明VIS的功能是编译成功了。

编写一个最小案例看看显示效果。

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(occvtk LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(VTK_DIR "C:/Program Files/VTK/lib/cmake/vtk-9.1")

find_package(VTK COMPONENTS 
 vtkCommonCore
 vtkFiltersCore
 vtkCommonDataModel
 vtkInteractionStyle
 vtkRenderingContextOpenGL2
 vtkRenderingCore
 vtkRenderingFreeType
 vtkRenderingGL2PSOpenGL2
 vtkRenderingOpenGL2
 QUIET
)

include_directories("C:/Program Files/OCCT/inc")
link_directories("C:/Program Files/OCCT/win64/vc14/lib")

add_executable(make_box make_box.cpp)
target_link_libraries(make_box 
    TKPrim TKIVtk TKMath TKernel 
    TKTopAlgo TKGeomAlgo TKV3d 
    ${VTK_LIBRARIES})

make_box.cpp 文件

#include <BRepPrimAPI_MakeBox.hxx>
#include <IVtkTools_ShapeDataSource.hxx>
#include <vtkType.h>
#include <vtkAutoInit.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataMapper.h>
#include <vtkInteractorStyleTrackballCamera.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)

int main()
{
    BRepPrimAPI_MakeBox mkBox(1., 2., 3);
    const TopoDS_Shape& shape = mkBox.Shape();

    vtkNew<IVtkTools_ShapeDataSource> occSource;
    occSource->SetShape(new IVtkOCC_Shape(shape));

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(occSource->GetOutputPort());
    
    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    
    vtkNew<vtkRenderer> ren;
    ren->AddActor(actor);

    vtkNew<vtkRenderWindow> renWin;
    renWin->AddRenderer(ren);
    renWin->SetSize(640, 640);

    vtkNew<vtkInteractorStyleTrackballCamera> istyle;
    vtkNew<vtkRenderWindowInteractor> iren;

    iren->SetRenderWindow(renWin);
    iren->SetInteractorStyle(istyle);

    renWin->Render();
    iren->Start();

    return 0;
}

显示效果如下:

看着还不错。但模型中有一堆白线,有没有什么方法去掉呢。

经过搜索,发现这个白线叫什么iso line,可以通过IVtkOCC_ShapeMesher去掉。

查看上面的代码,是没有涉及到IVtkOCC_ShapeMesher的。继续查阅文档,发现VIS有两种接口,一种是high-level API,就是上面那种,另一种是low-level API,可以控制的东西更多一些。

现在试试low-level API。

在CMakeLists.txt文件中添加:


add_executable(make_box2 make_box2.cpp)
target_link_libraries(make_box2 
    TKPrim TKIVtk TKMath TKernel 
    TKTopAlgo TKGeomAlgo TKV3d 
    ${VTK_LIBRARIES})

编写make_box2.cpp文件:

#include <BRepPrimAPI_MakeBox.hxx>
#include <IVtkVTK_ShapeData.hxx>
#include <IVtkOCC_ShapeMesher.hxx>
#include <vtkType.h>
#include <vtkAutoInit.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataMapper.h>
#include <vtkInteractorStyleTrackballCamera.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)

int main()
{
    BRepPrimAPI_MakeBox mkBox(1., 2., 3);
    const TopoDS_Shape& shape = mkBox.Shape();

    IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(shape);
    IVtkVTK_ShapeData::Handle aDataImpl = new IVtkVTK_ShapeData();
    IVtk_IShapeMesher::Handle aMesher = new IVtkOCC_ShapeMesher(0.0001, 12.0*M_PI/180, 0, 0);
    aMesher->Build(aShapeImpl, aDataImpl);
    vtkPolyData* aPolyData = aDataImpl->getVtkPolyData();

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputData(aPolyData);
    
    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    
    vtkNew<vtkRenderer> ren;
    ren->AddActor(actor);

    vtkNew<vtkRenderWindow> renWin;
    renWin->AddRenderer(ren);
    renWin->SetSize(960, 800);

    vtkNew<vtkInteractorStyleTrackballCamera> istyle;
    vtkNew<vtkRenderWindowInteractor> iren;

    iren->SetRenderWindow(renWin);
    iren->SetInteractorStyle(istyle);

    renWin->Render();
    iren->Start();

    return 0;
}

这一次的显示效果如下:

可以看到,白线没有了。

试一下显示stp文件。

在CMakeLists.txt文件中添加:

add_executable(import_step2 import_step2.cpp)
target_link_libraries(import_step2 
    TKSTEP TKIVtk TKV3d 
    TKGeomAlgo TKMath TKXSBase TKernel 
    ${VTK_LIBRARIES})

import_step2.cpp文件:

#include <STEPControl_Reader.hxx>
#include <Standard_Integer.hxx>
#include <TopoDS_Shape.hxx>
#include <IFSelect_ReturnStatus.hxx>
#include <IFSelect_PrintCount.hxx>
#include <IVtkVTK_ShapeData.hxx>
#include <IVtkOCC_ShapeMesher.hxx>
#include <vtkType.h>
#include <vtkAutoInit.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataMapper.h>
#include <vtkInteractorStyleTrackballCamera.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)

int main()
{
    STEPControl_Reader reader;
    IFSelect_ReturnStatus stat = reader.ReadFile("assembly_solid.stp");
    IFSelect_PrintCount mode = IFSelect_CountByItem;
    Standard_Integer NbRoots = reader.NbRootsForTransfer();
    Standard_Integer num = reader.TransferRoots();
    Standard_Integer NbTrans = reader.TransferRoots();
    TopoDS_Shape result = reader.OneShape();
    TopoDS_Shape shape = reader.Shape();

    Handle_IVtkOCC_Shape aShapeImpl = new IVtkOCC_Shape(shape);
    Handle_IVtkVTK_ShapeData aDataImpl = new IVtkVTK_ShapeData();
    Handle_IVtk_IShapeMesher aMesher = new IVtkOCC_ShapeMesher(0.0001, 12.0 * M_PI / 180, 0, 0);
    aMesher->Build(aShapeImpl, aDataImpl);
    vtkPolyData* aPolyData = aDataImpl->getVtkPolyData();

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputData(aPolyData);

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);

    vtkNew<vtkRenderer> ren;
    ren->AddActor(actor);

    vtkNew<vtkRenderWindow> renWin;
    renWin->AddRenderer(ren);
    renWin->SetSize(960, 800);

    vtkNew<vtkInteractorStyleTrackballCamera> istyle;
    vtkNew<vtkRenderWindowInteractor> iren;

    iren->SetRenderWindow(renWin);
    iren->SetInteractorStyle(istyle);

    renWin->Render();
    iren->Start();

    return 0;
}

这个效果就不是很理想了,弧面被离散成了很多小面片,不是很光滑。

继续查看OCC的文档看看有什么解决方法,发现可以使用vtkPolyDataNormals进行光滑。试一下效果。

在CMakeLists.txt文件中添加:

add_executable(import_step3 import_step3.cpp)
target_link_libraries(import_step3 
    TKSTEP TKIVtk TKV3d TKGeomAlgo 
    TKMath TKXSBase TKernel 
    ${VTK_LIBRARIES})

import_step3.cpp文件:

#include <STEPControl_Reader.hxx>
#include <Standard_Integer.hxx>
#include <TopoDS_Shape.hxx>
#include <IFSelect_ReturnStatus.hxx>
#include <IFSelect_PrintCount.hxx>
#include <IVtkVTK_ShapeData.hxx>
#include <IVtkOCC_ShapeMesher.hxx>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkPolyDataNormals.h>
#include <vtkType.h>
#include <vtkAutoInit.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)

int main()
{
    STEPControl_Reader reader;
    IFSelect_ReturnStatus stat = reader.ReadFile("assembly_solid.stp");
    IFSelect_PrintCount mode = IFSelect_CountByItem;
    Standard_Integer NbRoots = reader.NbRootsForTransfer();
    Standard_Integer num = reader.TransferRoots();
    Standard_Integer NbTrans = reader.TransferRoots();
    TopoDS_Shape result = reader.OneShape();
    TopoDS_Shape shape = reader.Shape();

    Handle_IVtkOCC_Shape aShapeImpl = new IVtkOCC_Shape(shape);
    Handle_IVtkVTK_ShapeData aDataImpl = new IVtkVTK_ShapeData();
    Handle_IVtk_IShapeMesher aMesher = new IVtkOCC_ShapeMesher(0.0001, 3.0 * M_PI / 180, 0, 0);
    aMesher->Build(aShapeImpl, aDataImpl);
    vtkPolyData* aPolyData = aDataImpl->getVtkPolyData();

    vtkNew<vtkPolyDataNormals> normalGenerator;
    normalGenerator->SetInputData(aPolyData);
    normalGenerator->Update();

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(normalGenerator->GetOutputPort());

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);

    vtkNew<vtkRenderer> ren;
    ren->AddActor(actor);

    vtkNew<vtkRenderWindow> renWin;
    renWin->AddRenderer(ren);
    renWin->SetSize(960, 800);

    vtkNew<vtkInteractorStyleTrackballCamera> istyle;
    vtkNew<vtkRenderWindowInteractor> iren;

    iren->SetRenderWindow(renWin);
    iren->SetInteractorStyle(istyle);

    renWin->Render();
    iren->Start();

    return 0;
}

这一次效果就好了很多,基本已经可以满足常规需求了。如果对显示效果还有更高要求,可以进一步修改IVtkOCC_ShapeMesher里的参数。

标签:VTK,iren,Shape,CAD,renWin,include,OCC,vtkNew
From: https://www.cnblogs.com/vaughnhuang/p/17573273.html

相关文章

  • VTK 9.2 Qt 5.14 安装及错误处理
    安装注意:编译release和debug,通过切换配置为release和debug,文件都是在cmake的CMAKE_INSTALL_PREFIX指定的文件夹,需要编译完一种后,把这个文件夹改名(比如debug配置,则改名为debug),不然会覆盖。在Qt项目中,出现错误:“无法解析的外部符号__imp_gl***”,“项目-属性-链接器-输入”添加:OpenG......
  • VTK 问题整理
    1)问题解决:#include<vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL2);VTK_MODULE_INIT(vtkInteractionStyle);VTK_MODULE_INIT(vtkRenderingFreeType);2)问题找不到vtkRenderingOpenGL.lib1>VTK_hello.obj:errorLNK2001:无法解析的外部符号"void__cdeclvtkRen......
  • VTK9.1.0在Windows10+VS2019+Qt 5.15.2环境下编译安装以及VTK应用于QT
    下载VTK安装包在VTK官网Download|VTK中下载VTK9.1.0待编译源码,解压后在路径Documentation/dev/bulid.md中可以看到官方提供的Prerequisites以及简易教程编译环境安装按照官方提供的Prerequisites,安装以下环境:CMakeVersion3.12ornewer,however,thelatestversionisal......
  • 《Language Model Cascades》论文学习
    一、Introduction语言模型(LM)已展现出令人印象深刻的小样本学习能力,很多人建议应该将LM视为一个基础通用推理计算器,这个基础通用推理计算器可以被用于例如:scratchpadschainofthoughtpromptinglearnedverifiersselection-inferencebootstrappingbeenappliedinfor......
  • CAD应用实践
     CAD应用:DATAEXTRACTION:如果将数据提取到表格;ME:等分多段线;PL:多段线命令;list:提取多段线端点坐标;  ......
  • vtk中截取图像显示
    目录1.CmakeLists2.C++实现部分部分项目中需要截取vtk图像进行显示1.CmakeLists#1.设置cmake的最小版本cmake_minimum_required(VERSION3.3...3.12FATAL_ERROR)#2.设置项目名称project(Step2)#3.查找vtkfind_package(VTKREQUIRED)#4.vtk模块的设置vtk_module_confi......
  • CAD设置尺寸标注箭头样式无效
    情况一,新增的标注设置箭头样式后,添加到图纸中此处无变化解决方法:先添加到图纸中,再修改情况二,按情况一操作后,此处箭头变了,但实际显示不变解决方法:1、尝试修改Dimasz属性的大小2、将Dimsah属性设置为true3、Dimtsz属性设置为0......
  • VTK mouse event -- 捕捉鼠标动作并发送信号:vtkCommand
    头文件申明:#pragmaonce#include<QObject>#include<vtkCallbackCommand.h>#include<vtkRenderWindow.h>#include<vtkRenderWindowInteractor.h>#include<vtkRenderer.h>#include<vtkSmartPointer.h>classMyMouseCallback:......
  • A failure occurred while executing com.android.build.gradle.tasks.PackageAnd
    Afailureoccurredwhileexecutingcom.android.build.gradle.tasks.PackageAnd在Android开发过程中,我们经常会遇到各种各样的错误和异常。其中一个常见的错误是“Afailureoccurredwhileexecutingcom.android.build.gradle.tasks.PackageAnd”。在本篇文章中,我们将讨论这个......
  • 在线CAD如何配合three.js绘制带线宽的线段
    前言1.在线CAD的产品经常会被集成到很多用户的网页系统内,前端开发人员只要会JavaScript,就可以对在线CAD进行集成和二次开发,今天这篇文章我们讲一下梦想CAD控件云图(H5方式)如何配合three.js绘制带线宽的线段。2.在这之前,如果还没有安装梦想CAD控件的朋友,可以查看快速入门,链接如......