FreeCAD

Форк
0
/
Command.cpp 
1456 строк · 46.8 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2009 Werner Mayer <wmayer@users.sourceforge.net>        *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23

24
#include "PreCompiled.h"
25
#ifndef _PreComp_
26
# ifdef FC_OS_WIN32
27
# define WIN32_LEAN_AND_MEAN
28
# define NOMINMAX
29
# include <windows.h>
30
# endif
31
# include <QApplication>
32
# include <QCalendarWidget>
33
# include <QColorDialog>
34
# include <QCryptographicHash>
35
# include <QObject>
36
# include <QEventLoop>
37
# include <QFontMetrics>
38
# include <QFuture>
39
# include <QFutureWatcher>
40
# include <QtConcurrentMap>
41
# include <QLabel>
42
# include <QInputDialog>
43
# include <QMessageBox>
44
# include <QTimer>
45
# include <QImage>
46
# include <QImageReader>
47
# include <QPainter>
48
# include <QPainterPath>
49
# include <QThread>
50
# include <Inventor/nodes/SoAnnotation.h>
51
# include <Inventor/nodes/SoImage.h>
52
# include <Inventor/nodes/SoCone.h>
53
# include <cmath>
54
# include <boost/thread/thread.hpp>
55
# include <boost/thread/mutex.hpp>
56
# include <boost/thread/condition_variable.hpp>
57
# include <boost/thread/future.hpp>
58
# include <boost/bind/bind.hpp>
59
# include <memory>
60
#endif
61

62
#include <Base/Console.h>
63
#include <Base/Sequencer.h>
64
#include <App/Application.h>
65
#include <App/Document.h>
66
#include <Gui/Application.h>
67
#include <Gui/BitmapFactory.h>
68
#include <Gui/Command.h>
69
#include <Gui/MainWindow.h>
70
#include <Gui/FileDialog.h>
71
#include <Gui/Tools.h>
72
#include <Gui/View3DInventor.h>
73
#include <Gui/View3DInventorViewer.h>
74
#include <Gui/WaitCursor.h>
75

76
#include <Mod/Sandbox/App/DocumentThread.h>
77
#include <Mod/Sandbox/App/DocumentProtector.h>
78
#include <Mod/Mesh/App/MeshFeature.h>
79
#include <Mod/Mesh/App/Core/Degeneration.h>
80
#include "Workbench.h"
81
#include "GLGraphicsView.h"
82
#include "TaskPanelView.h"
83

84
namespace bp = boost::placeholders;
85

86
DEF_STD_CMD(CmdSandboxDocumentThread)
87

88
CmdSandboxDocumentThread::CmdSandboxDocumentThread()
89
  :Command("Sandbox_Thread")
90
{
91
    sAppModule    = "Sandbox";
92
    sGroup        = QT_TR_NOOP("Sandbox");
93
    sMenuText     = QT_TR_NOOP("Run several threads");
94
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
95
    sWhatsThis    = "Sandbox_Thread";
96
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
97
    sPixmap       = "Std_Tool1";
98
}
99

100
void CmdSandboxDocumentThread::activated(int)
101
{
102
    App::GetApplication().newDocument("Thread");
103
    for (int i=0; i<5; i++) {
104
        Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
105
        dt->setObjectName(QString::fromLatin1("MyMesh_%1").arg(i));
106
        QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
107
        dt->start();
108
    }
109
}
110

111
// -------------------------------------------------------------------------------
112

113
DEF_STD_CMD(CmdSandboxDocumentTestThread)
114

115
CmdSandboxDocumentTestThread::CmdSandboxDocumentTestThread()
116
  :Command("Sandbox_TestThread")
117
{
118
    sAppModule    = "Sandbox";
119
    sGroup        = QT_TR_NOOP("Sandbox");
120
    sMenuText     = QT_TR_NOOP("Test thread");
121
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
122
    sWhatsThis    = "Sandbox_TestThread";
123
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
124
    sPixmap       = "Std_Tool1";
125
}
126

127
void CmdSandboxDocumentTestThread::activated(int)
128
{
129
    App::GetApplication().newDocument("Thread");
130
    Sandbox::DocumentTestThread* dt = new Sandbox::DocumentTestThread();
131
    QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
132
    dt->start();
133
}
134

135
// -------------------------------------------------------------------------------
136

137
DEF_STD_CMD_A(CmdSandboxDocumentSaveThread)
138

139
CmdSandboxDocumentSaveThread::CmdSandboxDocumentSaveThread()
140
  :Command("Sandbox_SaveThread")
141
{
142
    sAppModule    = "Sandbox";
143
    sGroup        = QT_TR_NOOP("Sandbox");
144
    sMenuText     = QT_TR_NOOP("Save thread");
145
    sToolTipText  = QT_TR_NOOP("Sandbox save function");
146
    sWhatsThis    = "Sandbox_SaveThread";
147
    sStatusTip    = QT_TR_NOOP("Sandbox save function");
148
}
149

150
void CmdSandboxDocumentSaveThread::activated(int)
151
{
152
    App::Document* doc = App::GetApplication().getActiveDocument();
153
    Sandbox::DocumentSaverThread* dt = new Sandbox::DocumentSaverThread(doc);
154
    QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
155
    dt->start();
156
}
157

158
bool CmdSandboxDocumentSaveThread::isActive()
159
{
160
    return App::GetApplication().getActiveDocument() != 0;
161
}
162

163
// -------------------------------------------------------------------------------
164

165
DEF_STD_CMD(CmdSandboxDocThreadWithSeq)
166

167
CmdSandboxDocThreadWithSeq::CmdSandboxDocThreadWithSeq()
168
  :Command("Sandbox_SeqThread")
169
{
170
    sAppModule    = "Sandbox";
171
    sGroup        = QT_TR_NOOP("Sandbox");
172
    sMenuText     = QT_TR_NOOP("Thread and sequencer");
173
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
174
    sWhatsThis    = "Sandbox_SeqThread";
175
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
176
    sPixmap       = "Std_Tool2";
177
}
178

179
void CmdSandboxDocThreadWithSeq::activated(int)
180
{
181
    App::GetApplication().newDocument("Thread");
182
    Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
183
    dt->setObjectName(QString::fromLatin1("MyMesh"));
184
    QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
185
    dt->start();
186
#ifdef FC_DEBUG
187
    int max = 10000;
188
#else
189
    int max = 100000000;
190
#endif
191
    Base::SequencerLauncher seq("Do something meaningful...", max);
192
    double val=0;
193
    for (int i=0; i<max; i++) {
194
        for (int j=0; j<max; j++) {
195
            val = sin(0.12345);
196
        }
197
        seq.next(true);
198
    }
199
    (void)val;
200
}
201

202
// -------------------------------------------------------------------------------
203

204
DEF_STD_CMD(CmdSandboxDocThreadBusy)
205

206
CmdSandboxDocThreadBusy::CmdSandboxDocThreadBusy()
207
  :Command("Sandbox_BlockThread")
208
{
209
    sAppModule    = "Sandbox";
210
    sGroup        = QT_TR_NOOP("Sandbox");
211
    sMenuText     = QT_TR_NOOP("Thread and no sequencer");
212
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
213
    sWhatsThis    = "Sandbox_BlockThread";
214
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
215
    sPixmap       = "Std_Tool3";
216
}
217

218
void CmdSandboxDocThreadBusy::activated(int)
219
{
220
    App::GetApplication().newDocument("Thread");
221
    Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
222
    dt->setObjectName(QString::fromLatin1("MyMesh"));
223
    QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
224
    dt->start();
225
#ifdef FC_DEBUG
226
    int max = 10000;
227
#else
228
    int max = 100000000;
229
#endif
230
    double val=0;
231
    for (int i=0; i<max; i++) {
232
        for (int j=0; j<max; j++) {
233
            val = sin(0.12345);
234
        }
235
    }
236
    (void)val;
237
}
238

239
// -------------------------------------------------------------------------------
240

241
DEF_STD_CMD(CmdSandboxDocumentNoThread)
242

243
CmdSandboxDocumentNoThread::CmdSandboxDocumentNoThread()
244
  :Command("Sandbox_NoThread")
245
{
246
    sAppModule    = "Sandbox";
247
    sGroup        = QT_TR_NOOP("Sandbox");
248
    sMenuText     = QT_TR_NOOP("GUI thread");
249
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
250
    sWhatsThis    = "Sandbox_NoThread";
251
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
252
    sPixmap       = "Std_Tool4";
253
}
254

255
void CmdSandboxDocumentNoThread::activated(int)
256
{
257
    App::GetApplication().newDocument("Thread");
258
    App::Document* doc = App::GetApplication().getActiveDocument();
259
    Sandbox::DocumentProtector dp(doc);
260
    App::DocumentObject* obj = dp.addObject("Mesh::Cube", "MyCube");
261
    (void)obj;
262
    dp.recompute();
263
    App::GetApplication().closeDocument("Thread");
264
    // this forces an exception
265
    App::DocumentObject* obj2 = dp.addObject("Mesh::Cube", "MyCube");
266
    (void)obj2;
267
    dp.recompute();
268
}
269

270
// -------------------------------------------------------------------------------
271

272
DEF_STD_CMD(CmdSandboxWorkerThread)
273

274
CmdSandboxWorkerThread::CmdSandboxWorkerThread()
275
  :Command("Sandbox_WorkerThread")
276
{
277
    sAppModule    = "Sandbox";
278
    sGroup        = QT_TR_NOOP("Sandbox");
279
    sMenuText     = QT_TR_NOOP("Worker thread");
280
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
281
    sWhatsThis    = "Sandbox_WorkerThread";
282
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
283
    sPixmap       = "Std_Tool1";
284
}
285

286
void CmdSandboxWorkerThread::activated(int)
287
{
288
    Sandbox::WorkerThread* wt = new Sandbox::WorkerThread();
289
    QObject::connect(wt, SIGNAL(finished()), wt, SLOT(deleteLater()));
290
    wt->start();
291
}
292

293
// -------------------------------------------------------------------------------
294

295
DEF_STD_CMD(CmdSandboxPythonLockThread)
296

297
CmdSandboxPythonLockThread::CmdSandboxPythonLockThread()
298
  :Command("Sandbox_PythonLockThread")
299
{
300
    sAppModule    = "Sandbox";
301
    sGroup        = QT_TR_NOOP("Sandbox");
302
    sMenuText     = QT_TR_NOOP("Locked Python threads");
303
    sToolTipText  = QT_TR_NOOP("Use Python's thread module where each thread is locked");
304
    sWhatsThis    = "Sandbox_PythonLockThread";
305
    sStatusTip    = QT_TR_NOOP("Use Python's thread module where each thread is locked");
306
}
307

308
void CmdSandboxPythonLockThread::activated(int)
309
{
310
    doCommand(Doc,
311
        "import thread, time, Sandbox\n"
312
        "def adder(doc):\n"
313
        "    lock.acquire()\n"
314
        "    dp=Sandbox.DocumentProtector(doc)\n"
315
        "    dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
316
        "    dp.recompute()\n"
317
        "    lock.release()\n"
318
        "\n"
319
        "lock=thread.allocate_lock()\n"
320
        "doc=App.newDocument()\n"
321
        "for i in range(2):\n"
322
        "    thread.start_new(adder,(doc,))\n"
323
        "\n"
324
        "time.sleep(1)\n"
325
    );
326
}
327

328
// -------------------------------------------------------------------------------
329

330
DEF_STD_CMD(CmdSandboxPythonNolockThread)
331

332
CmdSandboxPythonNolockThread::CmdSandboxPythonNolockThread()
333
  :Command("Sandbox_NolockPython")
334
{
335
    sAppModule    = "Sandbox";
336
    sGroup        = QT_TR_NOOP("Sandbox");
337
    sMenuText     = QT_TR_NOOP("Unlocked Python threads");
338
    sToolTipText  = QT_TR_NOOP("Use Python's thread module where each thread is unlocked");
339
    sWhatsThis    = "Sandbox_NolockPython";
340
    sStatusTip    = QT_TR_NOOP("Use Python's thread module where each thread is unlocked");
341
}
342

343
void CmdSandboxPythonNolockThread::activated(int)
344
{
345
    doCommand(Doc,
346
        "import thread, time, Sandbox\n"
347
        "def adder(doc):\n"
348
        "    dp=Sandbox.DocumentProtector(doc)\n"
349
        "    dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
350
        "    dp.recompute()\n"
351
        "\n"
352
        "doc=App.newDocument()\n"
353
        "for i in range(2):\n"
354
        "    thread.start_new(adder,(doc,))\n"
355
        "\n"
356
        "time.sleep(1)\n"
357
    );
358
}
359

360
// -------------------------------------------------------------------------------
361

362
DEF_STD_CMD(CmdSandboxPySideThread)
363

364
CmdSandboxPySideThread::CmdSandboxPySideThread()
365
  :Command("Sandbox_PySideThread")
366
{
367
    sAppModule    = "Sandbox";
368
    sGroup        = QT_TR_NOOP("Sandbox");
369
    sMenuText     = QT_TR_NOOP("PySide threads");
370
    sToolTipText  = QT_TR_NOOP("Use PySide's thread module");
371
    sWhatsThis    = "Sandbox_PySideThread";
372
    sStatusTip    = QT_TR_NOOP("Use PySide's thread module");
373
}
374

375
void CmdSandboxPySideThread::activated(int)
376
{
377
    doCommand(Doc,
378
        "from PySide import QtCore; import Sandbox\n"
379
        "class Thread(QtCore.QThread):\n"
380
        "    def run(self):\n"
381
        "        dp=Sandbox.DocumentProtector(doc)\n"
382
        "        dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
383
        "        dp.recompute()\n"
384
        "\n"
385
        "doc=App.newDocument()\n"
386
        "threads=[]\n"
387
        "for i in range(2):\n"
388
        "    thread=Thread()\n"
389
        "    threads.append(thread)\n"
390
        "    thread.start()\n"
391
        "\n"
392
    );
393
}
394

395
// -------------------------------------------------------------------------------
396

397
DEF_STD_CMD(CmdSandboxPythonThread)
398

399
CmdSandboxPythonThread::CmdSandboxPythonThread()
400
  :Command("Sandbox_PythonThread")
401
{
402
    sAppModule    = "Sandbox";
403
    sGroup        = QT_TR_NOOP("Sandbox");
404
    sMenuText     = QT_TR_NOOP("Python threads");
405
    sToolTipText  = QT_TR_NOOP("Use class PythonThread running Python code in its run() method");
406
    sWhatsThis    = "Sandbox_PythonThread";
407
    sStatusTip    = QT_TR_NOOP("Use class PythonThread running Python code in its run() method");
408
}
409

410
void CmdSandboxPythonThread::activated(int)
411
{
412
    App::GetApplication().newDocument("Thread");
413
    for (int i=0; i<5; i++) {
414
        Sandbox::PythonThread* pt = new Sandbox::PythonThread();
415
        pt->setObjectName(QString::fromLatin1("MyMesh_%1").arg(i));
416
        QObject::connect(pt, SIGNAL(finished()), pt, SLOT(deleteLater()));
417
        pt->start();
418
    }
419
}
420

421
// -------------------------------------------------------------------------------
422

423
DEF_STD_CMD(CmdSandboxPythonMainThread)
424

425
CmdSandboxPythonMainThread::CmdSandboxPythonMainThread()
426
  :Command("Sandbox_PythonMainThread")
427
{
428
    sAppModule    = "Sandbox";
429
    sGroup        = QT_TR_NOOP("Sandbox");
430
    sMenuText     = QT_TR_NOOP("Python main thread");
431
    sToolTipText  = QT_TR_NOOP("Run python code in main thread");
432
    sWhatsThis    = "Sandbox_PythonMainThread";
433
    sStatusTip    = QT_TR_NOOP("Run python code in main thread");
434
}
435

436
void CmdSandboxPythonMainThread::activated(int)
437
{
438
    doCommand(Doc,
439
        "import Sandbox\n"
440
        "doc=App.newDocument()\n"
441
        "dp=Sandbox.DocumentProtector(doc)\n"
442
        "dp.addObject(\"Mesh::Ellipsoid\",\"Mesh\")\n"
443
        "dp.recompute()\n"
444
    );
445
}
446

447
// -------------------------------------------------------------------------------
448

449
DEF_STD_CMD(CmdSandboxDocThreadWithDialog)
450

451
CmdSandboxDocThreadWithDialog::CmdSandboxDocThreadWithDialog()
452
  :Command("Sandbox_Dialog")
453
{
454
    sAppModule    = "Sandbox";
455
    sGroup        = QT_TR_NOOP("Sandbox");
456
    sMenuText     = QT_TR_NOOP("Thread and modal dialog");
457
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
458
    sWhatsThis    = "Sandbox_Dialog";
459
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
460
    sPixmap       = "Std_Tool7";
461
}
462

463
void CmdSandboxDocThreadWithDialog::activated(int)
464
{
465
    App::GetApplication().newDocument("Thread");
466
    Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
467
    dt->setObjectName(QString::fromLatin1("MyMesh"));
468
    QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
469
    dt->start();
470
    //QFileDialog::getOpenFileName();
471
    QColorDialog::getColor(Qt::white,Gui::getMainWindow());
472
}
473

474
// -------------------------------------------------------------------------------
475

476
DEF_STD_CMD(CmdSandboxDocThreadWithFileDlg)
477

478
CmdSandboxDocThreadWithFileDlg::CmdSandboxDocThreadWithFileDlg()
479
  :Command("Sandbox_FileDialog")
480
{
481
    sAppModule    = "Sandbox";
482
    sGroup        = QT_TR_NOOP("Sandbox");
483
    sMenuText     = QT_TR_NOOP("Thread and file dialog");
484
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
485
    sWhatsThis    = "Sandbox_FileDialog";
486
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
487
    sPixmap       = "Std_Tool7";
488
}
489

490
void CmdSandboxDocThreadWithFileDlg::activated(int)
491
{
492
    App::GetApplication().newDocument("Thread");
493
    Sandbox::DocumentThread* dt = new Sandbox::DocumentThread();
494
    dt->setObjectName(QString::fromLatin1("MyMesh"));
495
    QObject::connect(dt, SIGNAL(finished()), dt, SLOT(deleteLater()));
496
    dt->start();
497
    QFileDialog::getOpenFileName();
498
}
499

500
// -------------------------------------------------------------------------------
501

502
class CmdSandboxEventLoop : public Gui::Command
503
{
504
public:
505
    CmdSandboxEventLoop();
506
    const char* className() const
507
    { return "CmdSandboxEventLoop"; }
508
protected:
509
    void activated(int iMsg);
510
    bool isActive(void);
511
private:
512
    QEventLoop loop;
513
};
514

515

516
CmdSandboxEventLoop::CmdSandboxEventLoop()
517
  :Command("Sandbox_EventLoop")
518
{
519
    sAppModule    = "Sandbox";
520
    sGroup        = QT_TR_NOOP("Sandbox");
521
    sMenuText     = QT_TR_NOOP("Local event loop");
522
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
523
    sWhatsThis    = "Sandbox_EventLoop";
524
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
525
    sPixmap       = "Std_Tool6";
526
}
527

528
void CmdSandboxEventLoop::activated(int)
529
{
530
    QTimer timer;
531
    timer.setSingleShot(true);
532
    QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
533

534
    timer.start(5000); // 5s timeout
535
    loop.exec();
536
    Base::Console().Message("CmdSandboxEventLoop: timeout\n");
537
}
538

539
bool CmdSandboxEventLoop::isActive(void)
540
{
541
    return (!loop.isRunning());
542
}
543

544
// -------------------------------------------------------------------------------
545

546
class CmdSandboxMeshLoader : public Gui::Command
547
{
548
public:
549
    CmdSandboxMeshLoader();
550
    const char* className() const
551
    { return "CmdSandboxMeshLoader"; }
552
protected:
553
    void activated(int iMsg);
554
    bool isActive(void);
555
private:
556
    QEventLoop loop;
557
};
558

559
CmdSandboxMeshLoader::CmdSandboxMeshLoader()
560
  :Command("Sandbox_MeshLoad")
561
{
562
    sAppModule    = "Sandbox";
563
    sGroup        = QT_TR_NOOP("Sandbox");
564
    sMenuText     = QT_TR_NOOP("Load mesh in thread");
565
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
566
    sWhatsThis    = "Sandbox_MeshLoad";
567
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
568
    sPixmap       = "Std_Tool6";
569
}
570

571
void CmdSandboxMeshLoader::activated(int)
572
{
573
    // use current path as default
574
    QStringList filter;
575
    filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)");
576
    filter << QObject::tr("Binary STL (*.stl)");
577
    filter << QObject::tr("ASCII STL (*.ast)");
578
    filter << QObject::tr("Binary Mesh (*.bms)");
579
    filter << QObject::tr("Alias Mesh (*.obj)");
580
    filter << QObject::tr("Inventor V2.1 ascii (*.iv)");
581
    //filter << "Nastran (*.nas *.bdf)";
582
    filter << QObject::tr("All Files (*.*)");
583

584
    // Allow multi selection
585
    QString fn = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(),
586
        QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;")));
587

588
    Sandbox::MeshLoaderThread thread(fn);
589
    QObject::connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
590

591
    thread.start();
592
    loop.exec();
593

594
    Base::Reference<Mesh::MeshObject> data = thread.getMesh();
595
    App::Document* doc = App::GetApplication().getActiveDocument();
596
    Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh"));
597
    mesh->Mesh.setValuePtr((Mesh::MeshObject*)data);
598
    mesh->purgeTouched();
599
}
600

601
bool CmdSandboxMeshLoader::isActive(void)
602
{
603
    return (hasActiveDocument() && !loop.isRunning());
604
}
605

606
// -------------------------------------------------------------------------------
607

608
Base::Reference<Mesh::MeshObject> loadMesh(const QString& s)
609
{
610
    Mesh::MeshObject* mesh = new Mesh::MeshObject();
611
    mesh->load((const char*)s.toUtf8());
612
    return mesh;
613
}
614

615
DEF_STD_CMD_A(CmdSandboxMeshLoaderBoost)
616

617
CmdSandboxMeshLoaderBoost::CmdSandboxMeshLoaderBoost()
618
  :Command("Sandbox_MeshLoaderBoost")
619
{
620
    sAppModule    = "Sandbox";
621
    sGroup        = QT_TR_NOOP("Sandbox");
622
    sMenuText     = QT_TR_NOOP("Load mesh in boost-thread");
623
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
624
    sWhatsThis    = "Sandbox_MeshLoaderBoost";
625
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
626
    sPixmap       = "Std_Tool6";
627
}
628

629
void CmdSandboxMeshLoaderBoost::activated(int)
630
{
631
    // use current path as default
632
    QStringList filter;
633
    filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)");
634
    filter << QObject::tr("Binary STL (*.stl)");
635
    filter << QObject::tr("ASCII STL (*.ast)");
636
    filter << QObject::tr("Binary Mesh (*.bms)");
637
    filter << QObject::tr("Alias Mesh (*.obj)");
638
    filter << QObject::tr("Inventor V2.1 ascii (*.iv)");
639
    //filter << "Nastran (*.nas *.bdf)";
640
    filter << QObject::tr("All Files (*.*)");
641

642
    // Allow multi selection
643
    QString fn = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(),
644
        QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;")));
645

646
    boost::packaged_task< Base::Reference<Mesh::MeshObject> > pt
647
        (boost::bind(&loadMesh, fn));
648
    boost::unique_future< Base::Reference<Mesh::MeshObject> > fi=pt.get_future();
649
    boost::thread task(boost::move(pt)); // launch task on a thread
650
    fi.wait(); // wait for it to be finished
651

652
    App::Document* doc = App::GetApplication().getActiveDocument();
653
    Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh"));
654
    mesh->Mesh.setValuePtr((Mesh::MeshObject*)fi.get());
655
    mesh->purgeTouched();
656
}
657

658
bool CmdSandboxMeshLoaderBoost::isActive(void)
659
{
660
    return hasActiveDocument();
661
}
662

663
DEF_STD_CMD_A(CmdSandboxMeshLoaderFuture)
664

665
CmdSandboxMeshLoaderFuture::CmdSandboxMeshLoaderFuture()
666
  :Command("Sandbox_MeshLoaderFuture")
667
{
668
    sAppModule    = "Sandbox";
669
    sGroup        = QT_TR_NOOP("Sandbox");
670
    sMenuText     = QT_TR_NOOP("Load mesh in QFuture");
671
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
672
    sWhatsThis    = "Sandbox_MeshLoaderFuture";
673
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
674
    sPixmap       = "Std_Tool6";
675
}
676

677
void CmdSandboxMeshLoaderFuture::activated(int)
678
{
679
    // use current path as default
680
    QStringList filter;
681
    filter << QObject::tr("All Mesh Files (*.stl *.ast *.bms *.obj)");
682
    filter << QObject::tr("Binary STL (*.stl)");
683
    filter << QObject::tr("ASCII STL (*.ast)");
684
    filter << QObject::tr("Binary Mesh (*.bms)");
685
    filter << QObject::tr("Alias Mesh (*.obj)");
686
    filter << QObject::tr("Inventor V2.1 ascii (*.iv)");
687
    //filter << "Nastran (*.nas *.bdf)";
688
    filter << QObject::tr("All Files (*.*)");
689

690
    // Allow multi selection
691
    QStringList fn = Gui::FileDialog::getOpenFileNames(Gui::getMainWindow(),
692
        QObject::tr("Import mesh"), QString(), filter.join(QLatin1String(";;")));
693

694
    QFuture< Base::Reference<Mesh::MeshObject> > future = QtConcurrent::mapped
695
        (fn, loadMesh);
696

697
    QFutureWatcher< Base::Reference<Mesh::MeshObject> > watcher;
698
    watcher.setFuture(future);
699

700
    // keep it responsive during computation
701
    QEventLoop loop;
702
    QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
703
    loop.exec();
704

705
    App::Document* doc = App::GetApplication().getActiveDocument();
706
    for (QFuture< Base::Reference<Mesh::MeshObject> >::const_iterator it = future.begin(); it != future.end(); ++it) {
707
        Mesh::Feature* mesh = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","Mesh"));
708
        mesh->Mesh.setValuePtr((Mesh::MeshObject*)(*it));
709
        mesh->purgeTouched();
710
    }
711
}
712

713
bool CmdSandboxMeshLoaderFuture::isActive(void)
714
{
715
    return hasActiveDocument();
716
}
717

718
namespace Mesh {
719
typedef Base::Reference<const MeshObject> MeshObjectConstRef;
720
typedef std::list<MeshObjectConstRef> MeshObjectConstRefList;
721
typedef std::vector<MeshObjectConstRef> MeshObjectConstRefArray;
722
}
723

724
struct MeshObject_greater  : public std::binary_function<const Mesh::MeshObjectConstRef&,
725
                                                         const Mesh::MeshObjectConstRef&, bool>
726
{
727
    bool operator()(const Mesh::MeshObjectConstRef& x,
728
                    const Mesh::MeshObjectConstRef& y) const
729
    {
730
        return x->countFacets() > y->countFacets();
731
    }
732
};
733

734
class MeshTestJob
735
{
736

737
public:
738
    MeshTestJob()
739
    {
740
    }
741
    ~MeshTestJob()
742
    {
743
    }
744

745
    Mesh::MeshObject* run(const std::vector<Mesh::MeshObjectConstRef>& meshdata)
746
    {
747
        std::vector<Mesh::MeshObjectConstRef> meshes = meshdata;
748
        if (meshes.empty())
749
            return 0; // nothing todo
750
        Mesh::MeshObjectConstRef myMesh = 0;
751
        std::sort(meshes.begin(), meshes.end(), MeshObject_greater());
752
        myMesh = meshes.front();
753

754
        if (meshes.size() > 1) {
755
            MeshCore::MeshKernel kernel;
756

757
            // copy the data of the first mesh, this will be the new model then
758
            kernel = myMesh->getKernel();
759
            for (std::vector<Mesh::MeshObjectConstRef>::iterator it = meshes.begin(); it != meshes.end(); ++it) {
760
                if (*it != myMesh) {
761
                    Base::Console().Message("MeshTestJob::run() in thread: %p\n", QThread::currentThreadId());
762
                }
763
            }
764

765
            // avoid to copy the data
766
            Mesh::MeshObject* mesh = new Mesh::MeshObject();
767
            mesh->swap(kernel);
768
            return mesh;
769
        }
770
        else {
771
            Mesh::MeshObject* mesh = new Mesh::MeshObject();
772
            mesh->setKernel(myMesh->getKernel());
773
            return mesh;
774
        }
775
    }
776
};
777

778
DEF_STD_CMD_A(CmdSandboxMeshTestJob)
779

780
CmdSandboxMeshTestJob::CmdSandboxMeshTestJob()
781
  : Command("Sandbox_MeshTestJob")
782
{
783
    sAppModule    = "Sandbox";
784
    sGroup        = QT_TR_NOOP("Sandbox");
785
    sMenuText     = QT_TR_NOOP("Test mesh job");
786
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
787
    sWhatsThis    = "Sandbox_MeshTestJob";
788
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
789
    sPixmap       = "Std_Tool7";
790
}
791

792
void CmdSandboxMeshTestJob::activated(int)
793
{
794
    Mesh::MeshObjectConstRefList meshes;
795
    App::Document* app_doc = App::GetApplication().getActiveDocument();
796
    std::vector<Mesh::Feature*> meshObj = Gui::Selection().getObjectsOfType<Mesh::Feature>(app_doc->getName());
797
    for (std::vector<Mesh::Feature*>::iterator it = meshObj.begin(); it != meshObj.end(); ++it) {
798
        meshes.push_back((*it)->Mesh.getValuePtr());
799
    }
800

801
    int iteration = 1;
802
    while (meshes.size() > 1) {
803
        int numJobs = QThread::idealThreadCount();
804
        if (numJobs < 0) numJobs = 2;
805

806
        while (numJobs > (int)(meshes.size()+1)/2)
807
            numJobs /= 2;
808
        numJobs = std::max<int>(1, numJobs);
809

810
        // divide all meshes we have into several groups
811
        std::vector<Mesh::MeshObjectConstRefArray> mesh_groups;
812
        while (numJobs > 0) {
813
            int size = (int)meshes.size();
814
            int count = size / numJobs;
815
            --numJobs;
816
            Mesh::MeshObjectConstRefArray meshes_per_job;
817
            for (int i=0; i<count; i++) {
818
                meshes_per_job.push_back(meshes.front());
819
                meshes.pop_front();
820
            }
821
            mesh_groups.push_back(meshes_per_job);
822
        }
823

824
        // run the actual multi-threaded mesh test
825
        Base::Console().Message("Mesh test (step %d)...\n",iteration++);
826
        MeshTestJob meshJob;
827
        QFuture<Mesh::MeshObject*> mesh_future = QtConcurrent::mapped
828
            (mesh_groups, boost::bind(&MeshTestJob::run, &meshJob, bp::_1));
829

830
        // keep it responsive during computation
831
        QFutureWatcher<Mesh::MeshObject*> mesh_watcher;
832
        mesh_watcher.setFuture(mesh_future);
833
        QEventLoop loop;
834
        QObject::connect(&mesh_watcher, SIGNAL(finished()), &loop, SLOT(quit()));
835
        loop.exec();
836

837
        for (QFuture<Mesh::MeshObject*>::const_iterator it = mesh_future.begin(); it != mesh_future.end(); ++it) {
838
            meshes.push_back(Mesh::MeshObjectConstRef(*it));
839
        }
840
    }
841

842
    if (meshes.empty()) {
843
        Base::Console().Error("The mesh test failed to create a valid mesh.\n");
844
        return;
845
    }
846
}
847

848
bool CmdSandboxMeshTestJob::isActive(void)
849
{
850
    return hasActiveDocument();
851
}
852

853
class MeshThread : public QThread
854
{
855
public:
856
    MeshThread(Base::Reference<Mesh::MeshObject> m, QObject* p=0)
857
        : QThread(p), mesh(m)
858
    {}
859

860
protected:
861
    void run()
862
    {
863
        for (int i=0; i<100;i++) {
864
            Base::Reference<Mesh::MeshObject> new_ref;
865
            new_ref = mesh;
866
        }
867
    }
868

869
private:
870
    Base::Reference<Mesh::MeshObject> mesh;
871
};
872

873
DEF_STD_CMD_A(CmdSandboxMeshTestRef)
874

875
CmdSandboxMeshTestRef::CmdSandboxMeshTestRef()
876
  : Command("Sandbox_MeshTestRef")
877
{
878
    sAppModule    = "Sandbox";
879
    sGroup        = QT_TR_NOOP("Sandbox");
880
    sMenuText     = QT_TR_NOOP("Test mesh reference");
881
    sToolTipText  = QT_TR_NOOP("Sandbox Test function");
882
    sWhatsThis    = "Sandbox_MeshTestRef";
883
    sStatusTip    = QT_TR_NOOP("Sandbox Test function");
884
}
885

886
void CmdSandboxMeshTestRef::activated(int)
887
{
888
    Gui::WaitCursor wc;
889
    std::vector< std::shared_ptr<QThread> > threads;
890
    Base::Reference<Mesh::MeshObject> mesh(new Mesh::MeshObject);
891
    int num = mesh.getRefCount();
892

893
    for (int i=0; i<10; i++) {
894
        std::shared_ptr<QThread> trd(new MeshThread(mesh));
895
        trd->start();
896
        threads.push_back(trd);
897
    }
898

899
    QTimer timer;
900
    QEventLoop loop;
901
    QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
902
    timer.start(2000);
903
    loop.exec();
904
    threads.clear();
905

906
    Mesh::MeshObject* ptr = (Mesh::MeshObject*)mesh;
907
    if (!ptr)
908
        Base::Console().Error("Object deleted\n");
909
    if (num != mesh.getRefCount())
910
        Base::Console().Error("Reference count is %d\n",mesh.getRefCount());
911
}
912

913
bool CmdSandboxMeshTestRef::isActive(void)
914
{
915
    return true;
916
}
917

918
//===========================================================================
919
// Std_GrabWidget
920
//===========================================================================
921
DEF_STD_CMD_A(CmdTestGrabWidget)
922

923
CmdTestGrabWidget::CmdTestGrabWidget()
924
  : Command("Std_GrabWidget")
925
{
926
    sGroup          = "Standard-Test";
927
    sMenuText       = "Grab widget";
928
    sToolTipText    = "Grab widget";
929
    sWhatsThis      = "Std_GrabWidget";
930
    sStatusTip      = sToolTipText;
931
}
932

933
void CmdTestGrabWidget::activated(int)
934
{
935
    QCalendarWidget* c = new QCalendarWidget();
936
    c->hide();
937
    QPixmap p = c->grab(c->rect());
938
    QLabel* label = new QLabel();
939
    label->resize(c->size());
940
    label->setPixmap(p);
941
    label->show();
942
    delete c;
943
}
944

945
bool CmdTestGrabWidget::isActive(void)
946
{
947
    return true;
948
}
949

950
//===========================================================================
951
// Std_ImageNode
952
//===========================================================================
953
DEF_3DV_CMD(CmdTestImageNode)
954

955
class RenderArea : public QWidget
956
{
957
private:
958
    QPainterPath path;
959
    int penWidth;
960
    QColor penColor;
961

962
public:
963
    RenderArea(const QPainterPath &path, QWidget *parent=0)
964
      : QWidget(parent), path(path), penColor(0,0,127)
965
    {
966
        penWidth = 2;
967
        setBackgroundRole(QPalette::Base);
968
    }
969

970
    QSize minimumSizeHint() const
971
    {
972
        return QSize(50, 50);
973
    }
974

975
    QSize sizeHint() const
976
    {
977
        return QSize(100, 30);
978
    }
979

980
    void setFillRule(Qt::FillRule rule)
981
    {
982
        path.setFillRule(rule);
983
        update();
984
    }
985

986
    void setPenWidth(int width)
987
    {
988
        penWidth = width;
989
        update();
990
    }
991

992
    void setPenColor(const QColor &color)
993
    {
994
        penColor = color;
995
        update();
996
    }
997

998
    void paintEvent(QPaintEvent *)
999
    {
1000
        QPainter painter(this);
1001
        painter.setRenderHint(QPainter::Antialiasing);
1002

1003
        painter.scale(width() / 100.0, height() / 100.0);
1004
        painter.translate(50.0, 50.0);
1005
        painter.translate(-50.0, -50.0);
1006

1007
        painter.setPen(QPen(penColor, penWidth, Qt::SolidLine, Qt::RoundCap,
1008
                            Qt::RoundJoin));
1009
        painter.setBrush(QBrush(QColor(0,85,255), Qt::SolidPattern));
1010
        painter.drawPath(path);
1011
        painter.setPen(Qt::white);
1012
        painter.drawText(25, 40, 70, 20, Qt::AlignHCenter|Qt::AlignVCenter,
1013
            QString::fromLatin1("Distance: 2.784mm"));
1014
    }
1015
};
1016

1017
#ifdef Q_OS_WIN32
1018
class GDIWidget : public QWidget
1019
{
1020
public:
1021
    GDIWidget(QWidget* parent) : QWidget(parent)
1022
    {
1023
        setAttribute(Qt::WA_PaintOnScreen);
1024
        setAttribute(Qt::WA_NativeWindow);
1025
    }
1026
    QPaintEngine *paintEngine() const {
1027
        return 0;
1028
    }
1029
protected:
1030
    void paintEvent(QPaintEvent *event) {
1031

1032
        HWND hWnd = (HWND)this->winId();
1033
        HDC hdc = GetDC(hWnd);
1034
        SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW));
1035
        Rectangle(hdc, 0, 0, width(), height());
1036
        RECT rect = {0, 0, width(), height() };
1037
        DrawTextA(hdc, "Hello World!", 12, &rect,
1038
        DT_SINGLELINE | DT_VCENTER | DT_CENTER);
1039
        ReleaseDC(hWnd, hdc);
1040
     }
1041
};
1042
#endif
1043

1044
CmdTestImageNode::CmdTestImageNode()
1045
  : Command("Std_ImageNode")
1046
{
1047
    sGroup          = "Standard-Test";
1048
    sMenuText       = "SoImage node";
1049
    sToolTipText    = "SoImage node";
1050
    sWhatsThis      = "Std_ImageNode";
1051
    sStatusTip      = sToolTipText;
1052
}
1053

1054
void CmdTestImageNode::activated(int)
1055
{
1056
    QString text = QString::fromLatin1("Distance: 2.7jgiorjgor84mm");
1057
    QFont font;
1058
    QFontMetrics fm(font);
1059
    int w = Gui::QtTools::horizontalAdvance(fm, text);
1060
    int h = fm.height();
1061

1062

1063
    QPainterPath roundRectPath;
1064

1065
    roundRectPath.moveTo(100.0, 5.0);
1066
    roundRectPath.arcTo(90.0, 0.0, 10.0, 10.0, 0.0, 90.0);
1067
    roundRectPath.lineTo(5.0, 0.0);
1068
    roundRectPath.arcTo(0.0, 0.0, 10.0, 10.0, 90.0, 90.0);
1069
    roundRectPath.lineTo(0.0, 95.0);
1070
    roundRectPath.arcTo(0.0, 90.0, 10.0, 10.0, 180.0, 90.0);
1071
    roundRectPath.lineTo(95.0, 100.0);
1072
    roundRectPath.arcTo(90.0, 90.0, 10.0, 10.0, 270.0, 90.0);
1073
    roundRectPath.closeSubpath();
1074

1075

1076
    Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
1077
    Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
1078
    SoImage* node = new SoImage();
1079

1080
    QImage image(w+10,h+10,QImage::Format_ARGB32_Premultiplied);// = p.toImage();
1081
    image.fill(0x00000000);
1082
    QPainter painter(&image);
1083
    painter.setRenderHint(QPainter::Antialiasing);
1084

1085
    painter.setPen(QPen(QColor(0,0,127), 2, Qt::SolidLine, Qt::RoundCap,
1086
                        Qt::RoundJoin));
1087
    painter.setBrush(QBrush(QColor(0,85,255), Qt::SolidPattern));
1088
    QRectF rectangle(0.0, 0.0, w+10, h+10);
1089
    painter.drawRoundedRect(rectangle, 5, 5);
1090

1091
    painter.setPen(QColor(255,255,255));
1092
    painter.drawText(5,h+3, text);
1093
    painter.end();
1094

1095
    SoSFImage texture;
1096
    Gui::BitmapFactory().convert(image, texture);
1097
    node->image = texture;
1098
    SoAnnotation* anno = new SoAnnotation();
1099
    anno->addChild(node);
1100
    static_cast<SoGroup*>(viewer->getSceneGraph())->addChild(anno);
1101
}
1102

1103
//===========================================================================
1104
// Sandbox_GDIWidget
1105
//===========================================================================
1106
DEF_STD_CMD(CmdTestGDIWidget)
1107

1108
CmdTestGDIWidget::CmdTestGDIWidget()
1109
  : Command("Sandbox_GDIWidget")
1110
{
1111
    sGroup          = "Standard-Test";
1112
    sMenuText       = "GDI widget";
1113
    sToolTipText    = "GDI widget";
1114
    sWhatsThis      = "Sandbox_GDIWidget";
1115
    sStatusTip      = sToolTipText;
1116
}
1117

1118
void CmdTestGDIWidget::activated(int)
1119
{
1120
#ifdef Q_OS_WIN32
1121
    GDIWidget* gdi = new GDIWidget(Gui::getMainWindow());
1122
    gdi->show();
1123
    gdi->resize(200,200);
1124
    gdi->move(400,400);
1125
    gdi->setAttribute(Qt::WA_DeleteOnClose);
1126
#endif
1127
}
1128

1129
//===========================================================================
1130
// Sandbox_RedirectPaint
1131
//===========================================================================
1132
DEF_STD_CMD(CmdTestRedirectPaint)
1133

1134
CmdTestRedirectPaint::CmdTestRedirectPaint()
1135
  : Command("Sandbox_RedirectPaint")
1136
{
1137
    sGroup          = "Standard-Test";
1138
    sMenuText       = "Redirect paint";
1139
    sToolTipText    = "Redirect paint";
1140
    sWhatsThis      = "Sandbox_RedirectPaint";
1141
    sStatusTip      = sToolTipText;
1142
}
1143

1144
void CmdTestRedirectPaint::activated(int)
1145
{
1146
    QCalendarWidget* cal = new QCalendarWidget();
1147
    cal->setWindowTitle(QString::fromLatin1("QCalendarWidget"));
1148
    cal->show();
1149
    QPixmap img(cal->size());
1150
    cal->render(&img);
1151

1152
    QLabel* label = new QLabel();
1153
    label->setPixmap(img);
1154
    label->show();
1155
    label->setWindowTitle(QString::fromLatin1("QLabel"));
1156
}
1157

1158
//===========================================================================
1159
// Sandbox_CryptographicHash
1160
//===========================================================================
1161
DEF_STD_CMD(CmdTestCryptographicHash)
1162

1163
CmdTestCryptographicHash::CmdTestCryptographicHash()
1164
  : Command("Sandbox_CryptographicHash")
1165
{
1166
    sGroup          = "Standard-Test";
1167
    sMenuText       = "Cryptographic Hash";
1168
    sToolTipText    = "Cryptographic Hash";
1169
    sWhatsThis      = "Sandbox_CryptographicHash";
1170
    sStatusTip      = sToolTipText;
1171
}
1172

1173
void CmdTestCryptographicHash::activated(int)
1174
{
1175
    QByteArray data = "FreeCAD";
1176
    QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1177
    QMessageBox::information(0,QLatin1String("Hash of: FreeCAD"),QString::fromLatin1(hash));
1178
}
1179

1180
//===========================================================================
1181
// Sandbox_WidgetShape
1182
//===========================================================================
1183
DEF_3DV_CMD(CmdTestWidgetShape)
1184

1185
CmdTestWidgetShape::CmdTestWidgetShape()
1186
  : Command("Sandbox_WidgetShape")
1187
{
1188
    sGroup          = "Standard-Test";
1189
    sMenuText       = "Widget shape";
1190
    sToolTipText    = "Widget shape";
1191
    sWhatsThis      = "Sandbox_WidgetShape";
1192
    sStatusTip      = sToolTipText;
1193
}
1194

1195
void CmdTestWidgetShape::activated(int)
1196
{
1197
    SandboxGui::SoWidgetShape* shape = new SandboxGui::SoWidgetShape;
1198
    shape->setWidget(new QCalendarWidget());
1199
    Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
1200
    Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
1201
    static_cast<SoGroup*>(viewer->getSceneGraph())->addChild(shape);
1202
}
1203

1204
// -------------------------------------------------------------------------------
1205

1206
DEF_STD_CMD(CmdMengerSponge)
1207

1208
CmdMengerSponge::CmdMengerSponge()
1209
  :Command("Sandbox_MengerSponge")
1210
{
1211
    sAppModule    = "Sandbox";
1212
    sGroup        = QT_TR_NOOP("Sandbox");
1213
    sMenuText     = QT_TR_NOOP("Menger sponge");
1214
    sToolTipText  = QT_TR_NOOP("Menger sponge");
1215
    sWhatsThis    = "Sandbox_MengerSponge";
1216
    sStatusTip    = QT_TR_NOOP("Menger sponge");
1217
}
1218

1219
struct Param {
1220
    int level;
1221
    float x,y,z;
1222
    Param(int l, float x, float y, float z)
1223
        : level(l), x(x), y(y), z(z)
1224
    {
1225
    }
1226
};
1227

1228
typedef Base::Reference<Mesh::MeshObject> MeshObjectRef;
1229

1230
MeshObjectRef globalBox;
1231

1232
// Create a Box and Place it a coords (x,y,z)
1233
MeshObjectRef PlaceBox(float x, float y, float z)
1234
{
1235
    MeshObjectRef mesh = new Mesh::MeshObject(*globalBox);
1236
    Base::Matrix4D m;
1237
    m.move(x,y,z);
1238
    mesh->getKernel().Transform(m);
1239
    return mesh;
1240
}
1241

1242
MeshObjectRef Sierpinski(int level, float x0, float y0, float z0)
1243
{
1244
    float boxnums = std::pow(3.0f,level);
1245
    float thirds = boxnums / 3;
1246
    float twothirds = thirds * 2;
1247

1248
    QList<float> rangerx, rangery, rangerz;
1249
    if (level == 0) {
1250
        rangerx << x0;
1251
        rangery << y0;
1252
        rangerz << z0;
1253
    }
1254
    else {
1255
        rangerx << x0 << (x0 + thirds) << (x0 + twothirds);
1256
        rangery << y0 << (y0 + thirds) << (y0 + twothirds);
1257
        rangerz << z0 << (z0 + thirds) << (z0 + twothirds);
1258
    }
1259

1260
    int block = 1;
1261
    QList<int> skip; skip << 5 << 11 << 13 << 14 << 15 << 17 << 23;
1262
    MeshObjectRef mesh = new Mesh::MeshObject();
1263

1264
    for (QList<float>::iterator i = rangerx.begin(); i != rangerx.end(); ++i) {
1265
        for (QList<float>::iterator j = rangery.begin(); j != rangery.end(); ++j) {
1266
            for (QList<float>::iterator k = rangerz.begin(); k != rangerz.end(); ++k) {
1267
                if (!skip.contains(block)) {
1268
                    if (level > 0)
1269
                        mesh->addMesh(*Sierpinski(level-1,*i,*j,*k));
1270
                    else
1271
                        mesh->addMesh(*PlaceBox(*i,*j,*k));
1272
                }
1273
                block++;
1274
            }
1275
        }
1276
    }
1277

1278
    return mesh;
1279
}
1280

1281
MeshObjectRef runSierpinski(const Param& p)
1282
{
1283
    return Sierpinski(p.level,p.x,p.y,p.z);
1284
}
1285

1286
MeshObjectRef makeParallelMengerSponge(int level, float x0, float y0, float z0)
1287
{
1288
    float boxnums = std::pow(3.0f,level);
1289
    float thirds = boxnums / 3;
1290
    float twothirds = thirds * 2;
1291

1292
    QList<float> rangerx, rangery, rangerz;
1293
    rangerx << x0 << (x0 + thirds) << (x0 + twothirds);
1294
    rangery << y0 << (y0 + thirds) << (y0 + twothirds);
1295
    rangerz << z0 << (z0 + thirds) << (z0 + twothirds);
1296

1297
    int block = 1;
1298
    QList<int> skip; skip << 5 << 11 << 13 << 14 << 15 << 17 << 23;
1299

1300
    // collect the arguments for the algorithm in a list
1301
    QList<Param> args;
1302

1303
    for (QList<float>::iterator i = rangerx.begin(); i != rangerx.end(); ++i) {
1304
        for (QList<float>::iterator j = rangery.begin(); j != rangery.end(); ++j) {
1305
            for (QList<float>::iterator k = rangerz.begin(); k != rangerz.end(); ++k) {
1306
                if (!skip.contains(block)) {
1307
                    args << Param(level-1, *i, *j, *k);
1308
                }
1309
                block++;
1310
            }
1311
        }
1312
    }
1313

1314
    QFuture<MeshObjectRef> future = QtConcurrent::mapped(args, runSierpinski);
1315

1316
    QFutureWatcher<MeshObjectRef> watcher;
1317
    watcher.setFuture(future);
1318

1319
    // keep it responsive during computation
1320
    QEventLoop loop;
1321
    QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
1322
    loop.exec();
1323

1324
    MeshObjectRef mesh = new Mesh::MeshObject();
1325
    for (QFuture<MeshObjectRef>::const_iterator it = future.begin(); it != future.end(); ++it) {
1326
        mesh->addMesh(**it);
1327
        (*it)->clear();
1328
    }
1329

1330
    return mesh;
1331
}
1332

1333
void CmdMengerSponge::activated(int)
1334
{
1335
    bool ok;
1336
    int level = QInputDialog::getInt(Gui::getMainWindow(),
1337
        QString::fromLatin1("Menger sponge"),
1338
        QString::fromLatin1("Recursion depth:"),
1339
        3, 1, 5, 1, &ok);
1340
    if (!ok)
1341
        return;
1342
    int ret = QMessageBox::question(Gui::getMainWindow(),
1343
        QString::fromLatin1("Parallel"),
1344
        QString::fromLatin1("Do you want to run this in a thread pool?"),
1345
        QMessageBox::Yes|QMessageBox::No);
1346
    bool parallel=(ret == QMessageBox::Yes);
1347
    float x0=0,y0=0,z0=0;
1348

1349
    globalBox = Mesh::MeshObject::createCube(1,1,1);
1350

1351
    MeshObjectRef mesh;
1352
    if (parallel)
1353
        mesh = makeParallelMengerSponge(level,x0,y0,z0);
1354
    else
1355
        mesh = Sierpinski(level,x0,y0,z0);
1356

1357
    MeshCore::MeshKernel& kernel = mesh->getKernel();
1358

1359
    // remove duplicated points
1360
    MeshCore::MeshFixDuplicatePoints(kernel).Fixup();
1361

1362
    // remove internal facets
1363
    MeshCore::MeshEvalInternalFacets eval(kernel);
1364
    eval.Evaluate();
1365
    kernel.DeleteFacets(eval.GetIndices());
1366

1367
    // repair neighbourhood
1368
    kernel.RebuildNeighbours();
1369

1370
    App::Document* doc = App::GetApplication().newDocument();
1371
    Mesh::Feature* feature = static_cast<Mesh::Feature*>(doc->addObject("Mesh::Feature","MengerSponge"));
1372
    feature->Mesh.setValue(*mesh);
1373
    feature->purgeTouched();
1374
}
1375

1376
DEF_STD_CMD_A(CmdTestGraphicsView)
1377

1378
CmdTestGraphicsView::CmdTestGraphicsView()
1379
  : Command("Std_TestGraphicsView")
1380
{
1381
    sGroup      = QT_TR_NOOP("Standard-Test");
1382
    sMenuText   = QT_TR_NOOP("Create new graphics view");
1383
    sToolTipText= QT_TR_NOOP("Creates a new view window for the active document");
1384
    sStatusTip  = QT_TR_NOOP("Creates a new view window for the active document");
1385
}
1386

1387
void CmdTestGraphicsView::activated(int)
1388
{
1389
    Gui::GraphicsView3D* view3D = new Gui::GraphicsView3D(getActiveGuiDocument(), Gui::getMainWindow());
1390
    view3D->setWindowTitle(QString::fromLatin1("Graphics scene"));
1391
    view3D->setWindowIcon(QApplication::windowIcon());
1392
    view3D->resize(400, 300);
1393
    Gui::getMainWindow()->addWindow(view3D);
1394
}
1395

1396
bool CmdTestGraphicsView::isActive(void)
1397
{
1398
    return (getActiveGuiDocument()!=NULL);
1399
}
1400

1401
//===========================================================================
1402
// Std_TestTaskBox
1403
//===========================================================================
1404
DEF_STD_CMD(CmdTestTaskBox)
1405

1406
CmdTestTaskBox::CmdTestTaskBox()
1407
  : Command("Std_TestTaskBox")
1408
{
1409
    sGroup          = "Standard-Test";
1410
    sMenuText       = "Task box";
1411
    sToolTipText    = "Task box";
1412
    sWhatsThis      = "Std_TestTaskBox";
1413
    sStatusTip      = sToolTipText;
1414
}
1415

1416
void CmdTestTaskBox::activated(int)
1417
{
1418
    QWidget* w = new SandboxGui::TaskPanelView();
1419
    w->setAttribute(Qt::WA_DeleteOnClose);
1420
    w->show();
1421
}
1422

1423

1424
void CreateSandboxCommands()
1425
{
1426
    Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
1427
    rcCmdMgr.addCommand(new CmdSandboxDocumentThread());
1428
    rcCmdMgr.addCommand(new CmdSandboxDocumentTestThread());
1429
    rcCmdMgr.addCommand(new CmdSandboxDocumentSaveThread());
1430
    rcCmdMgr.addCommand(new CmdSandboxDocThreadWithSeq());
1431
    rcCmdMgr.addCommand(new CmdSandboxDocThreadBusy());
1432
    rcCmdMgr.addCommand(new CmdSandboxDocumentNoThread());
1433
    rcCmdMgr.addCommand(new CmdSandboxWorkerThread());
1434
    rcCmdMgr.addCommand(new CmdSandboxPythonLockThread());
1435
    rcCmdMgr.addCommand(new CmdSandboxPythonNolockThread());
1436
    rcCmdMgr.addCommand(new CmdSandboxPySideThread());
1437
    rcCmdMgr.addCommand(new CmdSandboxPythonThread());
1438
    rcCmdMgr.addCommand(new CmdSandboxPythonMainThread());
1439
    rcCmdMgr.addCommand(new CmdSandboxDocThreadWithDialog());
1440
    rcCmdMgr.addCommand(new CmdSandboxDocThreadWithFileDlg());
1441
    rcCmdMgr.addCommand(new CmdSandboxEventLoop);
1442
    rcCmdMgr.addCommand(new CmdSandboxMeshLoader);
1443
    rcCmdMgr.addCommand(new CmdSandboxMeshLoaderBoost);
1444
    rcCmdMgr.addCommand(new CmdSandboxMeshLoaderFuture);
1445
    rcCmdMgr.addCommand(new CmdSandboxMeshTestJob);
1446
    rcCmdMgr.addCommand(new CmdSandboxMeshTestRef);
1447
    rcCmdMgr.addCommand(new CmdTestGrabWidget());
1448
    rcCmdMgr.addCommand(new CmdTestImageNode());
1449
    rcCmdMgr.addCommand(new CmdTestWidgetShape());
1450
    rcCmdMgr.addCommand(new CmdTestGDIWidget());
1451
    rcCmdMgr.addCommand(new CmdTestRedirectPaint());
1452
    rcCmdMgr.addCommand(new CmdTestCryptographicHash());
1453
    rcCmdMgr.addCommand(new CmdMengerSponge());
1454
    rcCmdMgr.addCommand(new CmdTestGraphicsView());
1455
    rcCmdMgr.addCommand(new CmdTestTaskBox());
1456
}
1457

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.