通过VS编程OCC+qt学习日记1

最近学习了occ建模及显示的相关几个库以及学习了部分qt的使用编程,借此利用VS编辑了一个小程序用以学习。在此做一些总结。

首先VS编程时编程思路对于显示交互模块和窗口模块是分成两个.H文件写的这样写的好处是编写时思路会更加清晰,有利于窗口界面的布局。

MakeBottle.h的编写主要是实现occ包里面自带例子的makebottle的实现,直接调用函数实现对模型的建模构造。

#pragma once
#include <BRep_Tool.hxx>

#include <BRepAlgoAPI_Fuse.hxx>

#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_Transform.hxx>

#include <BRepFilletAPI_MakeFillet.hxx>

#include <BRepLib.hxx>

#include <BRepOffsetAPI_MakeThickSolid.hxx>
#include <BRepOffsetAPI_ThruSections.hxx>

#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakePrism.hxx>

#include <GC_MakeArcOfCircle.hxx>
#include <GC_MakeSegment.hxx>

#include <GCE2d_MakeSegment.hxx>

#include <gp.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Dir.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>

#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>

#include <Geom2d_Ellipse.hxx>
#include <Geom2d_TrimmedCurve.hxx>

#include <TopExp_Explorer.hxx>

#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>

#include <TopTools_ListOfShape.hxx>


//QT


using namespace std;

class OCC
{
public:
    TopoDS_Shape MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight, const Standard_Real myThickness)
    {
        // Profile : Define Support Points
        gp_Pnt aPnt1(-myWidth / 2., 0, 0);
        gp_Pnt aPnt2(-myWidth / 2., -myThickness / 4., 0);
        gp_Pnt aPnt3(0, -myThickness / 2., 0);
        gp_Pnt aPnt4(myWidth / 2., -myThickness / 4., 0);
        gp_Pnt aPnt5(myWidth / 2., 0, 0);

        // Profile : Define the Geometry
        Handle(Geom_TrimmedCurve) anArcOfCircle = GC_MakeArcOfCircle(aPnt2, aPnt3, aPnt4);
        Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1, aPnt2);
        Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4, aPnt5);

        // Profile : Define the Topology
        TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(aSegment1);
        TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(anArcOfCircle);
        TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);
        TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3);

        // Complete Profile
        gp_Ax1 xAxis = gp::OX();
        gp_Trsf aTrsf;

        aTrsf.SetMirror(xAxis);
        BRepBuilderAPI_Transform aBRepTrsf(aWire, aTrsf);
        TopoDS_Shape aMirroredShape = aBRepTrsf.Shape();
        TopoDS_Wire aMirroredWire = TopoDS::Wire(aMirroredShape);

        BRepBuilderAPI_MakeWire mkWire;
        mkWire.Add(aWire);
        mkWire.Add(aMirroredWire);
        TopoDS_Wire myWireProfile = mkWire.Wire();

        // Body : Prism the Profile
        TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile);
        gp_Vec aPrismVec(0, 0, myHeight);
        TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec);

        // Body : Apply Fillets
        BRepFilletAPI_MakeFillet mkFillet(myBody);
        TopExp_Explorer anEdgeExplorer(myBody, TopAbs_EDGE);
        while (anEdgeExplorer.More()) {
            TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExplorer.Current());
            //Add edge to fillet algorithm
            mkFillet.Add(myThickness / 12., anEdge);
            anEdgeExplorer.Next();
        }

        myBody = mkFillet.Shape();

        // Body : Add the Neck  
        gp_Pnt neckLocation(0, 0, myHeight);
        gp_Dir neckAxis = gp::DZ();
        gp_Ax2 neckAx2(neckLocation, neckAxis);

        Standard_Real myNeckRadius = myThickness / 4.;
        Standard_Real myNeckHeight = myHeight / 10.;

        BRepPrimAPI_MakeCylinder MKCylinder(neckAx2, myNeckRadius, myNeckHeight);
        TopoDS_Shape myNeck = MKCylinder.Shape();

        myBody = BRepAlgoAPI_Fuse(myBody, myNeck);

        // Body : Create a Hollowed Solid
        TopoDS_Face   faceToRemove;
        Standard_Real zMax = -1;

        for (TopExp_Explorer aFaceExplorer(myBody, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()) {
            TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current());
            // Check if <aFace> is the top face of the bottle抯 neck 
            Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace);
            if (aSurface->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
                Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface);
                gp_Pnt aPnt = aPlane->Location();
                Standard_Real aZ = aPnt.Z();
                if (aZ > zMax) {
                    zMax = aZ;
                    faceToRemove = aFace;
                }
            }
        }

        TopTools_ListOfShape facesToRemove;
        facesToRemove.Append(faceToRemove);
        BRepOffsetAPI_MakeThickSolid aSolidMaker;
        aSolidMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3);
        myBody = aSolidMaker.Shape();
        // Threading : Create Surfaces
        Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99);
        Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05);

        // Threading : Define 2D Curves
        gp_Pnt2d aPnt(2. * M_PI, myNeckHeight / 2.);
        gp_Dir2d aDir(2. * M_PI, myNeckHeight / 4.);
        gp_Ax2d anAx2d(aPnt, aDir);

        Standard_Real aMajor = 2. * M_PI;
        Standard_Real aMinor = myNeckHeight / 10;

        Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor);
        Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor / 4);
        Handle(Geom2d_TrimmedCurve) anArc1 = new Geom2d_TrimmedCurve(anEllipse1, 0, M_PI);
        Handle(Geom2d_TrimmedCurve) anArc2 = new Geom2d_TrimmedCurve(anEllipse2, 0, M_PI);
        gp_Pnt2d anEllipsePnt1 = anEllipse1->Value(0);
        gp_Pnt2d anEllipsePnt2 = anEllipse1->Value(M_PI);

        Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2);
        // Threading : Build Edges and Wires
        TopoDS_Edge anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1);
        TopoDS_Edge anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment, aCyl1);
        TopoDS_Edge anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2);
        TopoDS_Edge anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment, aCyl2);
        TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1, anEdge2OnSurf1);
        TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2, anEdge2OnSurf2);
        BRepLib::BuildCurves3d(threadingWire1);
        BRepLib::BuildCurves3d(threadingWire2);

        // Create Threading 
        BRepOffsetAPI_ThruSections aTool(Standard_True);
        aTool.AddWire(threadingWire1);
        aTool.AddWire(threadingWire2);
        aTool.CheckCompatibility(Standard_False);

        TopoDS_Shape myThreading = aTool.Shape();

        // Building the Resulting Compound 
        TopoDS_Compound aRes;
        BRep_Builder aBuilder;
        aBuilder.MakeCompound(aRes);
        aBuilder.Add(aRes, myBody);
        aBuilder.Add(aRes, myThreading);

        return aRes;
    }
};

View.h的编写,这个模块的主要功能是实现occ所建模型及交互的显示。

本文编写程序主要是显示官方历程里面的makeBottle模型和三角剖分离散化显示的模型。与AIS相关的函数及库都是用于显示及交互的。.h文件中的context对象是利用该对象调用相关交互显示函数操作的。该类选择继承QWidget类可以理解成这是个qt用于页面编写的可以后面添加到QWindows编写的窗口中显示其中创建了view,viewer对象用于窗口的设置调用(注意viewer是可以包含多个view其是对总体的一个控制调整,而使用view调用相关函数更偏向细节显示的设置,一个viewer尽量一个context交互对象不然可能会访问冲突)其中还包含一些鼠标的交互操作可以通过此函数实现鼠标的一些视图操作。

view.h

#ifndef VIEW_H
#define VIEW_H
#include"makeBottle.h"
#include <QWidget>
#include<QRubberBand>
#include<QMenu>

#include <QtWidgets/QMainWindow>
#include <Standard_Handle.hxx>
#include <V3d_Viewer.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <WNT_Window.hxx>
#include <V3d_View.hxx>
#include <AIS_InteractiveContext.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <TopoDs_Shape.hxx>
#include <AIS_Shape.hxx>

#include <AIS_InteractiveObject.hxx>//BaseSample可能是用来交互显示的一个基本父类
#include <NCollection_Vector.hxx>

#include <qevent.h>
//相当于视图显示View和框是分开写的(这里编写有些不好的地方对于对象context和myObject3d并没有设置为private类,可以通过函数来获取他们以此来将他们编写成私有)
class View : public QWidget//需要继承于QWidget不然后面再主的操作UI是不好添加这块的显示
{
	Q_OBJECT
public:
    View(QWidget* parent = nullptr);

    Handle(AIS_InteractiveContext) context;
    //Handle(AIS_InteractiveContext) contextCube;//专门用来显示正方体(一个view里面不能有多个交互对象不然会起冲突)
    NCollection_Vector<Handle(AIS_InteractiveObject)> myObject3d;//用于存储三维显示对象
protected:
    //重写绘图事件
    void paintEvent(QPaintEvent* event) override;
    //返回窗口绘图引擎
    QPaintEngine* paintEngine() const;

    enum Action3d
    {
        Action3d_Nothing,
        Action3d_Panning,//平移
        Action3d_Zooming,//缩放
        Action3d_Rotation//旋转
    };

    void mousePressEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void wheelEvent(QWheelEvent* event) override;


private:
    //Ui::QtWidgetsApplication1Class  ui;
    //定义查看器viewer 3D查看器
    Handle(V3d_Viewer) viewer;
    //视图
    Handle(V3d_View) view;
    //window NT窗口
    Handle(WNT_Window) window;


    Standard_Integer m_x;//记录鼠标平移坐标X
    Standard_Integer m_y;//记录鼠标平移坐标y
    Action3d m_mode;//平移、缩放、旋转

    OCC occ;

};

#endif

view.cpp

#include"view.h"
#include<AIS_ViewCube.hxx>
#include<Resource_Unicode.hxx>
View::View(QWidget* parent) :QWidget(parent)
{
    Handle(Aspect_DisplayConnection) hAspect_DisplayConnect = new Aspect_DisplayConnection;
    //创建3D接口定义图形驱动
    Handle(OpenGl_GraphicDriver) driver = new OpenGl_GraphicDriver(hAspect_DisplayConnect);

    //该类的方法允许编辑、询问连接该类的其他参数(如视图、光)
    viewer = new V3d_Viewer(driver);//通过构造函数赋予类中变量相应的值
    view = viewer->CreateView();

    WId win_handle = winId();
    //在已有的窗口上创建窗口
    window = new WNT_Window((Aspect_Handle)win_handle);
    view->SetWindow(window);
    if (!window->IsMapped())
    {
        window->Map();//打开窗口
    }

    view->SetBackgroundColor(Quantity_NOC_WHITE);//设置的显示背景是白色
    view->MustBeResized();//重新设置界面大小使其顺应几何形状
    viewer->SetDefaultLights();//设置显示光源
    setAttribute(Qt::WA_PaintOnScreen);//设置显示模式
    //交互式上下文

    context = new AIS_InteractiveContext(viewer);//利用viewer创建交互式对象
    context->SetDisplayMode(AIS_Shaded, Standard_True);//设置交互式对象显示方式还可以选择AIS_WireFrame,AIS_Shaded


    //TopoDS_Shape boxShape = occ.MakeBottle(50, 70, 30);

    //Quantity_Color color = Quantity_Color(0.3, 0.5, 0.3, Quantity_TOC_RGB);



    //Handle(AIS_Shape) abox = new AIS_Shape(boxShape);

    //context->SetMaterial(abox, Graphic3d_NameOfMaterial_Stone, Standard_False);//设置几何形状的材料
    //context->SetColor(abox, color, Standard_False);//设置其颜色

    //context->Display(abox, 1, 1, Standard_True);//设置显示的模式
    //view->FitAll();
    Handle(Prs3d_Drawer) t_hilight_style = context->HighlightStyle();
    t_hilight_style->SetMethod(Aspect_TOHM_COLOR);  // 颜色显示方式
    t_hilight_style->SetColor(Quantity_NOC_LIGHTYELLOW);    // 设置高亮颜色
    t_hilight_style->SetDisplayMode(1); // 整体高亮
    t_hilight_style->SetTransparency(0.2f); // 设置透明度

    // 设置选择模型的风格
    Handle(Prs3d_Drawer) t_select_style = context->SelectionStyle();  // 获取选择风格
    t_select_style->SetMethod(Aspect_TOHM_COLOR);  // 颜色显示方式
    t_select_style->SetColor(Quantity_NOC_LIGHTSEAGREEN);   // 设置选择后颜色
    t_select_style->SetDisplayMode(1); // 整体高亮
    t_select_style->SetTransparency(0.4f); // 设置透明度
    //这是用来显示构造坐标方位的低角的方位正方形
    TCollection_ExtendedString tostr;
    Handle(AIS_ViewCube) H_AisViewCube = new AIS_ViewCube();
    Resource_Unicode::ConvertGBToUnicode(Standard_CString("右"), tostr);
    H_AisViewCube->SetBoxSideLabel(V3d_Xpos, tostr);
    Resource_Unicode::ConvertGBToUnicode(Standard_CString("后"), tostr);
    H_AisViewCube->SetBoxSideLabel(V3d_Ypos, tostr);
    Resource_Unicode::ConvertGBToUnicode(Standard_CString("上"), tostr);
    H_AisViewCube->SetBoxSideLabel(V3d_Zpos, tostr);
    Resource_Unicode::ConvertGBToUnicode(Standard_CString("左"), tostr);
    H_AisViewCube->SetBoxSideLabel(V3d_Xneg, tostr);
    Resource_Unicode::ConvertGBToUnicode(Standard_CString("前"), tostr);
    H_AisViewCube->SetBoxSideLabel(V3d_Yneg, tostr);
    Resource_Unicode::ConvertGBToUnicode(Standard_CString("下"), tostr);
    H_AisViewCube->SetBoxSideLabel(V3d_Zneg, tostr);
    H_AisViewCube->SetTransparency(0.8);
    H_AisViewCube->SetTextColor(Quantity_Color(Quantity_NOC_WHITE));
    H_AisViewCube->SetFontHeight(20);
    H_AisViewCube->SetMaterial(Graphic3d_MaterialAspect(Graphic3d_NOM_STEEL));
    H_AisViewCube->SetTransformPersistence(
        new Graphic3d_TransformPers(
            Graphic3d_TMF_TriedronPers,
            Aspect_TOTP_LEFT_LOWER,
            Graphic3d_Vec2i(100, 100)));
    context->Display(H_AisViewCube, Standard_True);

}

void View::paintEvent(QPaintEvent* event)
{
    view->Redraw();//再次显示
}

QPaintEngine* View::paintEngine() const
{
    return 0;
}
void View::mousePressEvent(QMouseEvent* event)//鼠标相应输入操作
{
    //平移 鼠标右键+shift
    if ((event->buttons() & Qt::RightButton))//&& (QApplication::keyboardModifiers() == Qt::ShiftModifier))
    {
        m_mode = Action3d_Panning;//设置其为平移模式
        m_x = event->pos().x();//返回鼠标位置
        m_y = event->pos().y();
    }
    else if (event->buttons() & Qt::MiddleButton)//旋转检测中键
    {
        m_mode = Action3d_Rotation;//设置为旋转模式
        //开始旋转视图围绕屏幕轴
        view->StartRotation(event->pos().x(), event->pos().y());
    }
}
void View::mouseReleaseEvent(QMouseEvent* event)
{
    m_mode = Action3d_Nothing;
}

void View::mouseMoveEvent(QMouseEvent* event)
{
    switch (m_mode)//根据所处的模式来选择相应操作
    {
    case View::Action3d_Panning:
        view->Pan(event->pos().x() - m_x, m_y - event->pos().y());//移动
        m_x = event->pos().x();
        m_y = event->pos().y();
        break;
    case View::Action3d_Rotation:
        view->Rotation(event->pos().x(), event->pos().y());
        break;
    default:
        break;
    }
}
//缩放
//Zoom方法通过相邻两侧鼠标位置来判断缩小或者放大,以及缩放程度。鼠标滚轮event->angleDelta().y()会返回数值,以此模拟第二次鼠标位置
void View::wheelEvent(QWheelEvent* event)
{
    //view->Zoom(0, 0, event->angleDelta().y(), 0);//固定点缩放
    //跟随鼠标位置进行缩放
    view->StartZoomAtPoint(event->position().x(), event->position().y());//设定图像缩放的位置
    view->ZoomAtPoint(0, 0, event->angleDelta().y(), 0);//根据鼠标滚轮数值进行缩放

}

创建qt项目自动生成的项目功效是处理整个界面的交互操作,里面涉及到qt中action的使用自己定义创建了槽函数再在初始化的构造函数中写连接将信号与槽连接实现按下窗口按钮就可以显示相应的模型图像。其中的ui对象只需要知道通过该对象可以用于访问ui界面中的对象对其进行操作就可以了。创建了view指针就可以简单理解成构造出了一个可以显示模型的小窗口。

在定义槽函数的过程中,想实现点一个按钮显示新的模式,但想要原来显示的模型消除,于是就需要对context进行操作需要去除原来添加进去的几何模型,这里就又一个编程的小技巧需要在class qtOcc_Demo2 : public QMainWindow用于qt界面显示交互的类中添加类自身的句柄Handle(AIS_Shape) myShadeBottle用于实现在一个函数中利用该句柄添加几何模型,在另一个函数中删除context中已经生成的该句柄模型。另外是对应剖分离散模型的显示,对于剖分的离散模型因为显示是遍历出其剖分出来的一个个三角型显示出来所以要将其存储在NCollection_Vector<Handle(AIS_InteractiveObject)> myObject3d这个类型的容器中,然而这个容器中各个离散剖分三角形的显示发现context->Display函数是没有这个容器参数的因此需要将其遍历一遍,用每次遍历的值通过context->Display来显示出来。

qtOcc_Demo2.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_qtOcc_Demo2.h"
#include"view.h"
class qtOcc_Demo2 : public QMainWindow
{
    Q_OBJECT

public:
    qtOcc_Demo2(QWidget *parent = nullptr);
    ~qtOcc_Demo2();

private slots:
    void makeBottleShadeShow();
    void makeBottleMapShow();
private:
    Ui::qtOcc_Demo2Class ui;
    View* view;
    OCC occ;
    Handle(AIS_Shape) myShadeBottle;//用于存储瓶子的句柄,方便context显示的删除添加操作,相应的存储离散化的容器已经在view.h中定义过myObject3d
};

qtOcc_Demo2.cpp

#include "qtOcc_Demo2.h"
#include<BRepMesh_IncrementalMesh.hxx>
#include<AIS_Triangulation.hxx>
qtOcc_Demo2::qtOcc_Demo2(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    view = new View();
    ui.gridLayout->addWidget(view);//在框图中添加显示界面

    //建立信号与槽的连接
    connect(ui.actionShow, SIGNAL(triggered()), this, SLOT(makeBottleShadeShow()));
    connect(ui.actionShowTrian, SIGNAL(triggered()), this, SLOT(makeBottleMapShow()));
}

qtOcc_Demo2::~qtOcc_Demo2()
{}

void qtOcc_Demo2::makeBottleShadeShow()
{
    //先清空之前显示的几何体
    if (!view->myObject3d.IsEmpty())
    {
        for (NCollection_Vector<Handle(AIS_InteractiveObject)>::Iterator it(view->myObject3d); it.More(); it.Next())
        {
            view->context->Remove(it.Value(), Standard_True);

        }

    }

    //再绘制添加新的几何体
    //将几何体存储到句柄中
    TopoDS_Shape boxShape = occ.MakeBottle(50, 70, 30);
    myShadeBottle = new AIS_Shape(boxShape);
    Quantity_Color color = Quantity_Color(0.3, 0.5, 0.3, Quantity_TOC_RGB);
    view->context->SetMaterial(myShadeBottle, Graphic3d_NameOfMaterial_Stone, Standard_False);//设置几何形状的材料
    view->context->SetColor(myShadeBottle, color, Standard_False);//设置其颜色
    view->context->Display(myShadeBottle, 1, 1, Standard_True);
    view->context->UpdateCurrentViewer();
}

void qtOcc_Demo2::makeBottleMapShow()
{
    //先清空之前显示的几何体
    if (!myShadeBottle.IsNull())
        view->context->Remove(myShadeBottle, Standard_True);

    TopoDS_Shape aBottle = occ.MakeBottle(50, 70, 30);//先调用生成瓶子的函数生成实例对象
    BRepMesh_IncrementalMesh(aBottle, 1);//进行三角剖分算法操作对瓶子三角剖分

    BRep_Builder aBuilder;//创建实例其提供一些接口用于查询修改几何体
    TopoDS_Compound aCompound;//创建一个复合体
    aBuilder.MakeCompound(aCompound);

    Standard_Integer aNbTriangles(0);
    for (TopExp_Explorer anExplorer(aBottle, TopAbs_FACE); anExplorer.More(); anExplorer.Next())//开始遍历几何体中的面
    {
        TopoDS_Face aFace = TopoDS::Face(anExplorer.Current());
        TopLoc_Location aLocation;//对于一个单元的拓扑信息就这几种信息:种类,方向(法向量表示),位置(location)
        Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLocation);//获取当前面的位置

        for (Standard_Integer i = 1; i <= aTriangulation->NbTriangles(); i++)//aTriangulation->NbTriangles()返回的是当前面当中三角形数量,将面中所用三角剖分出来的三角形面遍历一遍
        {
            const Poly_Triangle trian = aTriangulation->Triangle(i);//获取其中一个三角面
            Standard_Integer index1, index2, index3, M = 0, N = 0;
            trian.Get(index1, index2, index3);//获取一个三角面中的三个点index1, index2, index3他们分别存储三角面中的三个点的信息

            for (Standard_Integer j = 1; j <= 3; j++)//这个for循环加switch相当于,依次取三个点中的两个点连成线
            {
                switch (j)
                {
                case 1:
                    M = index1;
                    N = index2;//像是1,2两点
                    break;
                case 2:
                    N = index3;//之后是1,3两点
                    break;
                case 3:
                    M = index2;//再之后2,3两点
                }

                BRepBuilderAPI_MakeEdge anEdgeMaker(aTriangulation->Node(M), aTriangulation->Node(N));//取其中的两个点构造成线
                if (anEdgeMaker.IsDone())
                {
                    aBuilder.Add(aCompound, anEdgeMaker.Edge());//anEdgeMaker.Edge()返回拓扑TopoDS_Edge添加到复合体中
                }
            }
        }
        Handle(AIS_Triangulation) anAisTriangulation = new AIS_Triangulation(aTriangulation);//利用面生成用于交互显示的对象
        aNbTriangles += aTriangulation->NbTriangles();//取得面中三角形面的数量
        view->myObject3d.Append(anAisTriangulation);//myObject3d这是个容器
    }

    Handle(AIS_Shape)  anAisCompound = new AIS_Shape(aCompound);//遍历完成后就相当将原先完整几何体表示离散成三角面,再重组成现在的aCompound复合体,再借此创造用以交换显示的对象
    view->myObject3d.Append(anAisCompound);
    //下面遍历容器中的对象进行显示
    for (NCollection_Vector<Handle(AIS_InteractiveObject)>::Iterator it(view->myObject3d); it.More(); it.Next())
    {
        view->context->Display(it.Value(), Standard_True);

    }
    view->context->CurrentViewer()->Update();
}

以上内容的文字部分不用看,我主要写了给自己加深一下学习效果,代码提供给大家学习,里面的注释可以不用看纯属个人瞎理解。

程序运行效果如下

项目已经上传网盘需要自行下载:(下载完后需自行配置一下环境)

链接:https://pan.baidu.com/s/1Q3XSezqR_qMz_p34ab9bTQ 
提取码:z7l3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值