当前位置:   article > 正文

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

occt安装

前言

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

  1. CASROOT=E:\cpp\code\OCCT\OCCT-7_8_0
  2. CSF_FPE=0
  3. CSF_OCCTResourcePath=E:\cpp\code\OCCT\OCCT-7_8_0/src
  4. CSF_OCCTDataPath=E:\cpp\code\OCCT\OCCT-7_8_0/data
  5. CSF_OCCTSamplesPath=E:\cpp\code\OCCT\OCCT-7_8_0/samples
  6. CSF_OCCTTestsPath=E:\cpp\code\OCCT\OCCT-7_8_0/tests
  7. CSF_OCCTDocPath=E:\cpp\code\OCCT\OCCT-7_8_0/doc
  8. QT_DEBUG_PLUGINS=1
  9. 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不同的地方即可,按照对应位置改就行。这里我附上我的源码。

  1. #include "PengKaiSamples.h"
  2. void PengKaiSamples::ExecuteSample(const TCollection_AsciiString& theSampleName)
  3. {
  4. Standard_Boolean anIsSamplePresent = Standard_True;
  5. FindSourceCode(theSampleName);
  6. if (theSampleName == "FirstTest")
  7. FirstTest();
  8. else
  9. {
  10. myResult << "No function found: " << theSampleName;
  11. myCode += TCollection_AsciiString("No function found: ") + theSampleName;
  12. anIsSamplePresent = Standard_False;
  13. }
  14. myIsProcessed = anIsSamplePresent;
  15. }
  16. void PengKaiSamples::FirstTest()
  17. {
  18. for (int i = 0; i < 20; i++)
  19. {
  20. std::cout << "enter FirstTest" << std::endl;
  21. }
  22. }
  1. #ifndef PENGKAISAMPLES_H
  2. #define PENGKAISAMPLES_H
  3. #include "BaseSample.h"
  4. #include <AIS_InteractiveContext.hxx>
  5. //! Implements PengKai samples
  6. class PengKaiSamples : public BaseSample
  7. {
  8. DEFINE_STANDARD_RTTI_INLINE(PengKaiSamples, BaseSample)
  9. public:
  10. PengKaiSamples(const TCollection_AsciiString& theSampleSourcePath,
  11. const Handle(AIS_InteractiveContext)& theContext)
  12. : BaseSample(theSampleSourcePath, theContext)
  13. {}
  14. protected:
  15. virtual void ExecuteSample(const TCollection_AsciiString& theSampleName) Standard_OVERRIDE;
  16. private:
  17. // One function for every sample
  18. void FirstTest();
  19. };
  20. #endif //PENGKAISAMPLES_H

第二处修改:添加XML文件

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

  1. <Menu>
  2. <MenuItem name="PengKai">
  3. <MenuItem name="PengKai Test">
  4. <Sample name="FirstTest" function="FirstTest"/>
  5. </MenuItem>
  6. </MenuItem>
  7. </Menu>

第三处修改:

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

  1. AdaptorCurve2d_AIS.cxx
  2. AdaptorCurve2d_AIS.h
  3. AdaptorCurve_AIS.cxx
  4. AdaptorCurve_AIS.h
  5. AdaptorPnt2d_AIS.cxx
  6. AdaptorPnt2d_AIS.h
  7. AdaptorVec_AIS.cxx
  8. AdaptorVec_AIS.h
  9. BaseSample.cxx
  10. BaseSample.h
  11. DataExchange.xml
  12. DataExchangeSamples.cxx
  13. DataExchangeSamples.h
  14. Geometry.xml
  15. GeometrySamples.cxx
  16. GeometrySamples.h
  17. MakeBottle.cxx
  18. MakeBottle.h
  19. Ocaf.xml
  20. OcafSamples.cxx
  21. OcafSamples.h
  22. Sample2D_Face.cxx
  23. Sample2D_Face.h
  24. Sample2D_Image.cxx
  25. Sample2D_Image.h
  26. Sample2D_Markers.cxx
  27. Sample2D_Markers.h
  28. Samples.qrc
  29. TOcafFunction_BoxDriver.cxx
  30. TOcafFunction_BoxDriver.h
  31. TOcafFunction_CutDriver.cxx
  32. TOcafFunction_CutDriver.h
  33. TOcafFunction_CylDriver.cxx
  34. TOcafFunction_CylDriver.h
  35. TOcaf_Application.cxx
  36. TOcaf_Application.h
  37. Topology.xml
  38. TopologySamples.cxx
  39. TopologySamples.h
  40. Triangulation.xml
  41. TriangulationSamples.cxx
  42. TriangulationSamples.h
  43. Viewer2d.xml
  44. Viewer2dSamples.cxx
  45. Viewer2dSamples.h
  46. Viewer3d.xml
  47. Viewer3dSamples.cxx
  48. Viewer3dSamples.h
  49. PengKai.xml
  50. PengKaiSamples.cxx
  51. PengKaiSamples.h

第四处修改:

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

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

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

  1. // Copyright (c) 2020 OPEN CASCADE SAS
  2. //
  3. // This file is part of the examples of the Open CASCADE Technology software library.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
  21. #include "ApplicationCommon.h"
  22. #include <Standard_WarningsDisable.hxx>
  23. #include <QApplication>
  24. #include <QDir>
  25. #include <QFile>
  26. #include <QFont>
  27. #include <QFrame>
  28. #include <QGroupBox>
  29. #include <QMap>
  30. #include <QMdiArea>
  31. #include <QMdiSubWindow>
  32. #include <QMenuBar>
  33. #include <QMessageBox>
  34. #include <QPair>
  35. #include <QSplitter>
  36. #include <QStatusBar>
  37. #include <QtGlobal>
  38. #include <QHBoxLayout>
  39. #include <QVBoxLayout>
  40. #include <QWidget>
  41. #include <QDomDocument>
  42. #include <QDomAttr>
  43. #include <Standard_WarningsRestore.hxx>
  44. #include <OpenGl_GraphicDriver.hxx>
  45. #include <OSD_Environment.hxx>
  46. #include <stdlib.h>
  47. #include <memory>
  48. ApplicationCommonWindow::ApplicationCommonWindow (ApplicationType theCategory)
  49. : QMainWindow (nullptr),
  50. myAppType(theCategory),
  51. myStdToolBar (nullptr),
  52. myViewBar (nullptr),
  53. myCasCadeBar (nullptr),
  54. myFilePopup (nullptr),
  55. myCategoryPopup (nullptr)
  56. {
  57. ALL_CATEGORIES[AppType_Geometry] = "Geometry";
  58. ALL_CATEGORIES[AppType_Topology] = "Topology";
  59. ALL_CATEGORIES[AppType_Triangulation] = "Triangulation";
  60. ALL_CATEGORIES[AppType_DataExchange] = "DataExchange";
  61. ALL_CATEGORIES[AppType_Ocaf] = "OCAF";
  62. ALL_CATEGORIES[AppType_Viewer3d] = "3D viewer";
  63. ALL_CATEGORIES[AppType_Viewer2d] = "2D Viewer";
  64. ALL_CATEGORIES[AppType_PengKai] = "PengKai";
  65. mySampleMapper = new QSignalMapper(this);
  66. myExchangeMapper = new QSignalMapper(this);
  67. myOcafMapper = new QSignalMapper(this);
  68. myViewer3dMapper = new QSignalMapper(this);
  69. myViewer2dMapper = new QSignalMapper(this);
  70. myCategoryMapper = new QSignalMapper(this);
  71. connect(mySampleMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessSample(const QString &)));
  72. connect(myExchangeMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessExchange(const QString &)));
  73. connect(myOcafMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessOcaf(const QString &)));
  74. connect(myViewer3dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer3d(const QString &)));
  75. connect(myViewer2dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer2d(const QString &)));
  76. connect(myCategoryMapper, SIGNAL(mapped(const QString &)), this, SLOT(onChangeCategory(const QString &)));
  77. setFocusPolicy(Qt::StrongFocus);
  78. QFont aCodeViewFont;
  79. aCodeViewFont.setFamily("Courier");
  80. aCodeViewFont.setFixedPitch(true);
  81. aCodeViewFont.setPointSize(10);
  82. QGroupBox* aCodeFrame = new QGroupBox(tr("Sample code"));
  83. QVBoxLayout* aCodeLayout = new QVBoxLayout(aCodeFrame);
  84. aCodeLayout->setContentsMargins(3, 3, 3, 3);
  85. myCodeView = new QTextEdit(aCodeFrame);
  86. aCodeLayout->addWidget(myCodeView);
  87. myCodeView->setDocumentTitle("Code");
  88. myCodeView->setLineWrapMode(QTextEdit::NoWrap);
  89. myCodeView->setReadOnly(true);
  90. myCodeView->setFont(aCodeViewFont);
  91. myCodeViewHighlighter = new OcctHighlighter(myCodeView->document());
  92. QGroupBox* aResultFrame = new QGroupBox(tr("Output"));
  93. QVBoxLayout* aResultLayout = new QVBoxLayout(aResultFrame);
  94. aResultLayout->setContentsMargins(3, 3, 3, 3);
  95. myResultView = new QTextEdit(aResultFrame);
  96. aResultLayout->addWidget(myResultView);
  97. myResultView->setDocumentTitle("Output");
  98. myResultView->setReadOnly(true);
  99. myResultView->setFont(aCodeViewFont);
  100. QSplitter* aCodeResultSplitter = new QSplitter(Qt::Vertical);
  101. aCodeResultSplitter->addWidget(aCodeFrame);
  102. aCodeResultSplitter->addWidget(aResultFrame);
  103. myDocument3d = createNewDocument();
  104. myDocument2d = createNewDocument();
  105. QFrame* aViewFrame = new QFrame;
  106. aViewFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
  107. aViewFrame->setLineWidth(3);
  108. QVBoxLayout* aViewLayout = new QVBoxLayout(aViewFrame);
  109. aViewLayout->setContentsMargins(0, 0, 0, 0);
  110. myGeomWidget = new GeomWidget(myDocument3d, myDocument2d, aViewFrame);
  111. aViewLayout->addWidget(myGeomWidget);
  112. myGeomWidget->setContentsMargins(0, 0, 0, 0);
  113. QSplitter* aGeomTextSplitter = new QSplitter(Qt::Horizontal);
  114. aGeomTextSplitter->addWidget(aViewFrame);
  115. aGeomTextSplitter->addWidget(aCodeResultSplitter);
  116. aGeomTextSplitter->setStretchFactor(0, 1);
  117. aGeomTextSplitter->setStretchFactor(1, 1);
  118. QList<int> aSizeList;
  119. aSizeList.append(640);
  120. aSizeList.append(640);
  121. aGeomTextSplitter->setSizes(aSizeList);
  122. setCentralWidget(aGeomTextSplitter);
  123. #include <Standard_WarningsDisable.hxx>
  124. Q_INIT_RESOURCE(Samples);
  125. #include <Standard_WarningsRestore.hxx>
  126. TCollection_AsciiString aSampleSourcePach = getSampleSourceDir();
  127. myGeometrySamples = new GeometrySamples(aSampleSourcePach,
  128. myDocument3d->getContext());
  129. myTopologySamples = new TopologySamples(aSampleSourcePach,
  130. myDocument3d->getContext());
  131. myTriangulationSamples = new TriangulationSamples(aSampleSourcePach,
  132. myDocument3d->getContext());
  133. myDataExchangeSamples = new DataExchangeSamples(aSampleSourcePach,
  134. myGeomWidget->Get3dView(),
  135. myDocument3d->getContext());
  136. myOcafSamples = new OcafSamples(aSampleSourcePach,
  137. myDocument3d->getViewer(),
  138. myDocument3d->getContext());
  139. myViewer3dSamples = new Viewer3dSamples(aSampleSourcePach,
  140. myGeomWidget->Get3dView(),
  141. myDocument3d->getContext());
  142. myViewer2dSamples = new Viewer2dSamples(aSampleSourcePach,
  143. myGeomWidget->Get2dView(),
  144. myDocument2d->getViewer(),
  145. myDocument2d->getContext());
  146. myPengKaiSamples = new PengKaiSamples(aSampleSourcePach,
  147. myDocument3d->getContext());
  148. MenuFormXml(":/menus/Geometry.xml", mySampleMapper, myGeometryMenus);
  149. MenuFormXml(":/menus/Topology.xml", mySampleMapper, myTopologyMenus);
  150. MenuFormXml(":/menus/Triangulation.xml", mySampleMapper, myTriangulationMenus);
  151. MenuFormXml(":/menus/DataExchange.xml", myExchangeMapper, myDataExchangeMenus);
  152. MenuFormXml(":/menus/Ocaf.xml", myOcafMapper, myOcafMenus);
  153. MenuFormXml(":/menus/Viewer3d.xml", myViewer3dMapper, myViewer3dMenus);
  154. MenuFormXml(":/menus/Viewer2d.xml", myViewer2dMapper, myViewer2dMenus);
  155. MenuFormXml(":/menus/PengKai.xml", mySampleMapper, myPengKaiMenus);
  156. onChangeCategory(ALL_CATEGORIES[myAppType]);
  157. resize(1280, 560);
  158. }
  159. void ApplicationCommonWindow::RebuildMenu()
  160. {
  161. menuBar()->clear();
  162. myStdActions[StdActions_FileQuit] = CreateAction("Quit", "CTRL+Q");
  163. connect(myStdActions[StdActions_FileQuit], SIGNAL(triggered()), this, SLOT(onCloseAllWindows()));
  164. myStdActions[StdActions_HelpAbout] = CreateAction("About", "F1", ":/icons/help.png");
  165. connect(myStdActions[StdActions_HelpAbout], SIGNAL(triggered()), this, SLOT(onAbout()));
  166. // populate a menu with all actions
  167. myFilePopup = new QMenu(this);
  168. myFilePopup = menuBar()->addMenu(tr("&File"));
  169. myFilePopup->addAction(myStdActions[StdActions_FileQuit]);
  170. myCategoryPopup = new QMenu(this);
  171. myCategoryPopup = menuBar()->addMenu(tr("&Category"));
  172. foreach (ApplicationType aCategory, ALL_CATEGORIES.keys())
  173. {
  174. QString aCategoryName = ALL_CATEGORIES.value(aCategory);
  175. QAction* anAction = myCategoryPopup->addAction(aCategoryName);
  176. anAction->setText(aCategoryName);
  177. myCategoryMapper->setMapping(anAction, aCategoryName);
  178. connect(anAction, SIGNAL(triggered()), myCategoryMapper, SLOT(map()));
  179. myCategoryPopup->addAction(anAction);
  180. myCategoryActions.insert(aCategory, anAction);
  181. }
  182. foreach (QMenu* aSampleMenu, GetCurrentMenus())
  183. {
  184. menuBar()->addMenu(aSampleMenu);
  185. }
  186. // add a help menu
  187. QMenu* aHelp = new QMenu(this);
  188. menuBar()->addSeparator();
  189. aHelp = menuBar()->addMenu(tr("&Help"));
  190. aHelp->addAction(myStdActions[StdActions_HelpAbout]);
  191. }
  192. Handle(BaseSample) ApplicationCommonWindow::GetCurrentSamples()
  193. {
  194. switch (myAppType)
  195. {
  196. case AppType_Geometry: return myGeometrySamples;
  197. case AppType_Topology: return myTopologySamples;
  198. case AppType_Triangulation: return myTriangulationSamples;
  199. case AppType_DataExchange: return myDataExchangeSamples;
  200. case AppType_Ocaf: return myOcafSamples;
  201. case AppType_Viewer2d: return myViewer2dSamples;
  202. case AppType_Viewer3d: return myViewer3dSamples;
  203. case AppType_PengKai: return myPengKaiSamples;
  204. case AppType_Unknown:
  205. break;
  206. }
  207. throw QString("Unknown Application type");
  208. }
  209. const QList<QMenu*>& ApplicationCommonWindow::GetCurrentMenus()
  210. {
  211. switch (myAppType)
  212. {
  213. case AppType_Geometry: return myGeometryMenus;
  214. case AppType_Topology: return myTopologyMenus;
  215. case AppType_Triangulation: return myTriangulationMenus;
  216. case AppType_DataExchange: return myDataExchangeMenus;
  217. case AppType_Ocaf: return myOcafMenus;
  218. case AppType_Viewer2d: return myViewer2dMenus;
  219. case AppType_Viewer3d: return myViewer3dMenus;
  220. case AppType_PengKai: return myPengKaiMenus;
  221. case AppType_Unknown:
  222. break;
  223. }
  224. throw QString("Unknown Application type");
  225. }
  226. DocumentCommon* ApplicationCommonWindow::createNewDocument()
  227. {
  228. return new DocumentCommon(this);
  229. }
  230. void ApplicationCommonWindow::onChangeCategory(const QString& theCategory)
  231. {
  232. myAppType = ALL_CATEGORIES.key(theCategory);
  233. setWindowTitle(ALL_CATEGORIES[myAppType]);
  234. myOcafSamples->ClearExtra();
  235. myViewer3dSamples->ClearExtra();
  236. myViewer2dSamples->ClearExtra();
  237. GetCurrentSamples()->Clear();
  238. myDocument3d->Clear();
  239. myDocument2d->Clear();
  240. myCodeView->setPlainText("");
  241. myResultView->setPlainText("");
  242. GetCurrentSamples()->AppendCube();
  243. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  244. myGeomWidget->FitAll();
  245. RebuildMenu();
  246. switch (myAppType)
  247. {
  248. case AppType_DataExchange:
  249. {
  250. myDataExchangeSamples->AppendBottle();
  251. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  252. myGeomWidget->Show3d();
  253. break;
  254. }
  255. case AppType_Ocaf:
  256. {
  257. onProcessOcaf("CreateOcafDocument");
  258. myGeomWidget->Show3d();
  259. break;
  260. }
  261. case AppType_Viewer2d:
  262. {
  263. myGeomWidget->Show2d();
  264. break;
  265. }
  266. case AppType_Viewer3d:
  267. {
  268. myViewer3dSamples->AppendBottle();
  269. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  270. myGeomWidget->Show3d();
  271. break;
  272. }
  273. case AppType_Geometry:
  274. case AppType_Topology:
  275. case AppType_PengKai:
  276. case AppType_Triangulation:
  277. case AppType_Unknown:
  278. {
  279. break;
  280. }
  281. }
  282. }
  283. void ApplicationCommonWindow::onAbout()
  284. {
  285. QMessageBox::information(this, tr("OCCT Overview"),
  286. tr("Qt based application to study OpenCASCADE Technology"),
  287. tr("Ok"), QString::null, QString::null, 0, 0);
  288. }
  289. TCollection_AsciiString ApplicationCommonWindow::getSampleSourceDir()
  290. {
  291. TCollection_AsciiString aSampleSourceDir = OSD_Environment("CSF_OCCTOverviewSampleCodePath").Value();
  292. if (aSampleSourceDir.IsEmpty())
  293. {
  294. TCollection_AsciiString aCasRoot = OSD_Environment("CASROOT").Value();
  295. if (!aCasRoot.IsEmpty())
  296. {
  297. aSampleSourceDir = aCasRoot + "/samples/OCCTOverview/code";
  298. }
  299. }
  300. return aSampleSourceDir;
  301. }
  302. QAction* ApplicationCommonWindow::CreateAction (const QString& theActionName,
  303. const QString& theShortcut,
  304. const QString& theIconName)
  305. {
  306. QAction* aAction(NULL);
  307. if (theIconName.isEmpty())
  308. {
  309. aAction = new QAction(theActionName, this);
  310. }
  311. else
  312. {
  313. QPixmap aIcon = QPixmap(theIconName);
  314. aAction = new QAction(aIcon, theActionName, this);
  315. }
  316. aAction->setToolTip(theActionName);
  317. aAction->setStatusTip(theActionName);
  318. aAction->setShortcut(theShortcut);
  319. return aAction;
  320. }
  321. template <typename PointerToMemberFunction>
  322. QAction* ApplicationCommonWindow::CreateSample (PointerToMemberFunction theHandlerMethod,
  323. const char* theActionName)
  324. {
  325. QAction* anAction = new QAction(QObject::tr(theActionName), this);
  326. connect(anAction, SIGNAL(triggered()), this, SLOT(theHandlerMethod()));
  327. return anAction;
  328. }
  329. void ApplicationCommonWindow::resizeEvent(QResizeEvent* e)
  330. {
  331. QMainWindow::resizeEvent(e);
  332. statusBar()->setSizeGripEnabled(!isMaximized());
  333. }
  334. void ApplicationCommonWindow::onProcessSample(const QString& theSampleName)
  335. {
  336. QApplication::setOverrideCursor(Qt::WaitCursor);
  337. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  338. GetCurrentSamples()->Process(theSampleName.toUtf8().data());
  339. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  340. myDocument2d->SetObjects(GetCurrentSamples()->Get2dObjects());
  341. myCodeView->setPlainText(GetCurrentSamples()->GetCode().ToCString());
  342. myResultView->setPlainText(GetCurrentSamples()->GetResult().ToCString());
  343. myGeomWidget->FitAll();
  344. QApplication::restoreOverrideCursor();
  345. }
  346. void ApplicationCommonWindow::onProcessExchange(const QString& theSampleName)
  347. {
  348. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  349. int aMode = 0;
  350. QString aFileName = selectFileName(theSampleName, getDataExchangeDialog(theSampleName), aMode);
  351. if (aFileName.isEmpty())
  352. {
  353. return;
  354. }
  355. QApplication::setOverrideCursor(Qt::WaitCursor);
  356. myDataExchangeSamples->SetFileName(aFileName.toUtf8().data());
  357. myDataExchangeSamples->SetStepType(static_cast<STEPControl_StepModelType>(aMode));
  358. myDataExchangeSamples->Process(theSampleName.toUtf8().data());
  359. myDocument3d->SetObjects(myDataExchangeSamples->Get3dObjects());
  360. myDocument2d->SetObjects(myDataExchangeSamples->Get2dObjects());
  361. myCodeView->setPlainText(myDataExchangeSamples->GetCode().ToCString());
  362. myResultView->setPlainText(myDataExchangeSamples->GetResult().ToCString());
  363. myGeomWidget->FitAll();
  364. QApplication::restoreOverrideCursor();
  365. }
  366. void ApplicationCommonWindow::onProcessOcaf(const QString& theSampleName)
  367. {
  368. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  369. if (theSampleName.indexOf("Dialog") == 0)
  370. {
  371. int aMode = 0; // not used
  372. QString aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);
  373. if (aFileName.isEmpty())
  374. {
  375. return;
  376. }
  377. myOcafSamples->SetFileName(aFileName.toUtf8().data());
  378. }
  379. QApplication::setOverrideCursor(Qt::WaitCursor);
  380. myOcafSamples->Process(theSampleName.toUtf8().data());
  381. myDocument2d->SetObjects(myOcafSamples->Get2dObjects());
  382. myCodeView->setPlainText(myOcafSamples->GetCode().ToCString());
  383. myResultView->setPlainText(myOcafSamples->GetResult().ToCString());
  384. QApplication::restoreOverrideCursor();
  385. }
  386. void ApplicationCommonWindow::onProcessViewer3d(const QString& theSampleName)
  387. {
  388. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  389. QApplication::setOverrideCursor(Qt::WaitCursor);
  390. myViewer3dSamples->Process(theSampleName.toUtf8().data());
  391. myCodeView->setPlainText(myViewer3dSamples->GetCode().ToCString());
  392. myResultView->setPlainText(myViewer3dSamples->GetResult().ToCString());
  393. myGeomWidget->FitAll();
  394. QApplication::restoreOverrideCursor();
  395. }
  396. void ApplicationCommonWindow::onProcessViewer2d(const QString& theSampleName)
  397. {
  398. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  399. Standard_Boolean anIsFileSample = Viewer2dSamples::IsFileSample(theSampleName.toUtf8().data());
  400. QString aFileName;
  401. if (anIsFileSample)
  402. {
  403. int aMode = 0; // not used
  404. aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);
  405. if (aFileName.isEmpty())
  406. {
  407. return;
  408. }
  409. myViewer2dSamples->SetFileName(aFileName.toUtf8().data());
  410. }
  411. if (!anIsFileSample || (anIsFileSample && !aFileName.isEmpty()))
  412. {
  413. QApplication::setOverrideCursor(Qt::WaitCursor);
  414. myViewer2dSamples->Process(theSampleName.toUtf8().data());
  415. if (!Viewer2dSamples::IsShadedSample(theSampleName.toUtf8().data()))
  416. {
  417. myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_False);
  418. }
  419. else
  420. {
  421. myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_True);
  422. }
  423. myCodeView->setPlainText(myViewer2dSamples->GetCode().ToCString());
  424. myResultView->setPlainText(myViewer2dSamples->GetResult().ToCString());
  425. myGeomWidget->Show2d();
  426. QApplication::restoreOverrideCursor();
  427. }
  428. else
  429. {
  430. myResultView->setPlainText("No file selected!");
  431. }
  432. }
  433. QString ApplicationCommonWindow::selectFileName(const QString& theSampleName,
  434. TranslateDialog* theDialog, int& theMode)
  435. {
  436. Q_UNUSED(theSampleName)
  437. std::shared_ptr<TranslateDialog> aDialog(theDialog);
  438. int ret = aDialog->exec();
  439. theMode = aDialog->getMode();
  440. qApp->processEvents();
  441. QString aFilename;
  442. QStringList aFileNameList;
  443. if (ret != QDialog::Accepted)
  444. {
  445. return aFilename;
  446. }
  447. aFileNameList = aDialog->selectedFiles();
  448. if (!aFileNameList.isEmpty())
  449. {
  450. aFilename = aFileNameList[0];
  451. }
  452. if (!QFileInfo(aFilename).completeSuffix().length())
  453. {
  454. QString selFilter = aDialog->selectedNameFilter();
  455. int idx = selFilter.indexOf("(*.");
  456. if (idx != -1)
  457. {
  458. QString tail = selFilter.mid(idx + 3);
  459. idx = tail.indexOf(" ");
  460. if (idx == -1)
  461. {
  462. idx = tail.indexOf(")");
  463. }
  464. QString ext = tail.left(idx);
  465. if (ext.length())
  466. {
  467. aFilename += QString(".") + ext;
  468. }
  469. }
  470. }
  471. return aFilename;
  472. }
  473. TranslateDialog* ApplicationCommonWindow::getDataExchangeDialog(const QString& theSampleName)
  474. {
  475. TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);
  476. TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());
  477. if (DataExchangeSamples::IsExportSample(aSampleName))
  478. {
  479. aTranslateDialog->setWindowTitle("Export file");
  480. aTranslateDialog->setFileMode(QFileDialog::AnyFile);
  481. aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);
  482. }
  483. else if (DataExchangeSamples::IsImportSample(aSampleName))
  484. {
  485. aTranslateDialog->setWindowTitle("Import file");
  486. aTranslateDialog->setFileMode(QFileDialog::ExistingFile);
  487. aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);
  488. }
  489. QString aFormatFilter;
  490. if (DataExchangeSamples::IsBrepSample(aSampleName))
  491. {
  492. aFormatFilter = "BREP Files(*.brep *.rle)";
  493. }
  494. else if (DataExchangeSamples::IsStepSample(aSampleName))
  495. {
  496. aFormatFilter = "STEP Files (*.stp *.step)";
  497. aTranslateDialog->addMode(STEPControl_ManifoldSolidBrep, "Manifold Solid Brep");
  498. aTranslateDialog->addMode(STEPControl_FacetedBrep, "Faceted Brep");
  499. aTranslateDialog->addMode(STEPControl_ShellBasedSurfaceModel, "Shell Based Surface Model");
  500. aTranslateDialog->addMode(STEPControl_GeometricCurveSet, "Geometric Curve Set");
  501. }
  502. else if (DataExchangeSamples::IsIgesSample(aSampleName))
  503. {
  504. aFormatFilter = "IGES Files (*.igs *.iges)";
  505. }
  506. else if (DataExchangeSamples::IsStlSample(aSampleName))
  507. {
  508. aFormatFilter = "STL Files (*.stl)";
  509. }
  510. else if (DataExchangeSamples::IsVrmlSample(aSampleName))
  511. {
  512. aFormatFilter = "VRML Files (*.vrml)";
  513. }
  514. else if (DataExchangeSamples::IsImageSample(aSampleName))
  515. {
  516. aFormatFilter = "All Image Files (*.bmp *.gif *.jpg *.jpeg *.png *.tga)";
  517. }
  518. QStringList aFilters;
  519. aFilters.append(aFormatFilter);
  520. aFilters.append("All Files(*.*)");
  521. aTranslateDialog->setNameFilters(aFilters);
  522. aTranslateDialog->clear();
  523. return aTranslateDialog;
  524. }
  525. TranslateDialog* ApplicationCommonWindow::getOcafDialog(const QString& theSampleName)
  526. {
  527. TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);
  528. TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());
  529. if (OcafSamples::IsExportSample(aSampleName))
  530. {
  531. aTranslateDialog->setWindowTitle("Export file");
  532. aTranslateDialog->setFileMode(QFileDialog::AnyFile);
  533. aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);
  534. }
  535. else if (OcafSamples::IsImportSample(aSampleName))
  536. {
  537. aTranslateDialog->setWindowTitle("Import file");
  538. aTranslateDialog->setFileMode(QFileDialog::ExistingFile);
  539. aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);
  540. }
  541. QStringList aFilters;
  542. if (OcafSamples::IsBinarySample(aSampleName))
  543. {
  544. aFilters.append("Binary OCAF Sample (*.cbf)");
  545. }
  546. if (OcafSamples::IsXmlSample(aSampleName))
  547. {
  548. aFilters.append("XML OCAF Sample (*.xml)");
  549. }
  550. aFilters.append("All Files(*.*)");
  551. aTranslateDialog->setNameFilters(aFilters);
  552. aTranslateDialog->clear();
  553. return aTranslateDialog;
  554. }
  555. QMenu* ApplicationCommonWindow::MenuFromDomNode(QDomElement& theItemElement,
  556. QWidget* theParent,
  557. QSignalMapper* theMapper)
  558. {
  559. QString anItemName = theItemElement.attribute("name");
  560. QMenu* aMenu = new QMenu(anItemName, theParent);
  561. QDomElement anChildItemElement = theItemElement.firstChildElement("MenuItem");
  562. QDomElement anSampleElement = theItemElement.firstChildElement("Sample");
  563. while(anChildItemElement.isElement())
  564. {
  565. aMenu->addMenu(MenuFromDomNode(anChildItemElement, aMenu, theMapper));
  566. anChildItemElement = anChildItemElement.nextSibling().toElement();
  567. }
  568. while(anSampleElement.isElement())
  569. {
  570. QString aSampleName = anSampleElement.attribute("name");
  571. QString aSampleFunction = anSampleElement.attribute("function");
  572. QAction* anAction = aMenu->addAction(aSampleFunction);
  573. anAction->setText(aSampleName);
  574. theMapper->setMapping(anAction, aSampleFunction);
  575. connect(anAction, SIGNAL(triggered()), theMapper, SLOT(map()));
  576. anSampleElement = anSampleElement.nextSibling().toElement();
  577. }
  578. return aMenu;
  579. }
  580. void ApplicationCommonWindow::MenuFormXml(const QString& thePath,
  581. QSignalMapper* theMapper,
  582. QList<QMenu*>& theMunusList)
  583. {
  584. QDomDocument aDomDocument;
  585. theMunusList.clear();
  586. QFile aXmlFile(thePath);
  587. QString anErrorMessage;
  588. if (aXmlFile.error() != QFile::NoError)
  589. {
  590. anErrorMessage = aXmlFile.errorString();
  591. Message::SendFail() << "QFile creating error: " << anErrorMessage.toUtf8().constData();
  592. aXmlFile.close();
  593. return;
  594. }
  595. if (!aXmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
  596. {
  597. Message::SendFail() << "File " << thePath.toUtf8().constData() << " could not open";
  598. if (aXmlFile.error() != QFile::NoError)
  599. {
  600. anErrorMessage = aXmlFile.errorString();
  601. Message::SendFail() << "QFile opening error: " << anErrorMessage.toUtf8().constData();
  602. }
  603. aXmlFile.close();
  604. return;
  605. }
  606. bool aNamespaceProcessing(false);
  607. QString anErrorMsg;
  608. int anErrorLine(0);
  609. int anErrorColumn(0);
  610. if (!aDomDocument.setContent(&aXmlFile, aNamespaceProcessing, &anErrorMsg, &anErrorLine, &anErrorColumn))
  611. {
  612. Message::SendFail() << "XML file parsing error: " << anErrorMsg.toStdString()
  613. << " at line: " << anErrorLine << " column: " << anErrorColumn;
  614. aXmlFile.close();
  615. return;
  616. }
  617. aXmlFile.close();
  618. QDomElement aRootElement = aDomDocument.documentElement();
  619. QDomElement anItemElement = aRootElement.firstChildElement("MenuItem");
  620. while(!anItemElement.isNull())
  621. {
  622. theMunusList.push_back(MenuFromDomNode(anItemElement, this, theMapper));
  623. anItemElement = anItemElement.nextSiblingElement("MenuItem");
  624. }
  625. }
  1. // Copyright (c) 2020 OPEN CASCADE SAS
  2. //
  3. // This file is part of the examples of the Open CASCADE Technology software library.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
  21. #include "ApplicationCommon.h"
  22. #include <Standard_WarningsDisable.hxx>
  23. #include <QApplication>
  24. #include <QDir>
  25. #include <QFile>
  26. #include <QFont>
  27. #include <QFrame>
  28. #include <QGroupBox>
  29. #include <QMap>
  30. #include <QMdiArea>
  31. #include <QMdiSubWindow>
  32. #include <QMenuBar>
  33. #include <QMessageBox>
  34. #include <QPair>
  35. #include <QSplitter>
  36. #include <QStatusBar>
  37. #include <QtGlobal>
  38. #include <QHBoxLayout>
  39. #include <QVBoxLayout>
  40. #include <QWidget>
  41. #include <QDomDocument>
  42. #include <QDomAttr>
  43. #include <Standard_WarningsRestore.hxx>
  44. #include <OpenGl_GraphicDriver.hxx>
  45. #include <OSD_Environment.hxx>
  46. #include <stdlib.h>
  47. #include <memory>
  48. ApplicationCommonWindow::ApplicationCommonWindow (ApplicationType theCategory)
  49. : QMainWindow (nullptr),
  50. myAppType(theCategory),
  51. myStdToolBar (nullptr),
  52. myViewBar (nullptr),
  53. myCasCadeBar (nullptr),
  54. myFilePopup (nullptr),
  55. myCategoryPopup (nullptr)
  56. {
  57. ALL_CATEGORIES[AppType_Geometry] = "Geometry";
  58. ALL_CATEGORIES[AppType_Topology] = "Topology";
  59. ALL_CATEGORIES[AppType_Triangulation] = "Triangulation";
  60. ALL_CATEGORIES[AppType_DataExchange] = "DataExchange";
  61. ALL_CATEGORIES[AppType_Ocaf] = "OCAF";
  62. ALL_CATEGORIES[AppType_Viewer3d] = "3D viewer";
  63. ALL_CATEGORIES[AppType_Viewer2d] = "2D Viewer";
  64. ALL_CATEGORIES[AppType_PengKai] = "PengKai";
  65. mySampleMapper = new QSignalMapper(this);
  66. myExchangeMapper = new QSignalMapper(this);
  67. myOcafMapper = new QSignalMapper(this);
  68. myViewer3dMapper = new QSignalMapper(this);
  69. myViewer2dMapper = new QSignalMapper(this);
  70. myCategoryMapper = new QSignalMapper(this);
  71. connect(mySampleMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessSample(const QString &)));
  72. connect(myExchangeMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessExchange(const QString &)));
  73. connect(myOcafMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessOcaf(const QString &)));
  74. connect(myViewer3dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer3d(const QString &)));
  75. connect(myViewer2dMapper, SIGNAL(mapped(const QString &)), this, SLOT(onProcessViewer2d(const QString &)));
  76. connect(myCategoryMapper, SIGNAL(mapped(const QString &)), this, SLOT(onChangeCategory(const QString &)));
  77. setFocusPolicy(Qt::StrongFocus);
  78. QFont aCodeViewFont;
  79. aCodeViewFont.setFamily("Courier");
  80. aCodeViewFont.setFixedPitch(true);
  81. aCodeViewFont.setPointSize(10);
  82. QGroupBox* aCodeFrame = new QGroupBox(tr("Sample code"));
  83. QVBoxLayout* aCodeLayout = new QVBoxLayout(aCodeFrame);
  84. aCodeLayout->setContentsMargins(3, 3, 3, 3);
  85. myCodeView = new QTextEdit(aCodeFrame);
  86. aCodeLayout->addWidget(myCodeView);
  87. myCodeView->setDocumentTitle("Code");
  88. myCodeView->setLineWrapMode(QTextEdit::NoWrap);
  89. myCodeView->setReadOnly(true);
  90. myCodeView->setFont(aCodeViewFont);
  91. myCodeViewHighlighter = new OcctHighlighter(myCodeView->document());
  92. QGroupBox* aResultFrame = new QGroupBox(tr("Output"));
  93. QVBoxLayout* aResultLayout = new QVBoxLayout(aResultFrame);
  94. aResultLayout->setContentsMargins(3, 3, 3, 3);
  95. myResultView = new QTextEdit(aResultFrame);
  96. aResultLayout->addWidget(myResultView);
  97. myResultView->setDocumentTitle("Output");
  98. myResultView->setReadOnly(true);
  99. myResultView->setFont(aCodeViewFont);
  100. QSplitter* aCodeResultSplitter = new QSplitter(Qt::Vertical);
  101. aCodeResultSplitter->addWidget(aCodeFrame);
  102. aCodeResultSplitter->addWidget(aResultFrame);
  103. myDocument3d = createNewDocument();
  104. myDocument2d = createNewDocument();
  105. QFrame* aViewFrame = new QFrame;
  106. aViewFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
  107. aViewFrame->setLineWidth(3);
  108. QVBoxLayout* aViewLayout = new QVBoxLayout(aViewFrame);
  109. aViewLayout->setContentsMargins(0, 0, 0, 0);
  110. myGeomWidget = new GeomWidget(myDocument3d, myDocument2d, aViewFrame);
  111. aViewLayout->addWidget(myGeomWidget);
  112. myGeomWidget->setContentsMargins(0, 0, 0, 0);
  113. QSplitter* aGeomTextSplitter = new QSplitter(Qt::Horizontal);
  114. aGeomTextSplitter->addWidget(aViewFrame);
  115. aGeomTextSplitter->addWidget(aCodeResultSplitter);
  116. aGeomTextSplitter->setStretchFactor(0, 1);
  117. aGeomTextSplitter->setStretchFactor(1, 1);
  118. QList<int> aSizeList;
  119. aSizeList.append(640);
  120. aSizeList.append(640);
  121. aGeomTextSplitter->setSizes(aSizeList);
  122. setCentralWidget(aGeomTextSplitter);
  123. #include <Standard_WarningsDisable.hxx>
  124. Q_INIT_RESOURCE(Samples);
  125. #include <Standard_WarningsRestore.hxx>
  126. TCollection_AsciiString aSampleSourcePach = getSampleSourceDir();
  127. myGeometrySamples = new GeometrySamples(aSampleSourcePach,
  128. myDocument3d->getContext());
  129. myTopologySamples = new TopologySamples(aSampleSourcePach,
  130. myDocument3d->getContext());
  131. myTriangulationSamples = new TriangulationSamples(aSampleSourcePach,
  132. myDocument3d->getContext());
  133. myDataExchangeSamples = new DataExchangeSamples(aSampleSourcePach,
  134. myGeomWidget->Get3dView(),
  135. myDocument3d->getContext());
  136. myOcafSamples = new OcafSamples(aSampleSourcePach,
  137. myDocument3d->getViewer(),
  138. myDocument3d->getContext());
  139. myViewer3dSamples = new Viewer3dSamples(aSampleSourcePach,
  140. myGeomWidget->Get3dView(),
  141. myDocument3d->getContext());
  142. myViewer2dSamples = new Viewer2dSamples(aSampleSourcePach,
  143. myGeomWidget->Get2dView(),
  144. myDocument2d->getViewer(),
  145. myDocument2d->getContext());
  146. myPengKaiSamples = new PengKaiSamples(aSampleSourcePach,
  147. myDocument3d->getContext());
  148. MenuFormXml(":/menus/Geometry.xml", mySampleMapper, myGeometryMenus);
  149. MenuFormXml(":/menus/Topology.xml", mySampleMapper, myTopologyMenus);
  150. MenuFormXml(":/menus/Triangulation.xml", mySampleMapper, myTriangulationMenus);
  151. MenuFormXml(":/menus/DataExchange.xml", myExchangeMapper, myDataExchangeMenus);
  152. MenuFormXml(":/menus/Ocaf.xml", myOcafMapper, myOcafMenus);
  153. MenuFormXml(":/menus/Viewer3d.xml", myViewer3dMapper, myViewer3dMenus);
  154. MenuFormXml(":/menus/Viewer2d.xml", myViewer2dMapper, myViewer2dMenus);
  155. MenuFormXml(":/menus/PengKai.xml", mySampleMapper, myPengKaiMenus);
  156. onChangeCategory(ALL_CATEGORIES[myAppType]);
  157. resize(1280, 560);
  158. }
  159. void ApplicationCommonWindow::RebuildMenu()
  160. {
  161. menuBar()->clear();
  162. myStdActions[StdActions_FileQuit] = CreateAction("Quit", "CTRL+Q");
  163. connect(myStdActions[StdActions_FileQuit], SIGNAL(triggered()), this, SLOT(onCloseAllWindows()));
  164. myStdActions[StdActions_HelpAbout] = CreateAction("About", "F1", ":/icons/help.png");
  165. connect(myStdActions[StdActions_HelpAbout], SIGNAL(triggered()), this, SLOT(onAbout()));
  166. // populate a menu with all actions
  167. myFilePopup = new QMenu(this);
  168. myFilePopup = menuBar()->addMenu(tr("&File"));
  169. myFilePopup->addAction(myStdActions[StdActions_FileQuit]);
  170. myCategoryPopup = new QMenu(this);
  171. myCategoryPopup = menuBar()->addMenu(tr("&Category"));
  172. foreach (ApplicationType aCategory, ALL_CATEGORIES.keys())
  173. {
  174. QString aCategoryName = ALL_CATEGORIES.value(aCategory);
  175. QAction* anAction = myCategoryPopup->addAction(aCategoryName);
  176. anAction->setText(aCategoryName);
  177. myCategoryMapper->setMapping(anAction, aCategoryName);
  178. connect(anAction, SIGNAL(triggered()), myCategoryMapper, SLOT(map()));
  179. myCategoryPopup->addAction(anAction);
  180. myCategoryActions.insert(aCategory, anAction);
  181. }
  182. foreach (QMenu* aSampleMenu, GetCurrentMenus())
  183. {
  184. menuBar()->addMenu(aSampleMenu);
  185. }
  186. // add a help menu
  187. QMenu* aHelp = new QMenu(this);
  188. menuBar()->addSeparator();
  189. aHelp = menuBar()->addMenu(tr("&Help"));
  190. aHelp->addAction(myStdActions[StdActions_HelpAbout]);
  191. }
  192. Handle(BaseSample) ApplicationCommonWindow::GetCurrentSamples()
  193. {
  194. switch (myAppType)
  195. {
  196. case AppType_Geometry: return myGeometrySamples;
  197. case AppType_Topology: return myTopologySamples;
  198. case AppType_Triangulation: return myTriangulationSamples;
  199. case AppType_DataExchange: return myDataExchangeSamples;
  200. case AppType_Ocaf: return myOcafSamples;
  201. case AppType_Viewer2d: return myViewer2dSamples;
  202. case AppType_Viewer3d: return myViewer3dSamples;
  203. case AppType_PengKai: return myPengKaiSamples;
  204. case AppType_Unknown:
  205. break;
  206. }
  207. throw QString("Unknown Application type");
  208. }
  209. const QList<QMenu*>& ApplicationCommonWindow::GetCurrentMenus()
  210. {
  211. switch (myAppType)
  212. {
  213. case AppType_Geometry: return myGeometryMenus;
  214. case AppType_Topology: return myTopologyMenus;
  215. case AppType_Triangulation: return myTriangulationMenus;
  216. case AppType_DataExchange: return myDataExchangeMenus;
  217. case AppType_Ocaf: return myOcafMenus;
  218. case AppType_Viewer2d: return myViewer2dMenus;
  219. case AppType_Viewer3d: return myViewer3dMenus;
  220. case AppType_PengKai: return myPengKaiMenus;
  221. case AppType_Unknown:
  222. break;
  223. }
  224. throw QString("Unknown Application type");
  225. }
  226. DocumentCommon* ApplicationCommonWindow::createNewDocument()
  227. {
  228. return new DocumentCommon(this);
  229. }
  230. void ApplicationCommonWindow::onChangeCategory(const QString& theCategory)
  231. {
  232. myAppType = ALL_CATEGORIES.key(theCategory);
  233. setWindowTitle(ALL_CATEGORIES[myAppType]);
  234. myOcafSamples->ClearExtra();
  235. myViewer3dSamples->ClearExtra();
  236. myViewer2dSamples->ClearExtra();
  237. GetCurrentSamples()->Clear();
  238. myDocument3d->Clear();
  239. myDocument2d->Clear();
  240. myCodeView->setPlainText("");
  241. myResultView->setPlainText("");
  242. GetCurrentSamples()->AppendCube();
  243. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  244. myGeomWidget->FitAll();
  245. RebuildMenu();
  246. switch (myAppType)
  247. {
  248. case AppType_DataExchange:
  249. {
  250. myDataExchangeSamples->AppendBottle();
  251. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  252. myGeomWidget->Show3d();
  253. break;
  254. }
  255. case AppType_Ocaf:
  256. {
  257. onProcessOcaf("CreateOcafDocument");
  258. myGeomWidget->Show3d();
  259. break;
  260. }
  261. case AppType_Viewer2d:
  262. {
  263. myGeomWidget->Show2d();
  264. break;
  265. }
  266. case AppType_Viewer3d:
  267. {
  268. myViewer3dSamples->AppendBottle();
  269. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  270. myGeomWidget->Show3d();
  271. break;
  272. }
  273. case AppType_Geometry:
  274. case AppType_Topology:
  275. case AppType_PengKai:
  276. case AppType_Triangulation:
  277. case AppType_Unknown:
  278. {
  279. break;
  280. }
  281. }
  282. }
  283. void ApplicationCommonWindow::onAbout()
  284. {
  285. QMessageBox::information(this, tr("OCCT Overview"),
  286. tr("Qt based application to study OpenCASCADE Technology"),
  287. tr("Ok"), QString::null, QString::null, 0, 0);
  288. }
  289. TCollection_AsciiString ApplicationCommonWindow::getSampleSourceDir()
  290. {
  291. TCollection_AsciiString aSampleSourceDir = OSD_Environment("CSF_OCCTOverviewSampleCodePath").Value();
  292. if (aSampleSourceDir.IsEmpty())
  293. {
  294. TCollection_AsciiString aCasRoot = OSD_Environment("CASROOT").Value();
  295. if (!aCasRoot.IsEmpty())
  296. {
  297. aSampleSourceDir = aCasRoot + "/samples/OCCTOverview/code";
  298. }
  299. }
  300. return aSampleSourceDir;
  301. }
  302. QAction* ApplicationCommonWindow::CreateAction (const QString& theActionName,
  303. const QString& theShortcut,
  304. const QString& theIconName)
  305. {
  306. QAction* aAction(NULL);
  307. if (theIconName.isEmpty())
  308. {
  309. aAction = new QAction(theActionName, this);
  310. }
  311. else
  312. {
  313. QPixmap aIcon = QPixmap(theIconName);
  314. aAction = new QAction(aIcon, theActionName, this);
  315. }
  316. aAction->setToolTip(theActionName);
  317. aAction->setStatusTip(theActionName);
  318. aAction->setShortcut(theShortcut);
  319. return aAction;
  320. }
  321. template <typename PointerToMemberFunction>
  322. QAction* ApplicationCommonWindow::CreateSample (PointerToMemberFunction theHandlerMethod,
  323. const char* theActionName)
  324. {
  325. QAction* anAction = new QAction(QObject::tr(theActionName), this);
  326. connect(anAction, SIGNAL(triggered()), this, SLOT(theHandlerMethod()));
  327. return anAction;
  328. }
  329. void ApplicationCommonWindow::resizeEvent(QResizeEvent* e)
  330. {
  331. QMainWindow::resizeEvent(e);
  332. statusBar()->setSizeGripEnabled(!isMaximized());
  333. }
  334. void ApplicationCommonWindow::onProcessSample(const QString& theSampleName)
  335. {
  336. QApplication::setOverrideCursor(Qt::WaitCursor);
  337. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  338. GetCurrentSamples()->Process(theSampleName.toUtf8().data());
  339. myDocument3d->SetObjects(GetCurrentSamples()->Get3dObjects());
  340. myDocument2d->SetObjects(GetCurrentSamples()->Get2dObjects());
  341. myCodeView->setPlainText(GetCurrentSamples()->GetCode().ToCString());
  342. myResultView->setPlainText(GetCurrentSamples()->GetResult().ToCString());
  343. myGeomWidget->FitAll();
  344. QApplication::restoreOverrideCursor();
  345. }
  346. void ApplicationCommonWindow::onProcessExchange(const QString& theSampleName)
  347. {
  348. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  349. int aMode = 0;
  350. QString aFileName = selectFileName(theSampleName, getDataExchangeDialog(theSampleName), aMode);
  351. if (aFileName.isEmpty())
  352. {
  353. return;
  354. }
  355. QApplication::setOverrideCursor(Qt::WaitCursor);
  356. myDataExchangeSamples->SetFileName(aFileName.toUtf8().data());
  357. myDataExchangeSamples->SetStepType(static_cast<STEPControl_StepModelType>(aMode));
  358. myDataExchangeSamples->Process(theSampleName.toUtf8().data());
  359. myDocument3d->SetObjects(myDataExchangeSamples->Get3dObjects());
  360. myDocument2d->SetObjects(myDataExchangeSamples->Get2dObjects());
  361. myCodeView->setPlainText(myDataExchangeSamples->GetCode().ToCString());
  362. myResultView->setPlainText(myDataExchangeSamples->GetResult().ToCString());
  363. myGeomWidget->FitAll();
  364. QApplication::restoreOverrideCursor();
  365. }
  366. void ApplicationCommonWindow::onProcessOcaf(const QString& theSampleName)
  367. {
  368. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  369. if (theSampleName.indexOf("Dialog") == 0)
  370. {
  371. int aMode = 0; // not used
  372. QString aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);
  373. if (aFileName.isEmpty())
  374. {
  375. return;
  376. }
  377. myOcafSamples->SetFileName(aFileName.toUtf8().data());
  378. }
  379. QApplication::setOverrideCursor(Qt::WaitCursor);
  380. myOcafSamples->Process(theSampleName.toUtf8().data());
  381. myDocument2d->SetObjects(myOcafSamples->Get2dObjects());
  382. myCodeView->setPlainText(myOcafSamples->GetCode().ToCString());
  383. myResultView->setPlainText(myOcafSamples->GetResult().ToCString());
  384. QApplication::restoreOverrideCursor();
  385. }
  386. void ApplicationCommonWindow::onProcessViewer3d(const QString& theSampleName)
  387. {
  388. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  389. QApplication::setOverrideCursor(Qt::WaitCursor);
  390. myViewer3dSamples->Process(theSampleName.toUtf8().data());
  391. myCodeView->setPlainText(myViewer3dSamples->GetCode().ToCString());
  392. myResultView->setPlainText(myViewer3dSamples->GetResult().ToCString());
  393. myGeomWidget->FitAll();
  394. QApplication::restoreOverrideCursor();
  395. }
  396. void ApplicationCommonWindow::onProcessViewer2d(const QString& theSampleName)
  397. {
  398. setWindowTitle(ALL_CATEGORIES[myAppType] + " - " + theSampleName);
  399. Standard_Boolean anIsFileSample = Viewer2dSamples::IsFileSample(theSampleName.toUtf8().data());
  400. QString aFileName;
  401. if (anIsFileSample)
  402. {
  403. int aMode = 0; // not used
  404. aFileName = selectFileName(theSampleName, getOcafDialog(theSampleName), aMode);
  405. if (aFileName.isEmpty())
  406. {
  407. return;
  408. }
  409. myViewer2dSamples->SetFileName(aFileName.toUtf8().data());
  410. }
  411. if (!anIsFileSample || (anIsFileSample && !aFileName.isEmpty()))
  412. {
  413. QApplication::setOverrideCursor(Qt::WaitCursor);
  414. myViewer2dSamples->Process(theSampleName.toUtf8().data());
  415. if (!Viewer2dSamples::IsShadedSample(theSampleName.toUtf8().data()))
  416. {
  417. myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_False);
  418. }
  419. else
  420. {
  421. myDocument2d->SetObjects(myViewer2dSamples->Get2dObjects(), Standard_True);
  422. }
  423. myCodeView->setPlainText(myViewer2dSamples->GetCode().ToCString());
  424. myResultView->setPlainText(myViewer2dSamples->GetResult().ToCString());
  425. myGeomWidget->Show2d();
  426. QApplication::restoreOverrideCursor();
  427. }
  428. else
  429. {
  430. myResultView->setPlainText("No file selected!");
  431. }
  432. }
  433. QString ApplicationCommonWindow::selectFileName(const QString& theSampleName,
  434. TranslateDialog* theDialog, int& theMode)
  435. {
  436. Q_UNUSED(theSampleName)
  437. std::shared_ptr<TranslateDialog> aDialog(theDialog);
  438. int ret = aDialog->exec();
  439. theMode = aDialog->getMode();
  440. qApp->processEvents();
  441. QString aFilename;
  442. QStringList aFileNameList;
  443. if (ret != QDialog::Accepted)
  444. {
  445. return aFilename;
  446. }
  447. aFileNameList = aDialog->selectedFiles();
  448. if (!aFileNameList.isEmpty())
  449. {
  450. aFilename = aFileNameList[0];
  451. }
  452. if (!QFileInfo(aFilename).completeSuffix().length())
  453. {
  454. QString selFilter = aDialog->selectedNameFilter();
  455. int idx = selFilter.indexOf("(*.");
  456. if (idx != -1)
  457. {
  458. QString tail = selFilter.mid(idx + 3);
  459. idx = tail.indexOf(" ");
  460. if (idx == -1)
  461. {
  462. idx = tail.indexOf(")");
  463. }
  464. QString ext = tail.left(idx);
  465. if (ext.length())
  466. {
  467. aFilename += QString(".") + ext;
  468. }
  469. }
  470. }
  471. return aFilename;
  472. }
  473. TranslateDialog* ApplicationCommonWindow::getDataExchangeDialog(const QString& theSampleName)
  474. {
  475. TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);
  476. TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());
  477. if (DataExchangeSamples::IsExportSample(aSampleName))
  478. {
  479. aTranslateDialog->setWindowTitle("Export file");
  480. aTranslateDialog->setFileMode(QFileDialog::AnyFile);
  481. aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);
  482. }
  483. else if (DataExchangeSamples::IsImportSample(aSampleName))
  484. {
  485. aTranslateDialog->setWindowTitle("Import file");
  486. aTranslateDialog->setFileMode(QFileDialog::ExistingFile);
  487. aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);
  488. }
  489. QString aFormatFilter;
  490. if (DataExchangeSamples::IsBrepSample(aSampleName))
  491. {
  492. aFormatFilter = "BREP Files(*.brep *.rle)";
  493. }
  494. else if (DataExchangeSamples::IsStepSample(aSampleName))
  495. {
  496. aFormatFilter = "STEP Files (*.stp *.step)";
  497. aTranslateDialog->addMode(STEPControl_ManifoldSolidBrep, "Manifold Solid Brep");
  498. aTranslateDialog->addMode(STEPControl_FacetedBrep, "Faceted Brep");
  499. aTranslateDialog->addMode(STEPControl_ShellBasedSurfaceModel, "Shell Based Surface Model");
  500. aTranslateDialog->addMode(STEPControl_GeometricCurveSet, "Geometric Curve Set");
  501. }
  502. else if (DataExchangeSamples::IsIgesSample(aSampleName))
  503. {
  504. aFormatFilter = "IGES Files (*.igs *.iges)";
  505. }
  506. else if (DataExchangeSamples::IsStlSample(aSampleName))
  507. {
  508. aFormatFilter = "STL Files (*.stl)";
  509. }
  510. else if (DataExchangeSamples::IsVrmlSample(aSampleName))
  511. {
  512. aFormatFilter = "VRML Files (*.vrml)";
  513. }
  514. else if (DataExchangeSamples::IsImageSample(aSampleName))
  515. {
  516. aFormatFilter = "All Image Files (*.bmp *.gif *.jpg *.jpeg *.png *.tga)";
  517. }
  518. QStringList aFilters;
  519. aFilters.append(aFormatFilter);
  520. aFilters.append("All Files(*.*)");
  521. aTranslateDialog->setNameFilters(aFilters);
  522. aTranslateDialog->clear();
  523. return aTranslateDialog;
  524. }
  525. TranslateDialog* ApplicationCommonWindow::getOcafDialog(const QString& theSampleName)
  526. {
  527. TranslateDialog* aTranslateDialog = new TranslateDialog(this, 0, true);
  528. TCollection_AsciiString aSampleName(theSampleName.toUtf8().data());
  529. if (OcafSamples::IsExportSample(aSampleName))
  530. {
  531. aTranslateDialog->setWindowTitle("Export file");
  532. aTranslateDialog->setFileMode(QFileDialog::AnyFile);
  533. aTranslateDialog->setAcceptMode(QFileDialog::AcceptSave);
  534. }
  535. else if (OcafSamples::IsImportSample(aSampleName))
  536. {
  537. aTranslateDialog->setWindowTitle("Import file");
  538. aTranslateDialog->setFileMode(QFileDialog::ExistingFile);
  539. aTranslateDialog->setAcceptMode(QFileDialog::AcceptOpen);
  540. }
  541. QStringList aFilters;
  542. if (OcafSamples::IsBinarySample(aSampleName))
  543. {
  544. aFilters.append("Binary OCAF Sample (*.cbf)");
  545. }
  546. if (OcafSamples::IsXmlSample(aSampleName))
  547. {
  548. aFilters.append("XML OCAF Sample (*.xml)");
  549. }
  550. aFilters.append("All Files(*.*)");
  551. aTranslateDialog->setNameFilters(aFilters);
  552. aTranslateDialog->clear();
  553. return aTranslateDialog;
  554. }
  555. QMenu* ApplicationCommonWindow::MenuFromDomNode(QDomElement& theItemElement,
  556. QWidget* theParent,
  557. QSignalMapper* theMapper)
  558. {
  559. QString anItemName = theItemElement.attribute("name");
  560. QMenu* aMenu = new QMenu(anItemName, theParent);
  561. QDomElement anChildItemElement = theItemElement.firstChildElement("MenuItem");
  562. QDomElement anSampleElement = theItemElement.firstChildElement("Sample");
  563. while(anChildItemElement.isElement())
  564. {
  565. aMenu->addMenu(MenuFromDomNode(anChildItemElement, aMenu, theMapper));
  566. anChildItemElement = anChildItemElement.nextSibling().toElement();
  567. }
  568. while(anSampleElement.isElement())
  569. {
  570. QString aSampleName = anSampleElement.attribute("name");
  571. QString aSampleFunction = anSampleElement.attribute("function");
  572. QAction* anAction = aMenu->addAction(aSampleFunction);
  573. anAction->setText(aSampleName);
  574. theMapper->setMapping(anAction, aSampleFunction);
  575. connect(anAction, SIGNAL(triggered()), theMapper, SLOT(map()));
  576. anSampleElement = anSampleElement.nextSibling().toElement();
  577. }
  578. return aMenu;
  579. }
  580. void ApplicationCommonWindow::MenuFormXml(const QString& thePath,
  581. QSignalMapper* theMapper,
  582. QList<QMenu*>& theMunusList)
  583. {
  584. QDomDocument aDomDocument;
  585. theMunusList.clear();
  586. QFile aXmlFile(thePath);
  587. QString anErrorMessage;
  588. if (aXmlFile.error() != QFile::NoError)
  589. {
  590. anErrorMessage = aXmlFile.errorString();
  591. Message::SendFail() << "QFile creating error: " << anErrorMessage.toUtf8().constData();
  592. aXmlFile.close();
  593. return;
  594. }
  595. if (!aXmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
  596. {
  597. Message::SendFail() << "File " << thePath.toUtf8().constData() << " could not open";
  598. if (aXmlFile.error() != QFile::NoError)
  599. {
  600. anErrorMessage = aXmlFile.errorString();
  601. Message::SendFail() << "QFile opening error: " << anErrorMessage.toUtf8().constData();
  602. }
  603. aXmlFile.close();
  604. return;
  605. }
  606. bool aNamespaceProcessing(false);
  607. QString anErrorMsg;
  608. int anErrorLine(0);
  609. int anErrorColumn(0);
  610. if (!aDomDocument.setContent(&aXmlFile, aNamespaceProcessing, &anErrorMsg, &anErrorLine, &anErrorColumn))
  611. {
  612. Message::SendFail() << "XML file parsing error: " << anErrorMsg.toStdString()
  613. << " at line: " << anErrorLine << " column: " << anErrorColumn;
  614. aXmlFile.close();
  615. return;
  616. }
  617. aXmlFile.close();
  618. QDomElement aRootElement = aDomDocument.documentElement();
  619. QDomElement anItemElement = aRootElement.firstChildElement("MenuItem");
  620. while(!anItemElement.isNull())
  621. {
  622. theMunusList.push_back(MenuFromDomNode(anItemElement, this, theMapper));
  623. anItemElement = anItemElement.nextSiblingElement("MenuItem");
  624. }
  625. }

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

5、总结

注意好以下几个关键点:

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/908156
推荐阅读
相关标签
  

闽ICP备14008679号