【全网最完整】Open CASCADE Technology (OCCT) 构建项目,QT可视化操作,添加自定义测试内容

泪水残留的余温 2024-07-22 13:05:03 阅读 84

前言

1、项目所需工具下载

2、使用CMake编译源码

3、配置项目运行环境

4、如何自定义测试项目

5、总结


前言

        本文为了记录自己在实习的过程中,学习到的有关OCCT开源项目的搭建工作,旨在教会小白从0开始下载开源项目及环境搭配,以及如何添加自定义测试内容,最终结果展示如下:

1、项目所需工具下载

本项目共需要使用四个工具,分别是OCCT开源代码QT环境CMake构建工具VS2019,版本也会介绍。我会把CMake、VS2019、第三方库放到Github链接里​​​​​https://github.com/shadow0fiend/OCCT-Project,OCCT源码以及QT环境需要自己下载

其中下载链接如下:

OCCT(7.8或7.6或7.5皆可):Download - Open CASCADE Technology

第三方库及VS2019:GitHub - shadow0fiend/OCCT-Project: 构建OCCT项目

QT工具(5.14.2):Index of /archive/qt

CMake(3.29.3):Download CMake

其中安装过程如下:

OCCT:下载64位的压缩包,解压到本地即可。

QT:对于新手,建议在勾选下载内容的时候全部选上(简单粗暴,不会缺少东西)

详情下载过程请参考链接:Qt5.14.2安装、配置及测试(Win10)-CSDN博客

CMake:无脑下一步即可

详情下载过程请参考链接:Windows下Cmake安装步骤详解(图文)_windows终端安装cmake-CSDN博客

安装完以后,本地应该有以下几个内容,注意检查cmake-gui、OCCT源码、编译用的三方库(下图product)、QT环境、VS2019

2、使用CMake编译源码

步骤1:在OCCT源码中建立一个build文件夹,用于存放编译后的文件

步骤2:打开CMake-gui,第一个位置填入OCCT源码文件夹的路径,第二个位置填入刚才创建好的build文件夹的路径

步骤3:点击configure,选择配置vs2019,x64,点击finish

步骤4:

第一步,在3RDPARTY_DIR这一行,填入第三方库文件的路径,也就是product的路径。

第二步,然后勾选上BUILD_SAMPLES_QT这一行。

第三步点击config。

步骤5:

第一步,修改QT路径,这个Qt5.14.2是安装完QT以后的文件夹,自行在里面找对应的文件(如果没有找到,应该是QT安装下载的时候,有的选项没有勾上)

第二步,改完以后点击config,点击generate,点击open project

步骤7:cmake配置完毕,最终配置结果如下所示

3、配置项目运行环境

生成的项目如下所示(如果没有勾选QT,那么编译完成以后的项目是不包含Samples文件的,只有非常简陋的可视化界面):

步骤1:鼠标右击OCCTOverview,设置OCCTOverview为启动项。

步骤2:鼠标右击OCCTOverview,依次找到属性、Debugging、environment,将以下内容粘贴进去,这是配置项目环境变量的。注意:需要将路径修改为自己电脑的路径。

配置解释:

CASROOT需要配置OCCT源码文件夹

CSF_OCCT都是OCCT源码文件夹里面的文件

最后一行是配置QT的bin,QT的platforms,第三方库文件freetype,freeimage

<code>CASROOT=E:\cpp\code\OCCT\OCCT-7_8_0

CSF_FPE=0

CSF_OCCTResourcePath=E:\cpp\code\OCCT\OCCT-7_8_0/src

CSF_OCCTDataPath=E:\cpp\code\OCCT\OCCT-7_8_0/data

CSF_OCCTSamplesPath=E:\cpp\code\OCCT\OCCT-7_8_0/samples

CSF_OCCTTestsPath=E:\cpp\code\OCCT\OCCT-7_8_0/tests

CSF_OCCTDocPath=E:\cpp\code\OCCT\OCCT-7_8_0/doc

QT_DEBUG_PLUGINS=1

PATH=%PATH%;D:\Qt\Qt5.14.2\5.14.2\msvc2015_64\bin;D:\Qt\Qt5.14.2\5.14.2\msvc2015_64\plugins\platforms;E:\cpp\code\OCCT\products\freetype-2.5.5-vc14-64\bin;E:\cpp\code\OCCT\products\freeimage-3.17.0-vc14-64\bin;

步骤3:复制  D:\Qt\Qt5.14.2\5.14.2\msvc2015_64\plugins 路径下的platforms文件,粘贴到 E:\cpp\code\OCCT\OCCT-7_8_0\build\win64\vc14\bind (生成的build文件里)路径下,如果要在release下运行,则将其粘贴到 E:\cpp\code\OCCT\OCCT-7_8_0\build\win64\vc14\bin路径下。

步骤4:编译运行即可完成。

4、如何自定义测试项目

先看自己修改的结果,在QT窗口自己添加按钮,用于触发函数,然后再在被触发的函数里编写自己的测试代码,就可以完成自定义测试了。

具体来说,需要修改5个地方:

找到OCCT源码里的samples文件(注意,不是build里的samples),进去以后找到OCCTOverview,再找到Code文件夹。我的路径是:E:\cpp\code\OCCT\OCCT-7_8_0\samples\OCCTOverview\code

第一处修改:把自己写的cxx文件和.h文件放在这里(注意:直接在build里右键添加cxx文件是添加不到这里来的,因为那只是在build文件里添加了,而这是OCCT的源码文件,只能在这里添加以后,通过cmake编译进build才行)

具体的cxx和.h文件的写法参考如下,可以仿照源码的 TopologySamples.cxx文件的写法,看我的cxx和TopologySamples.cxx不同的地方即可,按照对应位置改就行。这里我附上我的源码。

<code>#include "PengKaiSamples.h"

void PengKaiSamples::ExecuteSample(const TCollection_AsciiString& theSampleName)

{

Standard_Boolean anIsSamplePresent = Standard_True;

FindSourceCode(theSampleName);

if (theSampleName == "FirstTest")

FirstTest();

else

{

myResult << "No function found: " << theSampleName;

myCode += TCollection_AsciiString("No function found: ") + theSampleName;

anIsSamplePresent = Standard_False;

}

myIsProcessed = anIsSamplePresent;

}

void PengKaiSamples::FirstTest()

{

for (int i = 0; i < 20; i++)

{

std::cout << "enter FirstTest" << std::endl;

}

}

#ifndef PENGKAISAMPLES_H

#define PENGKAISAMPLES_H

#include "BaseSample.h"

#include <AIS_InteractiveContext.hxx>

//! Implements PengKai samples

class PengKaiSamples : public BaseSample

{

DEFINE_STANDARD_RTTI_INLINE(PengKaiSamples, BaseSample)

public:

PengKaiSamples(const TCollection_AsciiString& theSampleSourcePath,

const Handle(AIS_InteractiveContext)& theContext)

: BaseSample(theSampleSourcePath, theContext)

{}

protected:

virtual void ExecuteSample(const TCollection_AsciiString& theSampleName) Standard_OVERRIDE;

private:

// One function for every sample

void FirstTest();

};

#endif //PENGKAISAMPLES_H

第二处修改:添加XML文件

思路:仿照其他xml文件来写

<code><Menu>

<MenuItem name="PengKai">code>

<MenuItem name="PengKai Test">code>

<Sample name="FirstTest" function="FirstTest"/>code>

</MenuItem>

</MenuItem>

</Menu>

第三处修改:

修改FILES文件,仿照其他人的写法,把cxx文件、xml文件和.h文件添加进去

<code>AdaptorCurve2d_AIS.cxx

AdaptorCurve2d_AIS.h

AdaptorCurve_AIS.cxx

AdaptorCurve_AIS.h

AdaptorPnt2d_AIS.cxx

AdaptorPnt2d_AIS.h

AdaptorVec_AIS.cxx

AdaptorVec_AIS.h

BaseSample.cxx

BaseSample.h

DataExchange.xml

DataExchangeSamples.cxx

DataExchangeSamples.h

Geometry.xml

GeometrySamples.cxx

GeometrySamples.h

MakeBottle.cxx

MakeBottle.h

Ocaf.xml

OcafSamples.cxx

OcafSamples.h

Sample2D_Face.cxx

Sample2D_Face.h

Sample2D_Image.cxx

Sample2D_Image.h

Sample2D_Markers.cxx

Sample2D_Markers.h

Samples.qrc

TOcafFunction_BoxDriver.cxx

TOcafFunction_BoxDriver.h

TOcafFunction_CutDriver.cxx

TOcafFunction_CutDriver.h

TOcafFunction_CylDriver.cxx

TOcafFunction_CylDriver.h

TOcaf_Application.cxx

TOcaf_Application.h

Topology.xml

TopologySamples.cxx

TopologySamples.h

Triangulation.xml

TriangulationSamples.cxx

TriangulationSamples.h

Viewer2d.xml

Viewer2dSamples.cxx

Viewer2dSamples.h

Viewer3d.xml

Viewer3dSamples.cxx

Viewer3dSamples.h

PengKai.xml

PengKaiSamples.cxx

PengKaiSamples.h

第四处修改:

找到samples文件夹里的qt ->; Common -> src,找到这两个cxx文件,进去修改

仿照文件里Topology结构的写法来写,把所有带有Topology的地方全部换成自己修改的名字。

内容太多,这里不易说明,建议直接拿我修改后的代码与源码做对比,可以看出添加的部分在哪里

<code>// Copyright (c) 2020 OPEN CASCADE SAS

//

// This file is part of the examples of the Open CASCADE Technology software library.

//

// Permission is hereby granted, free of charge, to any person obtaining a copy

// of this software and associated documentation files (the "Software"), to deal

// in the Software without restriction, including without limitation the rights

// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

// copies of the Software, and to permit persons to whom the Software is

// furnished to do so, subject to the following conditions:

//

// The above copyright notice and this permission notice shall be included in all

// copies or substantial portions of the Software.

//

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

#include "ApplicationCommon.h"

#include <Standard_WarningsDisable.hxx>

#include <QApplication>

#include <QDir>

#include <QFile>

#include <QFont>

#include <QFrame>

#include <QGroupBox>

#include <QMap>

#include <QMdiArea>

#include <QMdiSubWindow>

#include <QMenuBar>

#include <QMessageBox>

#include <QPair>

#include <QSplitter>

#include <QStatusBar>

#include <QtGlobal>

#include <QHBoxLayout>

#include <QVBoxLayout>

#include <QWidget>

#include <QDomDocument>

#include <QDomAttr>

#include <Standard_WarningsRestore.hxx>

#include <OpenGl_GraphicDriver.hxx>

#include <OSD_Environment.hxx>

#include <stdlib.h>

#include <memory>

ApplicationCommonWindow::ApplicationCommonWindow (ApplicationType theCategory)

: QMainWindow (nullptr),

myAppType(theCategory),

myStdToolBar (nullptr),

myViewBar (nullptr),

myCasCadeBar (nullptr),

myFilePopup (nullptr),

myCategoryPopup (nullptr)

{

ALL_CATEGORIES[AppType_Geometry] = "Geometry";

ALL_CATEGORIES[AppType_Topology] = "Topology";

ALL_CATEGORIES[AppType_Triangulation] = "Triangulation";

ALL_CATEGORIES[AppType_DataExchange] = "DataExchange";

ALL_CATEGORIES[AppType_Ocaf] = "OCAF";

ALL_CATEGORIES[AppType_Viewer3d] = "3D viewer";

ALL_CATEGORIES[AppType_Viewer2d] = "2D Viewer";

ALL_CATEGORIES[AppType_PengKai] = "PengKai";

mySampleMapper = new QSignalMapper(this);

myExchangeMapper = new QSignalMapper(this);

myOcafMapper = new QSignalMapper(this);

myViewer3dMapper = new QSignalMapper(this);

myViewer2dMapper = new QSignalMapper(this);

myCategoryMapper = new QSignalMapper(this);

connect(mySampleMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessSample(const QString &)));

connect(myExchangeMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessExchange(const QString &)));

connect(myOcafMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessOcaf(const QString &)));

connect(myViewer3dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer3d(const QString &)));

connect(myViewer2dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer2d(const QString &)));

connect(myCategoryMapper, SIGNAL(mapped(const QString &)), this, SLOT(onChangeCategory(const QString &)));

setFocusPolicy(Qt::StrongFocus);

QFont aCodeViewFont;

aCodeViewFont.setFamily("Courier");

aCodeViewFont.setFixedPitch(true);

aCodeViewFont.setPointSize(10);

QGroupBox* aCodeFrame = new QGroupBox(tr("Sample code"));

QVBoxLayout* aCodeLayout = new QVBoxLayout(aCodeFrame);

aCodeLayout->;setContentsMargins(3, 3, 3, 3);

myCodeView = new QTextEdit(aCodeFrame);

aCodeLayout->addWidget(myCodeView);

myCodeView->setDocumentTitle("Code");

myCodeView->setLineWrapMode(QTextEdit::NoWrap);

myCodeView->setReadOnly(true);

myCodeView->setFont(aCodeViewFont);

myCodeViewHighlighter = new OcctHighlighter(myCodeView->document());

QGroupBox* aResultFrame = new QGroupBox(tr("Output"));

QVBoxLayout* aResultLayout = new QVBoxLayout(aResultFrame);

aResultLayout->setContentsMargins(3, 3, 3, 3);

myResultView = new QTextEdit(aResultFrame);

aResultLayout->addWidget(myResultView);

myResultView->setDocumentTitle("Output");

myResultView->setReadOnly(true);

myResultView->setFont(aCodeViewFont);

QSplitter* aCodeResultSplitter = new QSplitter(Qt::Vertical);

aCodeResultSplitter->addWidget(aCodeFrame);

aCodeResultSplitter->addWidget(aResultFrame);

myDocument3d = createNewDocument();

myDocument2d = createNewDocument();

QFrame* aViewFrame = new QFrame;

aViewFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken);

aViewFrame->setLineWidth(3);

QVBoxLayout* aViewLayout = new QVBoxLayout(aViewFrame);

aViewLayout->setContentsMargins(0, 0, 0, 0);

myGeomWidget = new GeomWidget(myDocument3d, myDocument2d, aViewFrame);

aViewLayout->addWidget(myGeomWidget);

myGeomWidget->setContentsMargins(0, 0, 0, 0);

QSplitter* aGeomTextSplitter = new QSplitter(Qt::Horizontal);

aGeomTextSplitter->addWidget(aViewFrame);

aGeomTextSplitter->addWidget(aCodeResultSplitter);

aGeomTextSplitter->setStretchFactor(0, 1);

aGeomTextSplitter->setStretchFactor(1, 1);

QList<int> aSizeList;

aSizeList.append(640);

aSizeList.append(640);

aGeomTextSplitter->setSizes(aSizeList);

setCentralWidget(aGeomTextSplitter);

#include <Standard_WarningsDisable.hxx>

Q_INIT_RESOURCE(Samples);

#include <Standard_WarningsRestore.hxx>

TCollection_AsciiString aSampleSourcePach = getSampleSourceDir();

myGeometrySamples = new GeometrySamples(aSampleSourcePach,

myDocument3d->getContext());

myTopologySamples = new TopologySamples(aSampleSourcePach,

myDocument3d->getContext());

myTriangulationSamples = new TriangulationSamples(aSampleSourcePach,

myDocument3d->getContext());

myDataExchangeSamples = new DataExchangeSamples(aSampleSourcePach,

myGeomWidget->Get3dView(),

myDocument3d->getContext());

myOcafSamples = new OcafSamples(aSampleSourcePach,

myDocument3d->getViewer(),

myDocument3d->getContext());

myViewer3dSamples = new Viewer3dSamples(aSampleSourcePach,

myGeomWidget->Get3dView(),

myDocument3d->getContext());

myViewer2dSamples = new Viewer2dSamples(aSampleSourcePach,

myGeomWidget->Get2dView(),

myDocument2d->getViewer(),

myDocument2d->getContext());

myPengKaiSamples = new PengKaiSamples(aSampleSourcePach,

myDocument3d->getContext());

MenuFormXml(":/menus/Geometry.xml", mySampleMapper, myGeometryMenus);

MenuFormXml(":/menus/Topology.xml", mySampleMapper, myTopologyMenus);

MenuFormXml(":/menus/Triangulation.xml", mySampleMapper, myTriangulationMenus);

MenuFormXml(":/menus/DataExchange.xml", myExchangeMapper, myDataExchangeMenus);

MenuFormXml(":/menus/Ocaf.xml", myOcafMapper, myOcafMenus);

MenuFormXml(":/menus/Viewer3d.xml", myViewer3dMapper, myViewer3dMenus);

MenuFormXml(":/menus/Viewer2d.xml", myViewer2dMapper, myViewer2dMenus);

MenuFormXml(":/menus/PengKai.xml", mySampleMapper, myPengKaiMenus);

onChangeCategory(ALL_CATEGORIES[myAppType]);

resize(1280, 560);

}

void ApplicationCommonWindow::RebuildMenu()

{

menuBar()->clear();

myStdActions[StdActions_FileQuit] = CreateAction("Quit", "CTRL+Q");

connect(myStdActions[StdActions_FileQuit], SIGNAL(triggered()), this, SLOT(onCloseAllWindows()));

myStdActions[StdActions_HelpAbout] = CreateAction("About", "F1", ":/icons/help.png");

connect(myStdActions[StdActions_HelpAbout], SIGNAL(triggered()), this, SLOT(onAbout()));

// populate a menu with all actions

myFilePopup = new QMenu(this);

myFilePopup = menuBar()->addMenu(tr("&File"));

myFilePopup->addAction(myStdActions[StdActions_FileQuit]);

myCategoryPopup = new QMenu(this);

myCategoryPopup = menuBar()->addMenu(tr("&Category"));

foreach (ApplicationType aCategory, ALL_CATEGORIES.keys())

{

QString aCategoryName = ALL_CATEGORIES.value(aCategory);

QAction* anAction = myCategoryPopup->addAction(aCategoryName);

anAction->setText(aCategoryName);

myCategoryMapper->setMapping(anAction, aCategoryName);

connect(anAction, SIGNAL(triggered()), myCategoryMapper, SLOT(map()));

myCategoryPopup->addAction(anAction);

myCategoryActions.insert(aCategory, anAction);

}

foreach (QMenu* aSampleMenu, GetCurrentMenus())

{

menuBar()->addMenu(aSampleMenu);

}

// add a help menu

QMenu* aHelp = new QMenu(this);

menuBar()->addSeparator();

aHelp = menuBar()->addMenu(tr("&Help"));

aHelp->addAction(myStdActions[StdActions_HelpAbout]);

}

Handle(BaseSample) ApplicationCommonWindow::GetCurrentSamples()

{

switch (myAppType)

{

case AppType_Geometry: return myGeometrySamples;

case AppType_Topology: return myTopologySamples;

case AppType_Triangulation: return myTriangulationSamples;

case AppType_DataExchange: return myDataExchangeSamples;

case AppType_Ocaf: return myOcafSamples;

case AppType_Viewer2d: return myViewer2dSamples;

case AppType_Viewer3d: return myViewer3dSamples;

case AppType_PengKai: return myPengKaiSamples;

case AppType_Unknown:

break;

}

throw QString("Unknown Application type");

}

const QList<QMenu*>& ApplicationCommonWindow::GetCurrentMenus()

{

switch (myAppType)

{

case AppType_Geometry: return myGeometryMenus;

case AppType_Topology: return myTopologyMenus;

case AppType_Triangulation: return myTriangulationMenus;

case AppType_DataExchange: return myDataExchangeMenus;

case AppType_Ocaf: return myOcafMenus;

case AppType_Viewer2d: return myViewer2dMenus;

case AppType_Viewer3d: return myViewer3dMenus;

case AppType_PengKai: return myPengKaiMenus;

case AppType_Unknown:

break;

}

throw QString("Unknown Application type");

}

DocumentCommon* ApplicationCommonWindow::createNewDocument()

{

return new DocumentCommon(this);

}

void ApplicationCommonWindow::onChangeCategory(const QString& theCategory)

{

myAppType = ALL_CATEGORIES.key(theCategory);

setWindowTitle(ALL_CATEGORIES[myAppType]);

myOcafSamples->ClearExtra();

myViewer3dSamples->ClearExtra();

myViewer2dSamples->ClearExtra();

GetCurrentSamples()->Clear();

myDocument3d->Clear();

myDocument2d->Clear();

myCodeView->setPlainText("");

myResultView->setPlainText("");

GetCurrentSamples()->AppendCube();

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myGeomWidget->FitAll();

RebuildMenu();

switch (myAppType)

{

case AppType_DataExchange:

{

myDataExchangeSamples->AppendBottle();

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myGeomWidget->Show3d();

break;

}

case AppType_Ocaf:

{

onProcessOcaf("CreateOcafDocument");

myGeomWidget->Show3d();

break;

}

case AppType_Viewer2d:

{

myGeomWidget->Show2d();

break;

}

case AppType_Viewer3d:

{

myViewer3dSamples->AppendBottle();

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myGeomWidget->Show3d();

break;

}

case AppType_Geometry:

case AppType_Topology:

case AppType_PengKai:

case AppType_Triangulation:

case AppType_Unknown:

{

break;

}

}

}

void ApplicationCommonWindow::onAbout()

{

QMessageBox::information(this, tr("OCCT Overview"),

tr("Qt based application to study OpenCASCADE Technology"),

tr("Ok"), QString::null, QString::null, 0, 0);

}

TCollection_AsciiString ApplicationCommonWindow::getSampleSourceDir()

{

TCollection_AsciiString aSampleSourceDir = OSD_Environment("CSF_OCCTOverviewSampleCodePath").Value();

if (aSampleSourceDir.IsEmpty())

{

TCollection_AsciiString aCasRoot = OSD_Environment("CASROOT").Value();

if (!aCasRoot.IsEmpty())

{

aSampleSourceDir = aCasRoot + "/samples/OCCTOverview/code";

}

}

return aSampleSourceDir;

}

QAction* ApplicationCommonWindow::CreateAction (const QString& theActionName,

const QString& theShortcut,

const QString& theIconName)

{

QAction* aAction(NULL);

if (theIconName.isEmpty())

{

aAction = new QAction(theActionName, this);

}

else

{

QPixmap aIcon = QPixmap(theIconName);

aAction = new QAction(aIcon, theActionName, this);

}

aAction->setToolTip(theActionName);

aAction->setStatusTip(theActionName);

aAction->setShortcut(theShortcut);

return aAction;

}

template <typename PointerToMemberFunction>

QAction* ApplicationCommonWindow::CreateSample (PointerToMemberFunction theHandlerMethod,

const char* theActionName)

{

QAction* anAction = new QAction(QObject::tr(theActionName), this);

connect(anAction, SIGNAL(triggered()), this, SLOT(theHandlerMethod()));

return anAction;

}

void ApplicationCommonWindow::resizeEvent(QResizeEvent* e)

{

QMainWindow::resizeEvent(e);

statusBar()->setSizeGripEnabled(!isMaximized());

}

void ApplicationCommonWindow::onProcessSample(const QString& theSampleName)

{

QApplication::setOverrideCursor(Qt::WaitCursor);

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

GetCurrentSamples()->Process(theSampleName.toUtf8().data());

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myDocument2d->SetObjects(GetCurrentSamples()->Get2dObjects());

myCodeView->setPlainText(GetCurrentSamples()->GetCode().ToCString());

myResultView->setPlainText(GetCurrentSamples()->GetResult().ToCString());

myGeomWidget->FitAll();

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessExchange(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

int aMode = 0;

QString aFileName = selectFileName(theSampleName, getDataExchangeDialog(theSampleName), aMode);

if (aFileName.isEmpty())

{

return;

}

QApplication::setOverrideCursor(Qt::WaitCursor);

myDataExchangeSamples->SetFileName(aFileName.toUtf8().data());

myDataExchangeSamples->SetStepType(static_cast<STEPControl_StepModelType>(aMode));

myDataExchangeSamples->Process(theSampleName.toUtf8().data());

myDocument3d->SetObjects(myDataExchangeSamples->Get3dObjects());

myDocument2d->SetObjects(myDataExchangeSamples->Get2dObjects());

myCodeView->setPlainText(myDataExchangeSamples->GetCode().ToCString());

myResultView->setPlainText(myDataExchangeSamples->GetResult().ToCString());

myGeomWidget->FitAll();

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessOcaf(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

if (theSampleName.indexOf("Dialog") == 0)

{

int aMode = 0; // not used

QString aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);

if (aFileName.isEmpty())

{

return;

}

myOcafSamples->SetFileName(aFileName.toUtf8().data());

}

QApplication::setOverrideCursor(Qt::WaitCursor);

myOcafSamples->Process(theSampleName.toUtf8().data());

myDocument2d->SetObjects(myOcafSamples->Get2dObjects());

myCodeView->setPlainText(myOcafSamples->GetCode().ToCString());

myResultView->setPlainText(myOcafSamples->GetResult().ToCString());

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessViewer3d(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

QApplication::setOverrideCursor(Qt::WaitCursor);

myViewer3dSamples->Process(theSampleName.toUtf8().data());

myCodeView->setPlainText(myViewer3dSamples->GetCode().ToCString());

myResultView->setPlainText(myViewer3dSamples->GetResult().ToCString());

myGeomWidget->FitAll();

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessViewer2d(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

Standard_Boolean anIsFileSample = Viewer2dSamples::IsFileSample(theSampleName.toUtf8().data());

QString aFileName;

if (anIsFileSample)

{

int aMode = 0; // not used

aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);

if (aFileName.isEmpty())

{

return;

}

myViewer2dSamples->SetFileName(aFileName.toUtf8().data());

}

if (!anIsFileSample || (anIsFileSample && !aFileName.isEmpty()))

{

QApplication::setOverrideCursor(Qt::WaitCursor);

myViewer2dSamples->Process(theSampleName.toUtf8().data());

if (!Viewer2dSamples::IsShadedSample(theSampleName.toUtf8().data()))

{

myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_False);

}

else

{

myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_True);

}

myCodeView->setPlainText(myViewer2dSamples->GetCode().ToCString());

myResultView->setPlainText(myViewer2dSamples->GetResult().ToCString());

myGeomWidget->Show2d();

QApplication::restoreOverrideCursor();

}

else

{

myResultView->setPlainText("No file selected!");

}

}

QString ApplicationCommonWindow::selectFileName(const QString& theSampleName,

TranslateDialog* theDialog, int& theMode)

{

Q_UNUSED(theSampleName)

std::shared_ptr<TranslateDialog> aDialog(theDialog);

int ret = aDialog->exec();

theMode = aDialog->getMode();

qApp->processEvents();

QString aFilename;

QStringList aFileNameList;

if (ret != QDialog::Accepted)

{

return aFilename;

}

aFileNameList = aDialog->selectedFiles();

if (!aFileNameList.isEmpty())

{

aFilename = aFileNameList[0];

}

if (!QFileInfo(aFilename).completeSuffix().length())

{

QString selFilter = aDialog->selectedNameFilter();

int idx = selFilter.indexOf("(*.");

if (idx != -1)

{

QString tail = selFilter.mid(idx + 3);

idx = tail.indexOf(" ");

if (idx == -1)

{

idx = tail.indexOf(")");

}

QString ext = tail.left(idx);

if (ext.length())

{

aFilename += QString(".") + ext;

}

}

}

return aFilename;

}

TranslateDialog* ApplicationCommonWindow::getDataExchangeDialog(const QString& theSampleName)

{

TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);

TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());

if (DataExchangeSamples::IsExportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Export file");

aTranslateDialog->setFileMode(QFileDialog::AnyFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);

}

else if (DataExchangeSamples::IsImportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Import file");

aTranslateDialog->setFileMode(QFileDialog::ExistingFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);

}

QString aFormatFilter;

if (DataExchangeSamples::IsBrepSample(aSampleName))

{

aFormatFilter = "BREP Files(*.brep *.rle)";

}

else if (DataExchangeSamples::IsStepSample(aSampleName))

{

aFormatFilter = "STEP Files (*.stp *.step)";

aTranslateDialog->addMode(STEPControl_ManifoldSolidBrep, "Manifold Solid Brep");

aTranslateDialog->addMode(STEPControl_FacetedBrep, "Faceted Brep");

aTranslateDialog->addMode(STEPControl_ShellBasedSurfaceModel, "Shell Based Surface Model");

aTranslateDialog->addMode(STEPControl_GeometricCurveSet, "Geometric Curve Set");

}

else if (DataExchangeSamples::IsIgesSample(aSampleName))

{

aFormatFilter = "IGES Files (*.igs *.iges)";

}

else if (DataExchangeSamples::IsStlSample(aSampleName))

{

aFormatFilter = "STL Files (*.stl)";

}

else if (DataExchangeSamples::IsVrmlSample(aSampleName))

{

aFormatFilter = "VRML Files (*.vrml)";

}

else if (DataExchangeSamples::IsImageSample(aSampleName))

{

aFormatFilter = "All Image Files (*.bmp *.gif *.jpg *.jpeg *.png *.tga)";

}

QStringList aFilters;

aFilters.append(aFormatFilter);

aFilters.append("All Files(*.*)");

aTranslateDialog->setNameFilters(aFilters);

aTranslateDialog->clear();

return aTranslateDialog;

}

TranslateDialog* ApplicationCommonWindow::getOcafDialog(const QString& theSampleName)

{

TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);

TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());

if (OcafSamples::IsExportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Export file");

aTranslateDialog->setFileMode(QFileDialog::AnyFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);

}

else if (OcafSamples::IsImportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Import file");

aTranslateDialog->setFileMode(QFileDialog::ExistingFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);

}

QStringList aFilters;

if (OcafSamples::IsBinarySample(aSampleName))

{

aFilters.append("Binary OCAF Sample (*.cbf)");

}

if (OcafSamples::IsXmlSample(aSampleName))

{

aFilters.append("XML OCAF Sample (*.xml)");

}

aFilters.append("All Files(*.*)");

aTranslateDialog->setNameFilters(aFilters);

aTranslateDialog->clear();

return aTranslateDialog;

}

QMenu* ApplicationCommonWindow::MenuFromDomNode(QDomElement& theItemElement,

QWidget* theParent,

QSignalMapper* theMapper)

{

QString anItemName = theItemElement.attribute("name");

QMenu* aMenu = new QMenu(anItemName, theParent);

QDomElement anChildItemElement = theItemElement.firstChildElement("MenuItem");

QDomElement anSampleElement = theItemElement.firstChildElement("Sample");

while(anChildItemElement.isElement())

{

aMenu->addMenu(MenuFromDomNode(anChildItemElement, aMenu, theMapper));

anChildItemElement = anChildItemElement.nextSibling().toElement();

}

while(anSampleElement.isElement())

{

QString aSampleName = anSampleElement.attribute("name");

QString aSampleFunction = anSampleElement.attribute("function");

QAction* anAction = aMenu->addAction(aSampleFunction);

anAction->setText(aSampleName);

theMapper->setMapping(anAction, aSampleFunction);

connect(anAction, SIGNAL(triggered()), theMapper, SLOT(map()));

anSampleElement = anSampleElement.nextSibling().toElement();

}

return aMenu;

}

void ApplicationCommonWindow::MenuFormXml(const QString& thePath,

QSignalMapper* theMapper,

QList<QMenu*>& theMunusList)

{

QDomDocument aDomDocument;

theMunusList.clear();

QFile aXmlFile(thePath);

QString anErrorMessage;

if (aXmlFile.error() != QFile::NoError)

{

anErrorMessage = aXmlFile.errorString();

Message::SendFail() << "QFile creating error: " << anErrorMessage.toUtf8().constData();

aXmlFile.close();

return;

}

if (!aXmlFile.open(QIODevice::ReadOnly | QIODevice::Text))

{

Message::SendFail() << "File " << thePath.toUtf8().constData() << " could not open";

if (aXmlFile.error() != QFile::NoError)

{

anErrorMessage = aXmlFile.errorString();

Message::SendFail() << "QFile opening error: " << anErrorMessage.toUtf8().constData();

}

aXmlFile.close();

return;

}

bool aNamespaceProcessing(false);

QString anErrorMsg;

int anErrorLine(0);

int anErrorColumn(0);

if (!aDomDocument.setContent(&aXmlFile, aNamespaceProcessing, &anErrorMsg, &anErrorLine, &anErrorColumn))

{

Message::SendFail() << "XML file parsing error: " << anErrorMsg.toStdString()

<< " at line: " << anErrorLine << " column: " << anErrorColumn;

aXmlFile.close();

return;

}

aXmlFile.close();

QDomElement aRootElement = aDomDocument.documentElement();

QDomElement anItemElement = aRootElement.firstChildElement("MenuItem");

while(!anItemElement.isNull())

{

theMunusList.push_back(MenuFromDomNode(anItemElement, this, theMapper));

anItemElement = anItemElement.nextSiblingElement("MenuItem");

}

}

// Copyright (c) 2020 OPEN CASCADE SAS

//

// This file is part of the examples of the Open CASCADE Technology software library.

//

// Permission is hereby granted, free of charge, to any person obtaining a copy

// of this software and associated documentation files (the "Software"), to deal

// in the Software without restriction, including without limitation the rights

// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

// copies of the Software, and to permit persons to whom the Software is

// furnished to do so, subject to the following conditions:

//

// The above copyright notice and this permission notice shall be included in all

// copies or substantial portions of the Software.

//

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

#include "ApplicationCommon.h"

#include <Standard_WarningsDisable.hxx>

#include <QApplication>

#include <QDir>

#include <QFile>

#include <QFont>

#include <QFrame>

#include <QGroupBox>

#include <QMap>

#include <QMdiArea>

#include <QMdiSubWindow>

#include <QMenuBar>

#include <QMessageBox>

#include <QPair>

#include <QSplitter>

#include <QStatusBar>

#include <QtGlobal>

#include <QHBoxLayout>

#include <QVBoxLayout>

#include <QWidget>

#include <QDomDocument>

#include <QDomAttr>

#include <Standard_WarningsRestore.hxx>

#include <OpenGl_GraphicDriver.hxx>

#include <OSD_Environment.hxx>

#include <stdlib.h>

#include <memory>

ApplicationCommonWindow::ApplicationCommonWindow (ApplicationType theCategory)

: QMainWindow (nullptr),

myAppType(theCategory),

myStdToolBar (nullptr),

myViewBar (nullptr),

myCasCadeBar (nullptr),

myFilePopup (nullptr),

myCategoryPopup (nullptr)

{

ALL_CATEGORIES[AppType_Geometry] = "Geometry";

ALL_CATEGORIES[AppType_Topology] = "Topology";

ALL_CATEGORIES[AppType_Triangulation] = "Triangulation";

ALL_CATEGORIES[AppType_DataExchange] = "DataExchange";

ALL_CATEGORIES[AppType_Ocaf] = "OCAF";

ALL_CATEGORIES[AppType_Viewer3d] = "3D viewer";

ALL_CATEGORIES[AppType_Viewer2d] = "2D Viewer";

ALL_CATEGORIES[AppType_PengKai] = "PengKai";

mySampleMapper = new QSignalMapper(this);

myExchangeMapper = new QSignalMapper(this);

myOcafMapper = new QSignalMapper(this);

myViewer3dMapper = new QSignalMapper(this);

myViewer2dMapper = new QSignalMapper(this);

myCategoryMapper = new QSignalMapper(this);

connect(mySampleMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessSample(const QString &)));

connect(myExchangeMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessExchange(const QString &)));

connect(myOcafMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessOcaf(const QString &)));

connect(myViewer3dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer3d(const QString &)));

connect(myViewer2dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer2d(const QString &)));

connect(myCategoryMapper, SIGNAL(mapped(const QString &)), this, SLOT(onChangeCategory(const QString &)));

setFocusPolicy(Qt::StrongFocus);

QFont aCodeViewFont;

aCodeViewFont.setFamily("Courier");

aCodeViewFont.setFixedPitch(true);

aCodeViewFont.setPointSize(10);

QGroupBox* aCodeFrame = new QGroupBox(tr("Sample code"));

QVBoxLayout* aCodeLayout = new QVBoxLayout(aCodeFrame);

aCodeLayout->setContentsMargins(3, 3, 3, 3);

myCodeView = new QTextEdit(aCodeFrame);

aCodeLayout->addWidget(myCodeView);

myCodeView->setDocumentTitle("Code");

myCodeView->setLineWrapMode(QTextEdit::NoWrap);

myCodeView->setReadOnly(true);

myCodeView->setFont(aCodeViewFont);

myCodeViewHighlighter = new OcctHighlighter(myCodeView->document());

QGroupBox* aResultFrame = new QGroupBox(tr("Output"));

QVBoxLayout* aResultLayout = new QVBoxLayout(aResultFrame);

aResultLayout->setContentsMargins(3, 3, 3, 3);

myResultView = new QTextEdit(aResultFrame);

aResultLayout->addWidget(myResultView);

myResultView->setDocumentTitle("Output");

myResultView->setReadOnly(true);

myResultView->setFont(aCodeViewFont);

QSplitter* aCodeResultSplitter = new QSplitter(Qt::Vertical);

aCodeResultSplitter->addWidget(aCodeFrame);

aCodeResultSplitter->addWidget(aResultFrame);

myDocument3d = createNewDocument();

myDocument2d = createNewDocument();

QFrame* aViewFrame = new QFrame;

aViewFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken);

aViewFrame->setLineWidth(3);

QVBoxLayout* aViewLayout = new QVBoxLayout(aViewFrame);

aViewLayout->setContentsMargins(0, 0, 0, 0);

myGeomWidget = new GeomWidget(myDocument3d, myDocument2d, aViewFrame);

aViewLayout->addWidget(myGeomWidget);

myGeomWidget->setContentsMargins(0, 0, 0, 0);

QSplitter* aGeomTextSplitter = new QSplitter(Qt::Horizontal);

aGeomTextSplitter->addWidget(aViewFrame);

aGeomTextSplitter->addWidget(aCodeResultSplitter);

aGeomTextSplitter->setStretchFactor(0, 1);

aGeomTextSplitter->setStretchFactor(1, 1);

QList<int> aSizeList;

aSizeList.append(640);

aSizeList.append(640);

aGeomTextSplitter->setSizes(aSizeList);

setCentralWidget(aGeomTextSplitter);

#include <Standard_WarningsDisable.hxx>

Q_INIT_RESOURCE(Samples);

#include <Standard_WarningsRestore.hxx>

TCollection_AsciiString aSampleSourcePach = getSampleSourceDir();

myGeometrySamples = new GeometrySamples(aSampleSourcePach,

myDocument3d->getContext());

myTopologySamples = new TopologySamples(aSampleSourcePach,

myDocument3d->getContext());

myTriangulationSamples = new TriangulationSamples(aSampleSourcePach,

myDocument3d->getContext());

myDataExchangeSamples = new DataExchangeSamples(aSampleSourcePach,

myGeomWidget->Get3dView(),

myDocument3d->getContext());

myOcafSamples = new OcafSamples(aSampleSourcePach,

myDocument3d->getViewer(),

myDocument3d->getContext());

myViewer3dSamples = new Viewer3dSamples(aSampleSourcePach,

myGeomWidget->Get3dView(),

myDocument3d->getContext());

myViewer2dSamples = new Viewer2dSamples(aSampleSourcePach,

myGeomWidget->Get2dView(),

myDocument2d->getViewer(),

myDocument2d->getContext());

myPengKaiSamples = new PengKaiSamples(aSampleSourcePach,

myDocument3d->getContext());

MenuFormXml(":/menus/Geometry.xml", mySampleMapper, myGeometryMenus);

MenuFormXml(":/menus/Topology.xml", mySampleMapper, myTopologyMenus);

MenuFormXml(":/menus/Triangulation.xml", mySampleMapper, myTriangulationMenus);

MenuFormXml(":/menus/DataExchange.xml", myExchangeMapper, myDataExchangeMenus);

MenuFormXml(":/menus/Ocaf.xml", myOcafMapper, myOcafMenus);

MenuFormXml(":/menus/Viewer3d.xml", myViewer3dMapper, myViewer3dMenus);

MenuFormXml(":/menus/Viewer2d.xml", myViewer2dMapper, myViewer2dMenus);

MenuFormXml(":/menus/PengKai.xml", mySampleMapper, myPengKaiMenus);

onChangeCategory(ALL_CATEGORIES[myAppType]);

resize(1280, 560);

}

void ApplicationCommonWindow::RebuildMenu()

{

menuBar()->clear();

myStdActions[StdActions_FileQuit] = CreateAction("Quit", "CTRL+Q");

connect(myStdActions[StdActions_FileQuit], SIGNAL(triggered()), this, SLOT(onCloseAllWindows()));

myStdActions[StdActions_HelpAbout] = CreateAction("About", "F1", ":/icons/help.png");

connect(myStdActions[StdActions_HelpAbout], SIGNAL(triggered()), this, SLOT(onAbout()));

// populate a menu with all actions

myFilePopup = new QMenu(this);

myFilePopup = menuBar()->addMenu(tr("&File"));

myFilePopup->addAction(myStdActions[StdActions_FileQuit]);

myCategoryPopup = new QMenu(this);

myCategoryPopup = menuBar()->addMenu(tr("&Category"));

foreach (ApplicationType aCategory, ALL_CATEGORIES.keys())

{

QString aCategoryName = ALL_CATEGORIES.value(aCategory);

QAction* anAction = myCategoryPopup->addAction(aCategoryName);

anAction->setText(aCategoryName);

myCategoryMapper->setMapping(anAction, aCategoryName);

connect(anAction, SIGNAL(triggered()), myCategoryMapper, SLOT(map()));

myCategoryPopup->addAction(anAction);

myCategoryActions.insert(aCategory, anAction);

}

foreach (QMenu* aSampleMenu, GetCurrentMenus())

{

menuBar()->addMenu(aSampleMenu);

}

// add a help menu

QMenu* aHelp = new QMenu(this);

menuBar()->addSeparator();

aHelp = menuBar()->addMenu(tr("&Help"));

aHelp->addAction(myStdActions[StdActions_HelpAbout]);

}

Handle(BaseSample) ApplicationCommonWindow::GetCurrentSamples()

{

switch (myAppType)

{

case AppType_Geometry: return myGeometrySamples;

case AppType_Topology: return myTopologySamples;

case AppType_Triangulation: return myTriangulationSamples;

case AppType_DataExchange: return myDataExchangeSamples;

case AppType_Ocaf: return myOcafSamples;

case AppType_Viewer2d: return myViewer2dSamples;

case AppType_Viewer3d: return myViewer3dSamples;

case AppType_PengKai: return myPengKaiSamples;

case AppType_Unknown:

break;

}

throw QString("Unknown Application type");

}

const QList<QMenu*>& ApplicationCommonWindow::GetCurrentMenus()

{

switch (myAppType)

{

case AppType_Geometry: return myGeometryMenus;

case AppType_Topology: return myTopologyMenus;

case AppType_Triangulation: return myTriangulationMenus;

case AppType_DataExchange: return myDataExchangeMenus;

case AppType_Ocaf: return myOcafMenus;

case AppType_Viewer2d: return myViewer2dMenus;

case AppType_Viewer3d: return myViewer3dMenus;

case AppType_PengKai: return myPengKaiMenus;

case AppType_Unknown:

break;

}

throw QString("Unknown Application type");

}

DocumentCommon* ApplicationCommonWindow::createNewDocument()

{

return new DocumentCommon(this);

}

void ApplicationCommonWindow::onChangeCategory(const QString& theCategory)

{

myAppType = ALL_CATEGORIES.key(theCategory);

setWindowTitle(ALL_CATEGORIES[myAppType]);

myOcafSamples->ClearExtra();

myViewer3dSamples->ClearExtra();

myViewer2dSamples->ClearExtra();

GetCurrentSamples()->Clear();

myDocument3d->Clear();

myDocument2d->Clear();

myCodeView->setPlainText("");

myResultView->setPlainText("");

GetCurrentSamples()->AppendCube();

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myGeomWidget->FitAll();

RebuildMenu();

switch (myAppType)

{

case AppType_DataExchange:

{

myDataExchangeSamples->AppendBottle();

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myGeomWidget->Show3d();

break;

}

case AppType_Ocaf:

{

onProcessOcaf("CreateOcafDocument");

myGeomWidget->Show3d();

break;

}

case AppType_Viewer2d:

{

myGeomWidget->Show2d();

break;

}

case AppType_Viewer3d:

{

myViewer3dSamples->AppendBottle();

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myGeomWidget->Show3d();

break;

}

case AppType_Geometry:

case AppType_Topology:

case AppType_PengKai:

case AppType_Triangulation:

case AppType_Unknown:

{

break;

}

}

}

void ApplicationCommonWindow::onAbout()

{

QMessageBox::information(this, tr("OCCT Overview"),

tr("Qt based application to study OpenCASCADE Technology"),

tr("Ok"), QString::null, QString::null, 0, 0);

}

TCollection_AsciiString ApplicationCommonWindow::getSampleSourceDir()

{

TCollection_AsciiString aSampleSourceDir = OSD_Environment("CSF_OCCTOverviewSampleCodePath").Value();

if (aSampleSourceDir.IsEmpty())

{

TCollection_AsciiString aCasRoot = OSD_Environment("CASROOT").Value();

if (!aCasRoot.IsEmpty())

{

aSampleSourceDir = aCasRoot + "/samples/OCCTOverview/code";

}

}

return aSampleSourceDir;

}

QAction* ApplicationCommonWindow::CreateAction (const QString& theActionName,

const QString& theShortcut,

const QString& theIconName)

{

QAction* aAction(NULL);

if (theIconName.isEmpty())

{

aAction = new QAction(theActionName, this);

}

else

{

QPixmap aIcon = QPixmap(theIconName);

aAction = new QAction(aIcon, theActionName, this);

}

aAction->setToolTip(theActionName);

aAction->setStatusTip(theActionName);

aAction->setShortcut(theShortcut);

return aAction;

}

template <typename PointerToMemberFunction>

QAction* ApplicationCommonWindow::CreateSample (PointerToMemberFunction theHandlerMethod,

const char* theActionName)

{

QAction* anAction = new QAction(QObject::tr(theActionName), this);

connect(anAction, SIGNAL(triggered()), this, SLOT(theHandlerMethod()));

return anAction;

}

void ApplicationCommonWindow::resizeEvent(QResizeEvent* e)

{

QMainWindow::resizeEvent(e);

statusBar()->setSizeGripEnabled(!isMaximized());

}

void ApplicationCommonWindow::onProcessSample(const QString& theSampleName)

{

QApplication::setOverrideCursor(Qt::WaitCursor);

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

GetCurrentSamples()->Process(theSampleName.toUtf8().data());

myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());

myDocument2d->SetObjects(GetCurrentSamples()->Get2dObjects());

myCodeView->setPlainText(GetCurrentSamples()->GetCode().ToCString());

myResultView->setPlainText(GetCurrentSamples()->GetResult().ToCString());

myGeomWidget->FitAll();

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessExchange(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

int aMode = 0;

QString aFileName = selectFileName(theSampleName, getDataExchangeDialog(theSampleName), aMode);

if (aFileName.isEmpty())

{

return;

}

QApplication::setOverrideCursor(Qt::WaitCursor);

myDataExchangeSamples->SetFileName(aFileName.toUtf8().data());

myDataExchangeSamples->SetStepType(static_cast<STEPControl_StepModelType>(aMode));

myDataExchangeSamples->Process(theSampleName.toUtf8().data());

myDocument3d->SetObjects(myDataExchangeSamples->Get3dObjects());

myDocument2d->SetObjects(myDataExchangeSamples->Get2dObjects());

myCodeView->setPlainText(myDataExchangeSamples->GetCode().ToCString());

myResultView->setPlainText(myDataExchangeSamples->GetResult().ToCString());

myGeomWidget->FitAll();

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessOcaf(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

if (theSampleName.indexOf("Dialog") == 0)

{

int aMode = 0; // not used

QString aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);

if (aFileName.isEmpty())

{

return;

}

myOcafSamples->SetFileName(aFileName.toUtf8().data());

}

QApplication::setOverrideCursor(Qt::WaitCursor);

myOcafSamples->Process(theSampleName.toUtf8().data());

myDocument2d->SetObjects(myOcafSamples->Get2dObjects());

myCodeView->setPlainText(myOcafSamples->GetCode().ToCString());

myResultView->setPlainText(myOcafSamples->GetResult().ToCString());

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessViewer3d(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

QApplication::setOverrideCursor(Qt::WaitCursor);

myViewer3dSamples->Process(theSampleName.toUtf8().data());

myCodeView->setPlainText(myViewer3dSamples->GetCode().ToCString());

myResultView->setPlainText(myViewer3dSamples->GetResult().ToCString());

myGeomWidget->FitAll();

QApplication::restoreOverrideCursor();

}

void ApplicationCommonWindow::onProcessViewer2d(const QString& theSampleName)

{

setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);

Standard_Boolean anIsFileSample = Viewer2dSamples::IsFileSample(theSampleName.toUtf8().data());

QString aFileName;

if (anIsFileSample)

{

int aMode = 0; // not used

aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);

if (aFileName.isEmpty())

{

return;

}

myViewer2dSamples->SetFileName(aFileName.toUtf8().data());

}

if (!anIsFileSample || (anIsFileSample && !aFileName.isEmpty()))

{

QApplication::setOverrideCursor(Qt::WaitCursor);

myViewer2dSamples->Process(theSampleName.toUtf8().data());

if (!Viewer2dSamples::IsShadedSample(theSampleName.toUtf8().data()))

{

myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_False);

}

else

{

myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_True);

}

myCodeView->setPlainText(myViewer2dSamples->GetCode().ToCString());

myResultView->setPlainText(myViewer2dSamples->GetResult().ToCString());

myGeomWidget->Show2d();

QApplication::restoreOverrideCursor();

}

else

{

myResultView->setPlainText("No file selected!");

}

}

QString ApplicationCommonWindow::selectFileName(const QString& theSampleName,

TranslateDialog* theDialog, int& theMode)

{

Q_UNUSED(theSampleName)

std::shared_ptr<TranslateDialog> aDialog(theDialog);

int ret = aDialog->exec();

theMode = aDialog->getMode();

qApp->processEvents();

QString aFilename;

QStringList aFileNameList;

if (ret != QDialog::Accepted)

{

return aFilename;

}

aFileNameList = aDialog->selectedFiles();

if (!aFileNameList.isEmpty())

{

aFilename = aFileNameList[0];

}

if (!QFileInfo(aFilename).completeSuffix().length())

{

QString selFilter = aDialog->selectedNameFilter();

int idx = selFilter.indexOf("(*.");

if (idx != -1)

{

QString tail = selFilter.mid(idx + 3);

idx = tail.indexOf(" ");

if (idx == -1)

{

idx = tail.indexOf(")");

}

QString ext = tail.left(idx);

if (ext.length())

{

aFilename += QString(".") + ext;

}

}

}

return aFilename;

}

TranslateDialog* ApplicationCommonWindow::getDataExchangeDialog(const QString& theSampleName)

{

TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);

TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());

if (DataExchangeSamples::IsExportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Export file");

aTranslateDialog->setFileMode(QFileDialog::AnyFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);

}

else if (DataExchangeSamples::IsImportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Import file");

aTranslateDialog->setFileMode(QFileDialog::ExistingFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);

}

QString aFormatFilter;

if (DataExchangeSamples::IsBrepSample(aSampleName))

{

aFormatFilter = "BREP Files(*.brep *.rle)";

}

else if (DataExchangeSamples::IsStepSample(aSampleName))

{

aFormatFilter = "STEP Files (*.stp *.step)";

aTranslateDialog->addMode(STEPControl_ManifoldSolidBrep, "Manifold Solid Brep");

aTranslateDialog->addMode(STEPControl_FacetedBrep, "Faceted Brep");

aTranslateDialog->addMode(STEPControl_ShellBasedSurfaceModel, "Shell Based Surface Model");

aTranslateDialog->addMode(STEPControl_GeometricCurveSet, "Geometric Curve Set");

}

else if (DataExchangeSamples::IsIgesSample(aSampleName))

{

aFormatFilter = "IGES Files (*.igs *.iges)";

}

else if (DataExchangeSamples::IsStlSample(aSampleName))

{

aFormatFilter = "STL Files (*.stl)";

}

else if (DataExchangeSamples::IsVrmlSample(aSampleName))

{

aFormatFilter = "VRML Files (*.vrml)";

}

else if (DataExchangeSamples::IsImageSample(aSampleName))

{

aFormatFilter = "All Image Files (*.bmp *.gif *.jpg *.jpeg *.png *.tga)";

}

QStringList aFilters;

aFilters.append(aFormatFilter);

aFilters.append("All Files(*.*)");

aTranslateDialog->setNameFilters(aFilters);

aTranslateDialog->clear();

return aTranslateDialog;

}

TranslateDialog* ApplicationCommonWindow::getOcafDialog(const QString& theSampleName)

{

TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);

TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());

if (OcafSamples::IsExportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Export file");

aTranslateDialog->setFileMode(QFileDialog::AnyFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);

}

else if (OcafSamples::IsImportSample(aSampleName))

{

aTranslateDialog->setWindowTitle("Import file");

aTranslateDialog->setFileMode(QFileDialog::ExistingFile);

aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);

}

QStringList aFilters;

if (OcafSamples::IsBinarySample(aSampleName))

{

aFilters.append("Binary OCAF Sample (*.cbf)");

}

if (OcafSamples::IsXmlSample(aSampleName))

{

aFilters.append("XML OCAF Sample (*.xml)");

}

aFilters.append("All Files(*.*)");

aTranslateDialog->setNameFilters(aFilters);

aTranslateDialog->clear();

return aTranslateDialog;

}

QMenu* ApplicationCommonWindow::MenuFromDomNode(QDomElement& theItemElement,

QWidget* theParent,

QSignalMapper* theMapper)

{

QString anItemName = theItemElement.attribute("name");

QMenu* aMenu = new QMenu(anItemName, theParent);

QDomElement anChildItemElement = theItemElement.firstChildElement("MenuItem");

QDomElement anSampleElement = theItemElement.firstChildElement("Sample");

while(anChildItemElement.isElement())

{

aMenu->addMenu(MenuFromDomNode(anChildItemElement, aMenu, theMapper));

anChildItemElement = anChildItemElement.nextSibling().toElement();

}

while(anSampleElement.isElement())

{

QString aSampleName = anSampleElement.attribute("name");

QString aSampleFunction = anSampleElement.attribute("function");

QAction* anAction = aMenu->addAction(aSampleFunction);

anAction->setText(aSampleName);

theMapper->setMapping(anAction, aSampleFunction);

connect(anAction, SIGNAL(triggered()), theMapper, SLOT(map()));

anSampleElement = anSampleElement.nextSibling().toElement();

}

return aMenu;

}

void ApplicationCommonWindow::MenuFormXml(const QString& thePath,

QSignalMapper* theMapper,

QList<QMenu*>& theMunusList)

{

QDomDocument aDomDocument;

theMunusList.clear();

QFile aXmlFile(thePath);

QString anErrorMessage;

if (aXmlFile.error() != QFile::NoError)

{

anErrorMessage = aXmlFile.errorString();

Message::SendFail() << "QFile creating error: " << anErrorMessage.toUtf8().constData();

aXmlFile.close();

return;

}

if (!aXmlFile.open(QIODevice::ReadOnly | QIODevice::Text))

{

Message::SendFail() << "File " << thePath.toUtf8().constData() << " could not open";

if (aXmlFile.error() != QFile::NoError)

{

anErrorMessage = aXmlFile.errorString();

Message::SendFail() << "QFile opening error: " << anErrorMessage.toUtf8().constData();

}

aXmlFile.close();

return;

}

bool aNamespaceProcessing(false);

QString anErrorMsg;

int anErrorLine(0);

int anErrorColumn(0);

if (!aDomDocument.setContent(&aXmlFile, aNamespaceProcessing, &anErrorMsg, &anErrorLine, &anErrorColumn))

{

Message::SendFail() << "XML file parsing error: " << anErrorMsg.toStdString()

<< " at line: " << anErrorLine << " column: " << anErrorColumn;

aXmlFile.close();

return;

}

aXmlFile.close();

QDomElement aRootElement = aDomDocument.documentElement();

QDomElement anItemElement = aRootElement.firstChildElement("MenuItem");

while(!anItemElement.isNull())

{

theMunusList.push_back(MenuFromDomNode(anItemElement, this, theMapper));

anItemElement = anItemElement.nextSiblingElement("MenuItem");

}

}

第五处修改:重新使用前面cmake编译的方法进行编译,重新生成build,运行以后就可以看到自己添加的按钮了,点击按钮即可触发测试函数,后续就可以自己在测试函数中编写测试案例

5、总结

注意好以下几个关键点:

1、环境和软件以及源码提前准备好

2、Cmake编译的时候记得修改成自己文件路径所在位置

3、一般而言配置完以后运行成功就行,自定义测试需要修改的地方较多,不易操作



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。