当前位置: 代码网 > it编程>编程语言>C/C++ > 【全网最完整】Open CASCADE Technology (OCCT) 构建项目,QT可视化操作,添加自定义测试内容

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

2024年07月28日 C/C++ 我要评论
步骤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 路径下。步骤2:鼠标右击OCCTOverview,依次找到属性、Debugging、environment,将以下内容粘贴进去,这是配置项目环境变量的。步骤5:在3RDPARTY_DIR这一行,填入第三方库文件的路径,也就是product的路径。

前言

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

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不同的地方即可,按照对应位置改就行。这里我附上我的源码。

#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文件来写

<menu>
  <menuitem name="pengkai">
    <menuitem name="pengkai test">
      <sample name="firsttest" function="firsttest"/>
    </menuitem>
  </menuitem>
</menu>

第三处修改:

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

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的地方全部换成自己修改的名字。

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

// 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、一般而言配置完以后运行成功就行,自定义测试需要修改的地方较多,不易操作

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com