Files
create/src/Mod/Sandbox/Gui/Command.cpp
2015-07-07 17:43:23 +02:00

1440 lines
47 KiB
C++

/***************************************************************************
* Copyright (c) 2009 Werner Mayer <wmayer@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# ifdef FC_OS_WIN32
# include <windows.h>
# endif
# include <QApplication>
# include <QCalendarWidget>
# include <QColorDialog>
# include <QCryptographicHash>
# include <QObject>
# include <QEventLoop>
# include <QFontMetrics>
# include <QFuture>
# include <QFutureWatcher>
# include <QtConcurrentMap>
# include <QLabel>
# include <QInputDialog>
# include <QMessageBox>
# include <QTimer>
# include <QImage>
# include <QImageReader>
# include <QPainter>
# include <QThread>
# include <Inventor/nodes/SoAnnotation.h>
# include <Inventor/nodes/SoImage.h>
# include <Inventor/nodes/SoCone.h>
# include <cmath>
# include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp>
# include <boost/thread/condition_variable.hpp>
# if BOOST_VERSION >= 104100
# include <boost/thread/future.hpp>
# endif
# include <boost/bind.hpp>
# include <boost/shared_ptr.hpp>
#endif
#include <Base/Console.h>
#include <Base/Sequencer.h>
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/MainWindow.h>
#include <Gui/FileDialog.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/WaitCursor.h>
#include <Mod/Sandbox/App/DocumentThread.h>
#include <Mod/Sandbox/App/DocumentProtector.h>
#include <Mod/Mesh/App/MeshFeature.h>
#include <Mod/Mesh/App/Core/Degeneration.h>
#include "Workbench.h"
#include "GLGraphicsView.h"
#include "TaskPanelView.h"
DEF_STD_CMD(CmdSandboxDocumentThread);
CmdSandboxDocumentThread::CmdSandboxDocumentThread()
:Command("Sandbox_Thread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Run several threads");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool1";
}
void CmdSandboxDocumentThread::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
for (int i=0; i<5; i++) {
Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
dt->setObjectName(QString::fromAscii("MyMesh_%1").arg(i));
QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
dt->start();
}
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxDocumentTestThread);
CmdSandboxDocumentTestThread::CmdSandboxDocumentTestThread()
:Command("Sandbox_TestThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Test thread");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool1";
}
void CmdSandboxDocumentTestThread::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
Sandbox::DocumentTestThread* dt = new Sandbox::DocumentTestThread();
QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
dt->start();
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxDocThreadWithSeq);
CmdSandboxDocThreadWithSeq::CmdSandboxDocThreadWithSeq()
:Command("Sandbox_SeqThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Thread and sequencer");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool2";
}
void CmdSandboxDocThreadWithSeq::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
dt->setObjectName(QString::fromAscii("MyMesh"));
QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
dt->start();
#ifdef FC_DEBUG
int max = 10000;
#else
int max = 100000000;
#endif
Base::SequencerLauncher seq("Do something meaningful...", max);
double val=0;
for (int i=0; i<max; i++) {
for (int j=0; j<max; j++) {
val = sin(0.12345);
}
seq.next(true);
}
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxDocThreadBusy);
CmdSandboxDocThreadBusy::CmdSandboxDocThreadBusy()
:Command("Sandbox_BlockThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Thread and no sequencer");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool3";
}
void CmdSandboxDocThreadBusy::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
dt->setObjectName(QString::fromAscii("MyMesh"));
QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
dt->start();
#ifdef FC_DEBUG
int max = 10000;
#else
int max = 100000000;
#endif
double val=0;
for (int i=0; i<max; i++) {
for (int j=0; j<max; j++) {
val = sin(0.12345);
}
}
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxDocumentNoThread);
CmdSandboxDocumentNoThread::CmdSandboxDocumentNoThread()
:Command("Sandbox_NoThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("GUI thread");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool4";
}
void CmdSandboxDocumentNoThread::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
App::Document* doc = App::GetApplication().getActiveDocument();
Sandbox::DocumentProtector dp(doc);
App::DocumentObject* obj = dp.addObject("Mesh::Cube", "MyCube");
dp.recompute();
App::GetApplication().closeDocument("Thread");
// this forces an exception
App::DocumentObject* obj2 = dp.addObject("Mesh::Cube", "MyCube");
dp.recompute();
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxWorkerThread);
CmdSandboxWorkerThread::CmdSandboxWorkerThread()
:Command("Sandbox_WorkerThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Worker thread");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool1";
}
void CmdSandboxWorkerThread::activated(int iMsg)
{
Sandbox::WorkerThread* wt = new Sandbox::WorkerThread();
QObject::connect(wt, SIGNAL(finished()), wt, SLOT(deleteLater()));
wt->start();
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxPythonLockThread);
CmdSandboxPythonLockThread::CmdSandboxPythonLockThread()
:Command("Sandbox_PythonLockThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Locked Python threads");
sToolTipText = QT_TR_NOOP("Use Python's thread module where each thread is locked");
sWhatsThis = QT_TR_NOOP("Use Python's thread module where each thread is locked");
sStatusTip = QT_TR_NOOP("Use Python's thread module where each thread is locked");
}
void CmdSandboxPythonLockThread::activated(int iMsg)
{
doCommand(Doc,
"import thread, time, Sandbox\n"
"def adder(doc):\n"
" lock.acquire()\n"
" dp=Sandbox.DocumentProtector(doc)\n"
" dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
" dp.recompute()\n"
" lock.release()\n"
"\n"
"lock=thread.allocate_lock()\n"
"doc=App.newDocument()\n"
"for i in range(2):\n"
" thread.start_new(adder,(doc,))\n"
"\n"
"time.sleep(1)\n"
);
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxPythonNolockThread);
CmdSandboxPythonNolockThread::CmdSandboxPythonNolockThread()
:Command("Sandbox_NolockPython")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Unlocked Python threads");
sToolTipText = QT_TR_NOOP("Use Python's thread module where each thread is unlocked");
sWhatsThis = QT_TR_NOOP("Use Python's thread module where each thread is unlocked");
sStatusTip = QT_TR_NOOP("Use Python's thread module where each thread is unlocked");
}
void CmdSandboxPythonNolockThread::activated(int iMsg)
{
doCommand(Doc,
"import thread, time, Sandbox\n"
"def adder(doc):\n"
" dp=Sandbox.DocumentProtector(doc)\n"
" dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
" dp.recompute()\n"
"\n"
"doc=App.newDocument()\n"
"for i in range(2):\n"
" thread.start_new(adder,(doc,))\n"
"\n"
"time.sleep(1)\n"
);
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxPyQtThread);
CmdSandboxPyQtThread::CmdSandboxPyQtThread()
:Command("Sandbox_PyQtThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("PyQt threads");
sToolTipText = QT_TR_NOOP("Use PyQt's thread module");
sWhatsThis = QT_TR_NOOP("Use PyQt's thread module");
sStatusTip = QT_TR_NOOP("Use PyQt's thread module");
}
void CmdSandboxPyQtThread::activated(int iMsg)
{
doCommand(Doc,
"from PyQt4 import QtCore; import Sandbox\n"
"class Thread(QtCore.QThread):\n"
" def run(self):\n"
" dp=Sandbox.DocumentProtector(doc)\n"
" dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
" dp.recompute()\n"
"\n"
"doc=App.newDocument()\n"
"threads=[]\n"
"for i in range(2):\n"
" thread=Thread()\n"
" threads.append(thread)\n"
" thread.start()\n"
"\n"
);
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxPythonThread);
CmdSandboxPythonThread::CmdSandboxPythonThread()
:Command("Sandbox_PythonThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Python threads");
sToolTipText = QT_TR_NOOP("Use class PythonThread running Python code in its run() method");
sWhatsThis = QT_TR_NOOP("Use class PythonThread running Python code in its run() method");
sStatusTip = QT_TR_NOOP("Use class PythonThread running Python code in its run() method");
}
void CmdSandboxPythonThread::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
for (int i=0; i<5; i++) {
Sandbox::PythonThread* pt = new Sandbox::PythonThread();
pt->setObjectName(QString::fromAscii("MyMesh_%1").arg(i));
QObject::connect(pt, SIGNAL(finished()), pt, SLOT(deleteLater()));
pt->start();
}
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxPythonMainThread);
CmdSandboxPythonMainThread::CmdSandboxPythonMainThread()
:Command("Sandbox_PythonMainThread")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Python main thread");
sToolTipText = QT_TR_NOOP("Run python code in main thread");
sWhatsThis = QT_TR_NOOP("Run python code in main thread");
sStatusTip = QT_TR_NOOP("Run python code in main thread");
}
void CmdSandboxPythonMainThread::activated(int iMsg)
{
doCommand(Doc,
"import Sandbox\n"
"doc=App.newDocument()\n"
"dp=Sandbox.DocumentProtector(doc)\n"
"dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
"dp.recompute()\n"
);
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxDocThreadWithDialog);
CmdSandboxDocThreadWithDialog::CmdSandboxDocThreadWithDialog()
:Command("Sandbox_Dialog")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Thread and modal dialog");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool7";
}
void CmdSandboxDocThreadWithDialog::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
dt->setObjectName(QString::fromAscii("MyMesh"));
QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
dt->start();
//QFileDialog::getOpenFileName();
QColorDialog::getColor(Qt::white,Gui::getMainWindow());
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdSandboxDocThreadWithFileDlg);
CmdSandboxDocThreadWithFileDlg::CmdSandboxDocThreadWithFileDlg()
:Command("Sandbox_FileDialog")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Thread and file dialog");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool7";
}
void CmdSandboxDocThreadWithFileDlg::activated(int iMsg)
{
App::GetApplication().newDocument("Thread");
Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
dt->setObjectName(QString::fromAscii("MyMesh"));
QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
dt->start();
QFileDialog::getOpenFileName();
}
// -------------------------------------------------------------------------------
class CmdSandboxEventLoop : public Gui::Command
{
public:
CmdSandboxEventLoop();
const char* className() const
{ return "CmdSandboxEventLoop"; }
protected:
void activated(int iMsg);
bool isActive(void);
private:
QEventLoop loop;
};
CmdSandboxEventLoop::CmdSandboxEventLoop()
:Command("Sandbox_EventLoop")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Local event loop");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool6";
}
void CmdSandboxEventLoop::activated(int iMsg)
{
QTimer timer;
timer.setSingleShot(true);
QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
timer.start(5000); // 5s timeout
loop.exec();
Base::Console().Message("CmdSandboxEventLoop: timeout\n");
}
bool CmdSandboxEventLoop::isActive(void)
{
return (!loop.isRunning());
}
// -------------------------------------------------------------------------------
class CmdSandboxMeshLoader : public Gui::Command
{
public:
CmdSandboxMeshLoader();
const char* className() const
{ return "CmdSandboxMeshLoader"; }
protected:
void activated(int iMsg);
bool isActive(void);
private:
QEventLoop loop;
};
CmdSandboxMeshLoader::CmdSandboxMeshLoader()
:Command("Sandbox_MeshLoad")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Load mesh in thread");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool6";
}
void CmdSandboxMeshLoader::activated(int iMsg)
{
// use current path as default
QStringList filter;
filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)");
filter << QObject::tr("Binary STL (*.stl)");
filter << QObject::tr("ASCII STL (*.ast)");
filter << QObject::tr("Binary Mesh (*.bms)");
filter << QObject::tr("Alias Mesh (*.obj)");
filter << QObject::tr("Inventor V2.1 ascii (*.iv)");
//filter << "Nastran (*.nas *.bdf)";
filter << QObject::tr("All Files (*.*)");
// Allow multi selection
QString fn = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(),
QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;")));
Sandbox::MeshLoaderThread thread(fn);
QObject::connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
thread.start();
loop.exec();
Base::Reference<Mesh::MeshObject> data = thread.getMesh();
App::Document* doc = App::GetApplication().getActiveDocument();
Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh"));
mesh->Mesh.setValuePtr((Mesh::MeshObject*)data);
mesh->purgeTouched();
}
bool CmdSandboxMeshLoader::isActive(void)
{
return (hasActiveDocument() && !loop.isRunning());
}
// -------------------------------------------------------------------------------
Base::Reference<Mesh::MeshObject> loadMesh(const QString& s)
{
Mesh::MeshObject* mesh = new Mesh::MeshObject();
mesh->load((const char*)s.toUtf8());
return mesh;
}
DEF_STD_CMD_A(CmdSandboxMeshLoaderBoost)
CmdSandboxMeshLoaderBoost::CmdSandboxMeshLoaderBoost()
:Command("Sandbox_MeshLoaderBoost")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Load mesh in boost-thread");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool6";
}
void CmdSandboxMeshLoaderBoost::activated(int iMsg)
{
# if BOOST_VERSION >= 104100
// use current path as default
QStringList filter;
filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)");
filter << QObject::tr("Binary STL (*.stl)");
filter << QObject::tr("ASCII STL (*.ast)");
filter << QObject::tr("Binary Mesh (*.bms)");
filter << QObject::tr("Alias Mesh (*.obj)");
filter << QObject::tr("Inventor V2.1 ascii (*.iv)");
//filter << "Nastran (*.nas *.bdf)";
filter << QObject::tr("All Files (*.*)");
// Allow multi selection
QString fn = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(),
QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;")));
boost::packaged_task< Base::Reference<Mesh::MeshObject> > pt
(boost::bind(&loadMesh, fn));
boost::unique_future< Base::Reference<Mesh::MeshObject> > fi=pt.get_future();
boost::thread task(boost::move(pt)); // launch task on a thread
fi.wait(); // wait for it to be finished
App::Document* doc = App::GetApplication().getActiveDocument();
Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh"));
mesh->Mesh.setValuePtr((Mesh::MeshObject*)fi.get());
mesh->purgeTouched();
#endif
}
bool CmdSandboxMeshLoaderBoost::isActive(void)
{
# if BOOST_VERSION >= 104100
return hasActiveDocument();
#else
return false;
#endif
}
DEF_STD_CMD_A(CmdSandboxMeshLoaderFuture)
CmdSandboxMeshLoaderFuture::CmdSandboxMeshLoaderFuture()
:Command("Sandbox_MeshLoaderFuture")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Load mesh in QFuture");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool6";
}
void CmdSandboxMeshLoaderFuture::activated(int iMsg)
{
// use current path as default
QStringList filter;
filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)");
filter << QObject::tr("Binary STL (*.stl)");
filter << QObject::tr("ASCII STL (*.ast)");
filter << QObject::tr("Binary Mesh (*.bms)");
filter << QObject::tr("Alias Mesh (*.obj)");
filter << QObject::tr("Inventor V2.1 ascii (*.iv)");
//filter << "Nastran (*.nas *.bdf)";
filter << QObject::tr("All Files (*.*)");
// Allow multi selection
QStringList fn = Gui::FileDialog::getOpenFileNames(Gui::getMainWindow(),
QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;")));
QFuture< Base::Reference<Mesh::MeshObject> > future = QtConcurrent::mapped
(fn, loadMesh);
QFutureWatcher< Base::Reference<Mesh::MeshObject> > watcher;
watcher.setFuture(future);
// keep it responsive during computation
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
App::Document* doc = App::GetApplication().getActiveDocument();
for (QFuture< Base::Reference<Mesh::MeshObject> >::const_iterator it = future.begin(); it != future.end(); ++it) {
Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh"));
mesh->Mesh.setValuePtr((Mesh::MeshObject*)(*it));
mesh->purgeTouched();
}
}
bool CmdSandboxMeshLoaderFuture::isActive(void)
{
return hasActiveDocument();
}
namespace Mesh {
typedef Base::Reference<const MeshObject> MeshObjectConstRef;
typedef std::list<MeshObjectConstRef> MeshObjectConstRefList;
typedef std::vector<MeshObjectConstRef> MeshObjectConstRefArray;
}
struct MeshObject_greater : public std::binary_function<const Mesh::MeshObjectConstRef&,
const Mesh::MeshObjectConstRef&, bool>
{
bool operator()(const Mesh::MeshObjectConstRef& x,
const Mesh::MeshObjectConstRef& y) const
{
return x->countFacets() > y->countFacets();
}
};
class MeshTestJob
{
public:
MeshTestJob()
{
}
~MeshTestJob()
{
}
Mesh::MeshObject* run(const std::vector<Mesh::MeshObjectConstRef>& meshdata)
{
std::vector<Mesh::MeshObjectConstRef> meshes = meshdata;
if (meshes.empty())
return 0; // nothing todo
Mesh::MeshObjectConstRef myMesh = 0;
std::sort(meshes.begin(), meshes.end(), MeshObject_greater());
myMesh = meshes.front();
if (meshes.size() > 1) {
MeshCore::MeshKernel kernel;
// copy the data of the first mesh, this will be the new model then
kernel = myMesh->getKernel();
for (std::vector<Mesh::MeshObjectConstRef>::iterator it = meshes.begin(); it != meshes.end(); ++it) {
if (*it != myMesh) {
Base::Console().Message("MeshTestJob::run() in thread: %p\n", QThread::currentThreadId());
}
}
// avoid to copy the data
Mesh::MeshObject* mesh = new Mesh::MeshObject();
mesh->swap(kernel);
return mesh;
}
else {
Mesh::MeshObject* mesh = new Mesh::MeshObject();
mesh->setKernel(myMesh->getKernel());
return mesh;
}
}
};
DEF_STD_CMD_A(CmdSandboxMeshTestJob)
CmdSandboxMeshTestJob::CmdSandboxMeshTestJob()
: Command("Sandbox_MeshTestJob")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Test mesh job");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
sPixmap = "Std_Tool7";
}
void CmdSandboxMeshTestJob::activated(int iMsg)
{
Mesh::MeshObjectConstRefList meshes;
App::Document* app_doc = App::GetApplication().getActiveDocument();
std::vector<Mesh::Feature*> meshObj = Gui::Selection().getObjectsOfType<Mesh::Feature>(app_doc->getName());
for (std::vector<Mesh::Feature*>::iterator it = meshObj.begin(); it != meshObj.end(); ++it) {
meshes.push_back((*it)->Mesh.getValuePtr());
}
int iteration = 1;
while (meshes.size() > 1) {
int numJobs = QThread::idealThreadCount();
if (numJobs < 0) numJobs = 2;
while (numJobs > (int)(meshes.size()+1)/2)
numJobs /= 2;
numJobs = std::max<int>(1, numJobs);
// divide all meshes we have into several groups
std::vector<Mesh::MeshObjectConstRefArray> mesh_groups;
while (numJobs > 0) {
int size = (int)meshes.size();
int count = size / numJobs;
--numJobs;
Mesh::MeshObjectConstRefArray meshes_per_job;
for (int i=0; i<count; i++) {
meshes_per_job.push_back(meshes.front());
meshes.pop_front();
}
mesh_groups.push_back(meshes_per_job);
}
// run the actual multi-threaded mesh test
Base::Console().Message("Mesh test (step %d)...\n",iteration++);
MeshTestJob meshJob;
QFuture<Mesh::MeshObject*> mesh_future = QtConcurrent::mapped
(mesh_groups, boost::bind(&MeshTestJob::run, &meshJob, _1));
// keep it responsive during computation
QFutureWatcher<Mesh::MeshObject*> mesh_watcher;
mesh_watcher.setFuture(mesh_future);
QEventLoop loop;
QObject::connect(&mesh_watcher, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
for (QFuture<Mesh::MeshObject*>::const_iterator it = mesh_future.begin(); it != mesh_future.end(); ++it) {
meshes.push_back(Mesh::MeshObjectConstRef(*it));
}
}
if (meshes.empty()) {
Base::Console().Error("The mesh test failed to create a valid mesh.\n");
return;
}
}
bool CmdSandboxMeshTestJob::isActive(void)
{
return hasActiveDocument();
}
class MeshThread : public QThread
{
public:
MeshThread(Base::Reference<Mesh::MeshObject> m, QObject* p=0)
: QThread(p), mesh(m)
{}
protected:
void run()
{
for (int i=0; i<100;i++) {
Base::Reference<Mesh::MeshObject> new_ref;
new_ref = mesh;
}
}
private:
Base::Reference<Mesh::MeshObject> mesh;
};
DEF_STD_CMD_A(CmdSandboxMeshTestRef)
CmdSandboxMeshTestRef::CmdSandboxMeshTestRef()
: Command("Sandbox_MeshTestRef")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Test mesh reference");
sToolTipText = QT_TR_NOOP("Sandbox Test function");
sWhatsThis = QT_TR_NOOP("Sandbox Test function");
sStatusTip = QT_TR_NOOP("Sandbox Test function");
}
void CmdSandboxMeshTestRef::activated(int iMsg)
{
Gui::WaitCursor wc;
std::vector< boost::shared_ptr<QThread> > threads;
Base::Reference<Mesh::MeshObject> mesh(new Mesh::MeshObject);
int num = mesh.getRefCount();
for (int i=0; i<10; i++) {
boost::shared_ptr<QThread> trd(new MeshThread(mesh));
trd->start();
threads.push_back(trd);
}
QTimer timer;
QEventLoop loop;
QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
timer.start(2000);
loop.exec();
threads.clear();
Mesh::MeshObject* ptr = (Mesh::MeshObject*)mesh;
if (!ptr)
Base::Console().Error("Object deleted\n");
if (num != mesh.getRefCount())
Base::Console().Error("Reference count is %d\n",mesh.getRefCount());
}
bool CmdSandboxMeshTestRef::isActive(void)
{
return true;
}
//===========================================================================
// Std_GrabWidget
//===========================================================================
DEF_STD_CMD_A(CmdTestGrabWidget);
CmdTestGrabWidget::CmdTestGrabWidget()
: Command("Std_GrabWidget")
{
sGroup = "Standard-Test";
sMenuText = "Grab widget";
sToolTipText = "Grab widget";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestGrabWidget::activated(int iMsg)
{
QCalendarWidget* c = new QCalendarWidget();
c->hide();
QPixmap p = QPixmap::grabWidget(c, c->rect());
QLabel* label = new QLabel();
label->resize(c->size());
label->setPixmap(p);
label->show();
delete c;
}
bool CmdTestGrabWidget::isActive(void)
{
return true;
}
//===========================================================================
// Std_ImageNode
//===========================================================================
DEF_3DV_CMD(CmdTestImageNode);
class RenderArea : public QWidget
{
private:
QPainterPath path;
int penWidth;
QColor penColor;
public:
RenderArea(const QPainterPath &path, QWidget *parent=0)
: QWidget(parent), path(path), penColor(0,0,127)
{
penWidth = 2;
setBackgroundRole(QPalette::Base);
}
QSize minimumSizeHint() const
{
return QSize(50, 50);
}
QSize sizeHint() const
{
return QSize(100, 30);
}
void setFillRule(Qt::FillRule rule)
{
path.setFillRule(rule);
update();
}
void setPenWidth(int width)
{
penWidth = width;
update();
}
void setPenColor(const QColor &color)
{
penColor = color;
update();
}
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.scale(width() / 100.0, height() / 100.0);
painter.translate(50.0, 50.0);
painter.translate(-50.0, -50.0);
painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.setBrush(QBrush(QColor(0,85,255), Qt::SolidPattern));
painter.drawPath(path);
painter.setPen(Qt::white);
painter.drawText(25, 40, 70, 20, Qt::AlignHCenter|Qt::AlignVCenter,
QString::fromAscii("Distance: 2.784mm"));
//QPainterPath text;
//text.addText(25,55,QFont(), QString::fromAscii("Distance"));
//painter.setBrush(QBrush(Qt::white, Qt::SolidPattern));
//painter.drawPath(text);
}
};
#ifdef Q_OS_WIN32
class GDIWidget : public QWidget
{
public:
GDIWidget(QWidget* parent) : QWidget(parent)
{setAttribute(Qt::WA_PaintOnScreen); }
QPaintEngine *paintEngine() const { return 0; }
protected:
void paintEvent(QPaintEvent *event) {
HDC hdc = getDC();
SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW));
Rectangle(hdc, 0, 0, width(), height());
RECT rect = {0, 0, width(), height() };
DrawText(hdc, "Hello World!", 12, &rect,
DT_SINGLELINE | DT_VCENTER | DT_CENTER);
releaseDC(hdc);
}
};
#endif
CmdTestImageNode::CmdTestImageNode()
: Command("Std_ImageNode")
{
sGroup = "Standard-Test";
sMenuText = "SoImage node";
sToolTipText = "SoImage node";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestImageNode::activated(int iMsg)
{
QString text = QString::fromAscii("Distance: 2.7jgiorjgor84mm");
QFont font;
QFontMetrics fm(font);
int w = fm.width(text);
int h = fm.height();
QPainterPath roundRectPath;
//roundRectPath.moveTo(80.0, 35.0);
//roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0);
//roundRectPath.lineTo(25.0, 30.0);
//roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0);
//roundRectPath.lineTo(20.0, 65.0);
//roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0);
//roundRectPath.lineTo(75.0, 70.0);
//roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0);
roundRectPath.moveTo(100.0, 5.0);
roundRectPath.arcTo(90.0, 0.0, 10.0, 10.0, 0.0, 90.0);
roundRectPath.lineTo(5.0, 0.0);
roundRectPath.arcTo(0.0, 0.0, 10.0, 10.0, 90.0, 90.0);
roundRectPath.lineTo(0.0, 95.0);
roundRectPath.arcTo(0.0, 90.0, 10.0, 10.0, 180.0, 90.0);
roundRectPath.lineTo(95.0, 100.0);
roundRectPath.arcTo(90.0, 90.0, 10.0, 10.0, 270.0, 90.0);
roundRectPath.closeSubpath();
QLabel* l = new QLabel();
//l.setText(QLatin1String("Distance: 2.784mm"));
//QPixmap p = QPixmap::grabWidget(&l, 0,0,100,100);
//l.show();
//QPixmap p = Gui::BitmapFactory().pixmap("edit-cut");
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
SoImage* node = new SoImage();
QImage image(w+10,h+10,QImage::Format_ARGB32_Premultiplied);// = p.toImage();
image.fill(0x00000000);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(QColor(0,0,127), 2, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.setBrush(QBrush(QColor(0,85,255), Qt::SolidPattern));
QRectF rectangle(0.0, 0.0, w+10, h+10);
painter.drawRoundedRect(rectangle, 5, 5);
//painter.drawRect(rectangle);
//painter.drawPath(roundRectPath);
painter.setPen(QColor(255,255,255));
painter.drawText(5,h+3, text);
painter.end();
//l->setPixmap(QPixmap::fromImage(image));
//l->show();
//RenderArea* ra = new RenderArea(roundRectPath);
//ra->show();
//QPixmap p = QPixmap::grabWidget(ra, 0,0,100,30);
//image = p.toImage();
SoSFImage texture;
Gui::BitmapFactory().convert(image, texture);
node->image = texture;
SoAnnotation* anno = new SoAnnotation();
anno->addChild(node);
static_cast<SoGroup*>(viewer->getSceneGraph())->addChild(anno);
}
//===========================================================================
// Sandbox_GDIWidget
//===========================================================================
DEF_STD_CMD(CmdTestGDIWidget);
CmdTestGDIWidget::CmdTestGDIWidget()
: Command("Sandbox_GDIWidget")
{
sGroup = "Standard-Test";
sMenuText = "GDI widget";
sToolTipText = "GDI widget";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestGDIWidget::activated(int iMsg)
{
#ifdef Q_OS_WIN32
GDIWidget* gdi = new GDIWidget(Gui::getMainWindow());
gdi->show();
gdi->resize(200,200);
gdi->move(400,400);
gdi->setAttribute(Qt::WA_DeleteOnClose);
#endif
}
//===========================================================================
// Sandbox_RedirectPaint
//===========================================================================
DEF_STD_CMD(CmdTestRedirectPaint);
CmdTestRedirectPaint::CmdTestRedirectPaint()
: Command("Sandbox_RedirectPaint")
{
sGroup = "Standard-Test";
sMenuText = "Redirect paint";
sToolTipText = "Redirect paint";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestRedirectPaint::activated(int iMsg)
{
QCalendarWidget* cal = new QCalendarWidget();
QLabel* label = new QLabel();
QPainter::setRedirected(cal,label);
cal->setWindowTitle(QString::fromAscii("QCalendarWidget"));
cal->show();
label->show();
label->setWindowTitle(QString::fromAscii("QLabel"));
}
//===========================================================================
// Sandbox_CryptographicHash
//===========================================================================
DEF_STD_CMD(CmdTestCryptographicHash);
CmdTestCryptographicHash::CmdTestCryptographicHash()
: Command("Sandbox_CryptographicHash")
{
sGroup = "Standard-Test";
sMenuText = "Cryptographic Hash";
sToolTipText = "Cryptographic Hash";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestCryptographicHash::activated(int iMsg)
{
QByteArray data = "FreeCAD";
QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
QMessageBox::information(0,QLatin1String("Hash of: FreeCAD"),QString::fromAscii(hash));
}
//===========================================================================
// Sandbox_WidgetShape
//===========================================================================
DEF_3DV_CMD(CmdTestWidgetShape);
CmdTestWidgetShape::CmdTestWidgetShape()
: Command("Sandbox_WidgetShape")
{
sGroup = "Standard-Test";
sMenuText = "Widget shape";
sToolTipText = "Widget shape";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestWidgetShape::activated(int iMsg)
{
SandboxGui::SoWidgetShape* shape = new SandboxGui::SoWidgetShape;
shape->setWidget(new QCalendarWidget());
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
static_cast<SoGroup*>(viewer->getSceneGraph())->addChild(shape);
}
// -------------------------------------------------------------------------------
DEF_STD_CMD(CmdMengerSponge);
CmdMengerSponge::CmdMengerSponge()
:Command("Sandbox_MengerSponge")
{
sAppModule = "Sandbox";
sGroup = QT_TR_NOOP("Sandbox");
sMenuText = QT_TR_NOOP("Menger sponge");
sToolTipText = QT_TR_NOOP("Menger sponge");
sWhatsThis = QT_TR_NOOP("Menger sponge");
sStatusTip = QT_TR_NOOP("Menger sponge");
}
struct Param {
int level;
float x,y,z;
Param(int l, float x, float y, float z)
: level(l), x(x), y(y), z(z)
{
}
};
typedef Base::Reference<Mesh::MeshObject> MeshObjectRef;
MeshObjectRef globalBox;
// Create a Box and Place it a coords (x,y,z)
MeshObjectRef PlaceBox(float x, float y, float z)
{
MeshObjectRef mesh = new Mesh::MeshObject(*globalBox);
Base::Matrix4D m;
m.move(x,y,z);
mesh->getKernel().Transform(m);
return mesh;
}
MeshObjectRef Sierpinski(int level, float x0, float y0, float z0)
{
float boxnums = std::pow(3.0f,level);
float thirds = boxnums / 3;
float twothirds = thirds * 2;
QList<float> rangerx, rangery, rangerz;
if (level == 0) {
rangerx << x0;
rangery << y0;
rangerz << z0;
}
else {
rangerx << x0 << (x0 + thirds) << (x0 + twothirds);
rangery << y0 << (y0 + thirds) << (y0 + twothirds);
rangerz << z0 << (z0 + thirds) << (z0 + twothirds);
}
int block = 1;
QList<int> skip; skip << 5 << 11 << 13 << 14 << 15 << 17 << 23;
MeshObjectRef mesh = new Mesh::MeshObject();
for (QList<float>::iterator i = rangerx.begin(); i != rangerx.end(); ++i) {
for (QList<float>::iterator j = rangery.begin(); j != rangery.end(); ++j) {
for (QList<float>::iterator k = rangerz.begin(); k != rangerz.end(); ++k) {
if (!skip.contains(block)) {
if (level > 0)
mesh->addMesh(*Sierpinski(level-1,*i,*j,*k));
else
mesh->addMesh(*PlaceBox(*i,*j,*k));
}
block++;
}
}
}
return mesh;
}
MeshObjectRef runSierpinski(const Param& p)
{
return Sierpinski(p.level,p.x,p.y,p.z);
}
MeshObjectRef makeParallelMengerSponge(int level, float x0, float y0, float z0)
{
float boxnums = std::pow(3.0f,level);
float thirds = boxnums / 3;
float twothirds = thirds * 2;
QList<float> rangerx, rangery, rangerz;
rangerx << x0 << (x0 + thirds) << (x0 + twothirds);
rangery << y0 << (y0 + thirds) << (y0 + twothirds);
rangerz << z0 << (z0 + thirds) << (z0 + twothirds);
int block = 1;
QList<int> skip; skip << 5 << 11 << 13 << 14 << 15 << 17 << 23;
// collect the arguments for the algorithm in a list
QList<Param> args;
for (QList<float>::iterator i = rangerx.begin(); i != rangerx.end(); ++i) {
for (QList<float>::iterator j = rangery.begin(); j != rangery.end(); ++j) {
for (QList<float>::iterator k = rangerz.begin(); k != rangerz.end(); ++k) {
if (!skip.contains(block)) {
args << Param(level-1, *i, *j, *k);
}
block++;
}
}
}
QFuture<MeshObjectRef> future = QtConcurrent::mapped(args, runSierpinski);
QFutureWatcher<MeshObjectRef> watcher;
watcher.setFuture(future);
// keep it responsive during computation
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
MeshObjectRef mesh = new Mesh::MeshObject();
for (QFuture<MeshObjectRef>::const_iterator it = future.begin(); it != future.end(); ++it) {
mesh->addMesh(**it);
(*it)->clear();
}
return mesh;
}
void CmdMengerSponge::activated(int iMsg)
{
bool ok;
int level = QInputDialog::getInteger(Gui::getMainWindow(),
QString::fromAscii("Menger sponge"),
QString::fromAscii("Recursion depth:"),
3, 1, 5, 1, &ok);
if (!ok) return;
int ret = QMessageBox::question(Gui::getMainWindow(),
QString::fromAscii("Parallel"),
QString::fromAscii("Do you want to run this in a thread pool?"),
QMessageBox::Yes|QMessageBox::No);
bool parallel=(ret == QMessageBox::Yes);
float x0=0,y0=0,z0=0;
globalBox = Mesh::MeshObject::createCube(1,1,1);
MeshObjectRef mesh;
if (parallel)
mesh = makeParallelMengerSponge(level,x0,y0,z0);
else
mesh = Sierpinski(level,x0,y0,z0);
MeshCore::MeshKernel& kernel = mesh->getKernel();
// remove duplicated points
MeshCore::MeshFixDuplicatePoints(kernel).Fixup();
// remove internal facets
MeshCore::MeshEvalInternalFacets eval(kernel);
eval.Evaluate();
kernel.DeleteFacets(eval.GetIndices());
// repair neighbourhood
kernel.RebuildNeighbours();
App::Document* doc = App::GetApplication().newDocument();
Mesh::Feature* feature = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","MengerSponge"));
feature->Mesh.setValue(*mesh);
feature->purgeTouched();
}
DEF_STD_CMD_A(CmdTestGraphicsView);
CmdTestGraphicsView::CmdTestGraphicsView()
: Command("Std_TestGraphicsView")
{
sGroup = QT_TR_NOOP("Standard-Test");
sMenuText = QT_TR_NOOP("Create new graphics view");
sToolTipText= QT_TR_NOOP("Creates a new view window for the active document");
sStatusTip = QT_TR_NOOP("Creates a new view window for the active document");
}
void CmdTestGraphicsView::activated(int iMsg)
{
Gui::GraphicsView3D* view3D = new Gui::GraphicsView3D(getActiveGuiDocument(), Gui::getMainWindow());
view3D->setWindowTitle(QString::fromAscii("Graphics scene"));
view3D->setWindowIcon(QApplication::windowIcon());
view3D->resize(400, 300);
Gui::getMainWindow()->addWindow(view3D);
}
bool CmdTestGraphicsView::isActive(void)
{
return (getActiveGuiDocument()!=NULL);
}
//===========================================================================
// Std_TestTaskBox
//===========================================================================
DEF_STD_CMD(CmdTestTaskBox);
CmdTestTaskBox::CmdTestTaskBox()
: Command("Std_TestTaskBox")
{
sGroup = "Standard-Test";
sMenuText = "Task box";
sToolTipText = "Task box";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void CmdTestTaskBox::activated(int iMsg)
{
QWidget* w = new SandboxGui::TaskPanelView();
w->setAttribute(Qt::WA_DeleteOnClose);
w->show();
}
void CreateSandboxCommands(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdSandboxDocumentThread());
rcCmdMgr.addCommand(new CmdSandboxDocumentTestThread());
rcCmdMgr.addCommand(new CmdSandboxDocThreadWithSeq());
rcCmdMgr.addCommand(new CmdSandboxDocThreadBusy());
rcCmdMgr.addCommand(new CmdSandboxDocumentNoThread());
rcCmdMgr.addCommand(new CmdSandboxWorkerThread());
rcCmdMgr.addCommand(new CmdSandboxPythonLockThread());
rcCmdMgr.addCommand(new CmdSandboxPythonNolockThread());
rcCmdMgr.addCommand(new CmdSandboxPyQtThread());
rcCmdMgr.addCommand(new CmdSandboxPythonThread());
rcCmdMgr.addCommand(new CmdSandboxPythonMainThread());
rcCmdMgr.addCommand(new CmdSandboxDocThreadWithDialog());
rcCmdMgr.addCommand(new CmdSandboxDocThreadWithFileDlg());
rcCmdMgr.addCommand(new CmdSandboxEventLoop);
rcCmdMgr.addCommand(new CmdSandboxMeshLoader);
rcCmdMgr.addCommand(new CmdSandboxMeshLoaderBoost);
rcCmdMgr.addCommand(new CmdSandboxMeshLoaderFuture);
rcCmdMgr.addCommand(new CmdSandboxMeshTestJob);
rcCmdMgr.addCommand(new CmdSandboxMeshTestRef);
rcCmdMgr.addCommand(new CmdTestGrabWidget());
rcCmdMgr.addCommand(new CmdTestImageNode());
rcCmdMgr.addCommand(new CmdTestWidgetShape());
rcCmdMgr.addCommand(new CmdTestGDIWidget());
rcCmdMgr.addCommand(new CmdTestRedirectPaint());
rcCmdMgr.addCommand(new CmdTestCryptographicHash());
rcCmdMgr.addCommand(new CmdMengerSponge());
rcCmdMgr.addCommand(new CmdTestGraphicsView());
rcCmdMgr.addCommand(new CmdTestTaskBox());
}