~ubuntu-branches/ubuntu/maverick/freecad/maverick

« back to all changes in this revision

Viewing changes to src/Gui/View3DInventor.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Teemu Ikonen
  • Date: 2009-07-16 18:37:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090716183741-oww9kcxqrk991i1n
Tags: upstream-0.8.2237
ImportĀ upstreamĀ versionĀ 0.8.2237

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (c) 2004 Jļæ½rgen Riegel <juergen.riegel@web.de>              *
 
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
 
 
26
#ifndef _PreComp_
 
27
# include <QApplication>
 
28
# include <QFileInfo>
 
29
# include <QKeyEvent>
 
30
# include <QEvent>
 
31
# include <QDropEvent>
 
32
# include <QDragEnterEvent>
 
33
# include <Inventor/actions/SoWriteAction.h>
 
34
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
 
35
# include <Inventor/nodes/SoDirectionalLight.h>
 
36
# include <Inventor/nodes/SoMaterial.h>
 
37
# include <Inventor/nodes/SoOrthographicCamera.h>
 
38
# include <Inventor/nodes/SoPerspectiveCamera.h>
 
39
# include <Inventor/nodes/SoSeparator.h>
 
40
# include <Inventor/nodes/SoShapeHints.h>
 
41
# include <Inventor/events/SoEvent.h>
 
42
# include <Inventor/fields/SoSFString.h>
 
43
# include <Inventor/fields/SoSFColor.h>
 
44
#endif
 
45
 
 
46
#include <Base/Exception.h>
 
47
 
 
48
#include "View3DInventor.h"
 
49
#include "View3DInventorViewer.h"
 
50
#include "Document.h"
 
51
#include "FileDialog.h"
 
52
#include "Application.h"
 
53
#include "MainWindow.h"
 
54
#include "MenuManager.h"
 
55
#include <App/Feature.h>
 
56
#include <Base/Console.h>
 
57
 
 
58
// build in Inventor
 
59
#include "Inventor/Qt/viewers/SoQtExaminerViewer.h"
 
60
#include <Inventor/nodes/SoPerspectiveCamera.h>
 
61
#include <Inventor/nodes/SoOrthographicCamera.h>
 
62
 
 
63
#include "View3DInventorExamples.h"
 
64
#include "SoFCSelectionAction.h"
 
65
#include "View3DPy.h"
 
66
#include "SoFCDB.h"
 
67
#include "NavigationStyle.h"
 
68
 
 
69
#include <locale>
 
70
 
 
71
using namespace Gui;
 
72
 
 
73
TYPESYSTEM_SOURCE_ABSTRACT(Gui::View3DInventor,Gui::BaseView);
 
74
 
 
75
View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, Qt::WFlags wflags)
 
76
    : MDIView(pcDocument, parent, wflags), _viewerPy(0)
 
77
{
 
78
    // important for highlighting 
 
79
    setMouseTracking(true);
 
80
    // accept drops on the window, get handled in dropEvent, dragEnterEvent   
 
81
    setAcceptDrops(true);
 
82
  
 
83
    // attach parameter Observer
 
84
    hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
 
85
    hGrp->Attach(this);
 
86
 
 
87
    // create the inventor widget and set the defaults
 
88
    _viewer = new View3DInventorViewer(this);
 
89
    setViewerDefaults();
 
90
    // apply the user settings
 
91
    hGrp->Notify("HeadlightColor");
 
92
    hGrp->Notify("HeadlightDirection");
 
93
    hGrp->Notify("HeadlightIntensity");
 
94
    hGrp->Notify("EnableBacklight");
 
95
    hGrp->Notify("BacklightColor");
 
96
    hGrp->Notify("BacklightDirection");
 
97
    hGrp->Notify("BacklightIntensity");
 
98
    hGrp->Notify("NavigationStyle");
 
99
 
 
100
    stopSpinTimer = new QTimer(this);
 
101
    connect(stopSpinTimer, SIGNAL(timeout()), this, SLOT(stopAnimating()));
 
102
}
 
103
 
 
104
View3DInventor::~View3DInventor()
 
105
{
 
106
    hGrp->Detach(this);
 
107
 
 
108
    //If we destroy this viewer by calling 'delete' directly the focus proxy widget which is defined 
 
109
    //by a widget in SoQtViewer isn't resetted. This widget becomes to a dangling pointer and makes
 
110
    //the application crash. (Probably it's better to destroy this viewer by calling close().)
 
111
    //See also Gui::Document::~Document().
 
112
    QWidget* foc = qApp->focusWidget();
 
113
    if (foc) {
 
114
        QWidget* par = foc->parentWidget();
 
115
        while (par) {
 
116
            if (par == this) {
 
117
                foc->setFocusProxy(0);
 
118
                foc->clearFocus();
 
119
                break;
 
120
            }
 
121
            par = par->parentWidget();
 
122
        }
 
123
    }
 
124
 
 
125
    if (_viewerPy) {
 
126
        static_cast<View3DInventorPy*>(_viewerPy)->_view = 0;
 
127
        Py_DECREF(_viewerPy);
 
128
    }
 
129
 
 
130
    delete _viewer;
 
131
}
 
132
 
 
133
PyObject *View3DInventor::getPyObject(void)
 
134
{
 
135
    if (!_viewerPy)
 
136
        _viewerPy = new View3DInventorPy(this);
 
137
 
 
138
    Py_INCREF(_viewerPy);
 
139
    return _viewerPy;
 
140
}
 
141
 
 
142
void View3DInventor::setViewerDefaults(void)
 
143
{
 
144
    _viewer->setStereoOffset(hGrp->GetFloat("EyeDistance",65.0));
 
145
    _viewer->setFeedbackVisibility(hGrp->GetBool("CornerCoordSystem",true));
 
146
    _viewer->setAnimationEnabled(hGrp->GetBool("UseAutoRotation",true));
 
147
    _viewer->setGradientBackgroud((hGrp->GetBool("Gradient",true)));
 
148
    unsigned long col1 = hGrp->GetUnsigned("BackgroundColor",0);
 
149
    unsigned long col2 = hGrp->GetUnsigned("BackgroundColor2",2139082239); // default color (purple)
 
150
    unsigned long col3 = hGrp->GetUnsigned("BackgroundColor3",ULONG_MAX); // default color (white)
 
151
    unsigned long col4 = hGrp->GetUnsigned("BackgroundColor4",ULONG_MAX); // default color (white)
 
152
    float r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
 
153
    r1 = ((col1 >> 24) & 0xff) / 255.0; g1 = ((col1 >> 16) & 0xff) / 255.0; b1 = ((col1 >> 8) & 0xff) / 255.0;
 
154
    r2 = ((col2 >> 24) & 0xff) / 255.0; g2 = ((col2 >> 16) & 0xff) / 255.0; b2 = ((col2 >> 8) & 0xff) / 255.0;
 
155
    r3 = ((col3 >> 24) & 0xff) / 255.0; g3 = ((col3 >> 16) & 0xff) / 255.0; b3 = ((col3 >> 8) & 0xff) / 255.0;
 
156
    r4 = ((col4 >> 24) & 0xff) / 255.0; g4 = ((col4 >> 16) & 0xff) / 255.0; b4 = ((col4 >> 8) & 0xff) / 255.0;
 
157
    _viewer->setBackgroundColor(SbColor(r1, g1, b1));
 
158
    if (hGrp->GetBool("UseBackgroundColorMid",false) == false)
 
159
        _viewer->setGradientBackgroudColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3));
 
160
    else
 
161
        _viewer->setGradientBackgroudColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4));
 
162
 
 
163
    if (hGrp->GetBool("UseAntialiasing"  ,false))
 
164
        _viewer->getGLRenderAction()->setSmoothing(true);
 
165
    else
 
166
        _viewer->getGLRenderAction()->setSmoothing(false);
 
167
    _viewer->setEnabledFPSCounter(hGrp->GetBool("ShowFPS",false));
 
168
 
 
169
    // check whether a perspective or orthogrphic camera should be set
 
170
    if (hGrp->GetBool("Orthographic", false))
 
171
        _viewer->setCameraType(SoOrthographicCamera::getClassTypeId());
 
172
    else
 
173
        _viewer->setCameraType(SoPerspectiveCamera::getClassTypeId());
 
174
}
 
175
 
 
176
void View3DInventor::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason)
 
177
{
 
178
    const ParameterGrp& rGrp = static_cast<ParameterGrp&>(rCaller);
 
179
    if (strcmp(Reason,"HeadlightColor") == 0) {
 
180
        unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white)
 
181
        float transparency;
 
182
        SbColor headlightColor;
 
183
        headlightColor.setPackedValue((uint32_t)headlight, transparency);
 
184
        _viewer->getHeadlight()->color.setValue(headlightColor);
 
185
    }
 
186
    else if (strcmp(Reason,"HeadlightDirection") == 0) {
 
187
        std::string pos = rGrp.GetASCII("HeadlightDirection");
 
188
        QString flt = QString::fromAscii("([-+]?[0-9]+\\.?[0-9]+)");
 
189
        QRegExp rx(QString::fromAscii("^\\(%1,%1,%1\\)$").arg(flt));
 
190
        if (rx.indexIn(QLatin1String(pos.c_str())) > -1) {
 
191
            float x = rx.cap(1).toFloat();
 
192
            float y = rx.cap(2).toFloat();
 
193
            float z = rx.cap(3).toFloat();
 
194
            _viewer->getHeadlight()->direction.setValue(x,y,z);
 
195
        }
 
196
    }
 
197
    else if (strcmp(Reason,"HeadlightIntensity") == 0) {
 
198
        long value = rGrp.GetInt("HeadlightIntensity", 100);
 
199
        _viewer->getHeadlight()->intensity.setValue((float)value/100.0f);
 
200
    }
 
201
    else if (strcmp(Reason,"EnableBacklight") == 0) {
 
202
        _viewer->setBacklight(rGrp.GetBool("EnableBacklight", false));
 
203
    }
 
204
    else if (strcmp(Reason,"BacklightColor") == 0) {
 
205
        unsigned long backlight = rGrp.GetUnsigned("BacklightColor",ULONG_MAX); // default color (white)
 
206
        float transparency;
 
207
        SbColor backlightColor;
 
208
        backlightColor.setPackedValue((uint32_t)backlight, transparency);
 
209
        _viewer->getBacklight()->color.setValue(backlightColor);
 
210
    }
 
211
    else if (strcmp(Reason,"BacklightDirection") == 0) {
 
212
        std::string pos = rGrp.GetASCII("BacklightDirection");
 
213
        QString flt = QString::fromAscii("([-+]?[0-9]+\\.?[0-9]+)");
 
214
        QRegExp rx(QString::fromAscii("^\\(%1,%1,%1\\)$").arg(flt));
 
215
        if (rx.indexIn(QLatin1String(pos.c_str())) > -1) {
 
216
            float x = rx.cap(1).toFloat();
 
217
            float y = rx.cap(2).toFloat();
 
218
            float z = rx.cap(3).toFloat();
 
219
            _viewer->getBacklight()->direction.setValue(x,y,z);
 
220
        }
 
221
    }
 
222
    else if (strcmp(Reason,"BacklightIntensity") == 0) {
 
223
        long value = rGrp.GetInt("BacklightIntensity", 100);
 
224
        _viewer->getBacklight()->intensity.setValue((float)value/100.0f);
 
225
    }
 
226
    else if (strcmp(Reason,"EnablePreselection") == 0) {
 
227
        const ParameterGrp& rclGrp = ((ParameterGrp&)rCaller);
 
228
        SoFCEnableHighlightAction cAct(rclGrp.GetBool("EnablePreselection", false));
 
229
        cAct.apply(_viewer->getSceneGraph());
 
230
    }
 
231
    else if (strcmp(Reason,"EnableSelection") == 0) {
 
232
        const ParameterGrp& rclGrp = ((ParameterGrp&)rCaller);
 
233
        SoFCEnableSelectionAction cAct(rclGrp.GetBool("EnableSelection", false));
 
234
        cAct.apply(_viewer->getSceneGraph());
 
235
    }
 
236
    else if (strcmp(Reason,"HighlightColor") == 0) {
 
237
        float transparency;
 
238
        SbColor highlightColor(0.1f, 0.1f, 0.8f);
 
239
        unsigned long highlight = (unsigned long)(highlightColor.getPackedValue());
 
240
        highlight = rGrp.GetUnsigned("HighlightColor", highlight);
 
241
        highlightColor.setPackedValue((uint32_t)highlight, transparency);
 
242
        SoSFColor col; col.setValue(highlightColor);
 
243
        SoFCHighlightColorAction cAct(col);
 
244
        cAct.apply(_viewer->getSceneGraph());
 
245
    }
 
246
    else if (strcmp(Reason,"SelectionColor") == 0) {
 
247
        float transparency;
 
248
        SbColor selectionColor(0.1f, 0.5f, 0.1f);
 
249
        unsigned long selection = (unsigned long)(selectionColor.getPackedValue());
 
250
        selection = rGrp.GetUnsigned("SelectionColor", selection);
 
251
        selectionColor.setPackedValue((uint32_t)selection, transparency);
 
252
        SoSFColor col; col.setValue(selectionColor);
 
253
        SoFCSelectionColorAction cAct(col);
 
254
        cAct.apply(_viewer->getSceneGraph());
 
255
    }
 
256
    else if (strcmp(Reason,"NavigationStyle") == 0) {
 
257
        // check whether the simple or the full mouse model is used
 
258
        std::string model = rGrp.GetASCII("NavigationStyle",CADNavigationStyle::getClassTypeId().getName());
 
259
        Base::Type type = Base::Type::fromName(model.c_str());
 
260
        _viewer->setNavigationType(type);
 
261
    }
 
262
    else {
 
263
        setViewerDefaults();
 
264
    }
 
265
}
 
266
 
 
267
void View3DInventor::onRename(Gui::Document *pDoc)
 
268
{
 
269
    SoSFString name;
 
270
    name.setValue(pDoc->getDocument()->getName());
 
271
    SoFCDocumentAction cAct(name);
 
272
    cAct.apply(_viewer->getSceneGraph());
 
273
}
 
274
 
 
275
void View3DInventor::onUpdate(void)
 
276
{
 
277
#ifdef FC_LOGUPDATECHAIN
 
278
    Base::Console().Log("Acti: Gui::View3DInventor::onUpdate()");
 
279
#endif
 
280
    update();  
 
281
    _viewer->render();
 
282
}
 
283
 
 
284
void View3DInventor::viewAll()
 
285
{
 
286
    _viewer->viewAll();
 
287
}
 
288
 
 
289
const char *View3DInventor::getName(void) const
 
290
{
 
291
    return "View3DInventor";
 
292
}
 
293
 
 
294
// **********************************************************************************
 
295
 
 
296
bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn)
 
297
{
 
298
    if (strcmp("ViewFit",pMsg) == 0 ) {
 
299
        _viewer->viewAll();
 
300
        return true;
 
301
    }
 
302
    else if(strcmp("ViewSelection",pMsg) == 0) {
 
303
        _viewer->viewSelection();
 
304
        return true;
 
305
    // comment out on older Inventor
 
306
#if (SOQT_MAJOR_VERSION >= 1 && SOQT_MINOR_VERSION >= 2)
 
307
    }
 
308
    else if(strcmp("SetStereoRedGreen",pMsg) == 0 ) {
 
309
        _viewer->setStereoType(SoQtViewer::STEREO_ANAGLYPH);
 
310
        return true;
 
311
    }
 
312
    else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ) {
 
313
        _viewer->setStereoType(SoQtViewer::STEREO_QUADBUFFER );
 
314
        return true;
 
315
    }
 
316
    else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ) {
 
317
        _viewer->setStereoType(SoQtViewer::STEREO_INTERLEAVED_ROWS );
 
318
        return true;
 
319
    }
 
320
    else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ) {
 
321
        _viewer->setStereoType(SoQtViewer::STEREO_INTERLEAVED_COLUMNS  );
 
322
        return true;
 
323
    }
 
324
    else if(strcmp("SetStereoOff",pMsg) == 0 ) {
 
325
        _viewer->setStereoType(SoQtViewer::STEREO_NONE );
 
326
        return true;
 
327
#else
 
328
    }
 
329
    else if(strcmp("SetStereoRedGreen",pMsg) == 0 ) {
 
330
        Base::Console().Warning("Use SoQt 1.2.x or later!\n");
 
331
        return true;
 
332
    }
 
333
    else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ) {
 
334
        Base::Console().Warning("Use SoQt 1.2.x or later!\n");
 
335
        return true;
 
336
    }
 
337
    else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ) {
 
338
        Base::Console().Warning("Use SoQt 1.2.x or later!\n");
 
339
        return true;
 
340
    }
 
341
    else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ) {
 
342
        Base::Console().Warning("Use SoQt 1.2.x or later!\n");
 
343
        return true;
 
344
    }
 
345
    else if(strcmp("SetStereoOff",pMsg) == 0 ) {
 
346
        Base::Console().Warning("Use SoQt 1.2.x or later!\n");
 
347
        return true;
 
348
#endif
 
349
    }
 
350
    else if(strcmp("Example1",pMsg) == 0 ) {
 
351
        SoSeparator * root = new SoSeparator;
 
352
        Texture3D(root);
 
353
        _viewer->setSceneGraph(root);
 
354
        return true;
 
355
    }
 
356
    else if(strcmp("Example2",pMsg) == 0 ) {
 
357
        SoSeparator * root = new SoSeparator;
 
358
        LightManip(root);
 
359
        _viewer->setSceneGraph(root);
 
360
        return true;
 
361
    }
 
362
    else if(strcmp("Example3",pMsg) == 0 ) {
 
363
        SoSeparator * root = new SoSeparator;
 
364
        AnimationTexture(root);
 
365
        _viewer->setSceneGraph(root);
 
366
        return true;
 
367
    }
 
368
    else if(strcmp("GetCamera",pMsg) == 0 ) {
 
369
        SoCamera * Cam = _viewer->getCamera();
 
370
        *ppReturn = SoFCDB::writeNodesToString(Cam).c_str();
 
371
        return true;
 
372
    }
 
373
    else if(strncmp("SetCamera",pMsg,9) == 0 ) {
 
374
        return setCamera(pMsg+10);
 
375
    }
 
376
    else if(strncmp("Dump",pMsg,4) == 0 ) {
 
377
        dump(pMsg+5);
 
378
        return true;
 
379
    }
 
380
    else if(strcmp("ViewBottom",pMsg) == 0 ) {
 
381
        _viewer->setCameraOrientation(SbRotation(-1, 0, 0, 0));
 
382
        _viewer->viewAll();
 
383
        return true;
 
384
    }
 
385
    else if(strcmp("ViewFront",pMsg) == 0 ) {
 
386
        float root = (float)(sqrt(2.0)/2.0);
 
387
        _viewer->setCameraOrientation(SbRotation(-root, 0, 0, -root));
 
388
        _viewer->viewAll();
 
389
        return true;
 
390
    }
 
391
    else if(strcmp("ViewLeft",pMsg) == 0 ) {
 
392
        _viewer->setCameraOrientation(SbRotation(0.5, 0.5, 0.5, 0.5));
 
393
        _viewer->viewAll();
 
394
        return true;
 
395
    }
 
396
    else if(strcmp("ViewRear",pMsg) == 0 ) {
 
397
        float root = (float)(sqrt(2.0)/2.0);
 
398
        _viewer->setCameraOrientation(SbRotation(0, root, root, 0));
 
399
        _viewer->viewAll();
 
400
        return true;
 
401
    }
 
402
    else if(strcmp("ViewRight",pMsg) == 0 ) {
 
403
        _viewer->setCameraOrientation(SbRotation(-0.5, 0.5, 0.5, -0.5));
 
404
        _viewer->viewAll();
 
405
        return true;
 
406
    }
 
407
    else if(strcmp("ViewTop",pMsg) == 0 ) {
 
408
        _viewer->setCameraOrientation(SbRotation(0, 0, 0, 1));
 
409
        _viewer->viewAll();
 
410
        return true;
 
411
    }
 
412
    else if(strcmp("ViewAxo",pMsg) == 0 ) {
 
413
        _viewer->setCameraOrientation(SbRotation
 
414
            (-0.353553f, -0.146447f, -0.353553f, 0.853553f));
 
415
        _viewer->viewAll();
 
416
        return true;
 
417
    }
 
418
    else if(strcmp("OrthographicCamera",pMsg) == 0 ) {
 
419
        _viewer->setCameraType(SoOrthographicCamera::getClassTypeId());
 
420
        return true;
 
421
    }
 
422
    else if(strcmp("PerspectiveCamera",pMsg) == 0 ) {
 
423
        _viewer->setCameraType(SoPerspectiveCamera::getClassTypeId());
 
424
        return true;
 
425
    }
 
426
    else  if(strcmp("Undo",pMsg) == 0 ) {
 
427
        getGuiDocument()->undo(1);
 
428
        return true;
 
429
    }
 
430
    else  if(strcmp("Redo",pMsg) == 0 ) {
 
431
        getGuiDocument()->redo(1);
 
432
        return true;
 
433
    }
 
434
    else if (strcmp("Save",pMsg) == 0) {
 
435
        getGuiDocument()->save();
 
436
        return true;
 
437
    }
 
438
    else if (strcmp("SaveAs",pMsg) == 0) {
 
439
        getGuiDocument()->saveAs();
 
440
        return true;
 
441
    }
 
442
    else
 
443
        return false;
 
444
}
 
445
 
 
446
 
 
447
bool View3DInventor::onHasMsg(const char* pMsg) const
 
448
{
 
449
  if(strcmp("Save",pMsg) == 0 ){
 
450
    return true;
 
451
  }else if(strcmp("SaveAs",pMsg) == 0 ){
 
452
    return true;
 
453
  }else if(strcmp("Undo",pMsg) == 0 ){
 
454
    return getAppDocument()->getAvailableUndos() > 0;
 
455
  }else if(strcmp("Redo",pMsg) == 0 ){
 
456
    return getAppDocument()->getAvailableRedos() > 0; 
 
457
  }else if(strcmp("SetStereoRedGreen",pMsg) == 0 ){
 
458
    return true;
 
459
  }else if(strcmp("SetStereoQuadBuff",pMsg) == 0 ){
 
460
    return true;
 
461
  }else if(strcmp("SetStereoInterleavedRows",pMsg) == 0 ){
 
462
    return true;
 
463
  }else if(strcmp("SetStereoInterleavedColumns",pMsg) == 0 ){
 
464
    return true;
 
465
  }else if(strcmp("SetStereoOff",pMsg) == 0 ){
 
466
    return true;
 
467
  }else if(strcmp("Example1",pMsg) == 0 ){
 
468
    return true;
 
469
  }else if(strcmp("Example2",pMsg) == 0 ){
 
470
    return true;
 
471
  }else if(strcmp("Example3",pMsg) == 0 ){
 
472
    return true;
 
473
  }else if(strcmp("ViewFit",pMsg) == 0 ){
 
474
    return true;
 
475
  }else if(strcmp("ViewSelection",pMsg) == 0 ){
 
476
    return true;
 
477
  }else if(strcmp("ViewBottom",pMsg) == 0 ){
 
478
    return true;
 
479
  }else if(strcmp("ViewFront",pMsg) == 0 ){
 
480
    return true;
 
481
  }else if(strcmp("ViewLeft",pMsg) == 0 ){
 
482
    return true;
 
483
  }else if(strcmp("ViewRear",pMsg) == 0 ){
 
484
    return true;
 
485
  }else if(strcmp("ViewRight",pMsg) == 0 ){
 
486
    return true;
 
487
  }else if(strcmp("ViewTop",pMsg) == 0 ){
 
488
    return true;
 
489
  }else if(strcmp("ViewAxo",pMsg) == 0 ){
 
490
    return true;
 
491
  }else if(strcmp("GetCamera",pMsg) == 0 ){
 
492
    return true;
 
493
  }else if(strncmp("SetCamera",pMsg,9) == 0 ){
 
494
    return true;
 
495
  }else if(strncmp("Dump",pMsg,4) == 0 ){
 
496
    return true;
 
497
  }
 
498
  return false;
 
499
}
 
500
 
 
501
bool View3DInventor::setCamera(const char* pCamera)
 
502
{
 
503
    SoCamera * CamViewer = _viewer->getCamera();
 
504
    if (!CamViewer) {
 
505
        throw Base::Exception("No camera set so far...");
 
506
    }
 
507
 
 
508
    SoInput in;
 
509
    in.setBuffer((void*)pCamera,std::strlen(pCamera));
 
510
 
 
511
    SoNode * Cam;
 
512
    SoDB::read(&in,Cam);
 
513
 
 
514
    if (!Cam){
 
515
        throw Base::Exception("Camera settings failed to read");
 
516
    }
 
517
 
 
518
    // toogle between persepective and orthographic camera
 
519
    if (Cam->getTypeId() != CamViewer->getTypeId())
 
520
    {
 
521
        _viewer->setCameraType(Cam->getTypeId());
 
522
        CamViewer = _viewer->getCamera();
 
523
    }
 
524
 
 
525
    SoPerspectiveCamera  * CamViewerP = 0;
 
526
    SoOrthographicCamera * CamViewerO = 0;
 
527
 
 
528
    if (CamViewer->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
 
529
        CamViewerP = (SoPerspectiveCamera *)CamViewer;  // safe downward cast, knows the type
 
530
    } else if (CamViewer->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
 
531
        CamViewerO = (SoOrthographicCamera *)CamViewer;  // safe downward cast, knows the type
 
532
    }
 
533
 
 
534
    if (Cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
 
535
        if (CamViewerP){
 
536
            CamViewerP->position      = ((SoPerspectiveCamera *)Cam)->position;
 
537
            CamViewerP->orientation   = ((SoPerspectiveCamera *)Cam)->orientation;
 
538
            CamViewerP->nearDistance  = ((SoPerspectiveCamera *)Cam)->nearDistance;
 
539
            CamViewerP->farDistance   = ((SoPerspectiveCamera *)Cam)->farDistance;
 
540
            CamViewerP->focalDistance = ((SoPerspectiveCamera *)Cam)->focalDistance;
 
541
        } else {
 
542
            throw Base::Exception("Camera type mismatch");
 
543
        }
 
544
    } else if (Cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
 
545
        if (CamViewerO){
 
546
            CamViewerO->viewportMapping  = ((SoOrthographicCamera *)Cam)->viewportMapping;
 
547
            CamViewerO->position         = ((SoOrthographicCamera *)Cam)->position;
 
548
            CamViewerO->orientation      = ((SoOrthographicCamera *)Cam)->orientation;
 
549
            CamViewerO->nearDistance     = ((SoOrthographicCamera *)Cam)->nearDistance;
 
550
            CamViewerO->farDistance      = ((SoOrthographicCamera *)Cam)->farDistance;
 
551
            CamViewerO->focalDistance    = ((SoOrthographicCamera *)Cam)->focalDistance;
 
552
            CamViewerO->aspectRatio      = ((SoOrthographicCamera *)Cam)->aspectRatio ;
 
553
            CamViewerO->height           = ((SoOrthographicCamera *)Cam)->height;
 
554
        } else {
 
555
            throw Base::Exception("Camera type mismatch");
 
556
        }
 
557
    }
 
558
 
 
559
    return true;
 
560
}
 
561
 
 
562
void View3DInventor::toggleClippingPlane()
 
563
{
 
564
    _viewer->toggleClippingPlane();
 
565
}
 
566
 
 
567
bool View3DInventor::hasClippingPlane() const
 
568
{
 
569
    return _viewer->hasClippingPlane();
 
570
}
 
571
 
 
572
void View3DInventor::setCursor(const QCursor& aCursor)
 
573
{
 
574
    _viewer->getWidget()->setCursor(aCursor);
 
575
}
 
576
 
 
577
void View3DInventor::dump(const char* filename)
 
578
{
 
579
    SoGetPrimitiveCountAction action;
 
580
    action.setCanApproximate(true);
 
581
    action.apply(_viewer->getSceneGraph());
 
582
 
 
583
    if ( action.getTriangleCount() > 100000 || action.getPointCount() > 30000 || action.getLineCount() > 10000 )
 
584
        _viewer->dumpToFile(filename,true);
 
585
    else
 
586
        _viewer->dumpToFile(filename,false);
 
587
}
 
588
 
 
589
void View3DInventor::windowStateChanged(MDIView* view)
 
590
{
 
591
    bool canStartTimer = false;
 
592
    if (this != view) {
 
593
        // If both views are child widgets of the workspace and view is maximized this view 
 
594
        // must be hidden, hence we can start the timer.
 
595
        // Note: If view is top-level or fullscreen it doesn't necessarily hide the other view
 
596
        // e.g. if it is on a second monitor.
 
597
        canStartTimer = (!this->isTopLevel() && !view->isTopLevel() && view->isMaximized());
 
598
    } else if (isMinimized()) {
 
599
        // I am the active view but minimized
 
600
        canStartTimer = true;
 
601
    }
 
602
 
 
603
    if (canStartTimer) {
 
604
        // do a single shot event (maybe insert a checkbox in viewer settings)
 
605
        int msecs = hGrp->GetInt("stopAnimatingIfDeactivated", 3000);
 
606
        if (!stopSpinTimer->isActive() && msecs >= 0) { // if < 0 do not stop rotation
 
607
            stopSpinTimer->setSingleShot(true);
 
608
            stopSpinTimer->start(msecs);
 
609
        }
 
610
    } else if (stopSpinTimer->isActive()) {
 
611
        // If this view may be visible again we can stop the timer
 
612
        stopSpinTimer->stop();
 
613
    }
 
614
}
 
615
 
 
616
void View3DInventor::stopAnimating()
 
617
{
 
618
    _viewer->stopAnimating();
 
619
}
 
620
 
 
621
/**
 
622
 * Drops the event \a e and writes the right Python command.
 
623
 */
 
624
void View3DInventor::dropEvent (QDropEvent * e)
 
625
{
 
626
    const QMimeData* data = e->mimeData();
 
627
    if (data->hasUrls()) {
 
628
        QList<QUrl> uri = data->urls();
 
629
        QStringList files;
 
630
        App::Document* pDoc = getAppDocument();
 
631
        if (pDoc) {
 
632
            for (QList<QUrl>::ConstIterator it = uri.begin(); it != uri.end(); ++it) {
 
633
                QFileInfo info((*it).toLocalFile());
 
634
                if ( info.exists() && info.isFile() ) {
 
635
                    if (info.isSymLink())
 
636
                        info.setFile(info.readLink());
 
637
                    files << info.absoluteFilePath();
 
638
                }
 
639
            }
 
640
 
 
641
            const char *docName = pDoc->getName();
 
642
            SelectModule::Dict dict = SelectModule::importHandler(files);
 
643
            // load the files with the associated modules
 
644
            for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
 
645
                Application::Instance->importFrom(it.key().toUtf8(), docName, it.value().toAscii());
 
646
            }
 
647
        }
 
648
    }
 
649
    else {
 
650
        MDIView::dropEvent(e);
 
651
    }
 
652
}
 
653
 
 
654
void View3DInventor::dragEnterEvent (QDragEnterEvent * e)
 
655
{
 
656
    // Here we must allow uri drafs and check them in dropEvent
 
657
    const QMimeData* data = e->mimeData();
 
658
    if ( data->hasUrls() )
 
659
        e->accept();
 
660
    else
 
661
        e->ignore();
 
662
}
 
663
 
 
664
void View3DInventor::setCurrentViewMode(ViewMode newmode)
 
665
{
 
666
    ViewMode oldmode = MDIView::currentViewMode();
 
667
    MDIView::setCurrentViewMode(newmode);
 
668
 
 
669
    // This widget becomes the focus proxy of the embedded GL widget if we leave 
 
670
    // the 'Child' mode. If we reenter 'Child' mode the focus proxy is reset to 0.
 
671
    // If we change from 'TopLevel' mode to 'Fullscreen' mode or vice versa nothing
 
672
    // happens.
 
673
    // Grabbing keyboard when leaving 'Child' mode (as done in a recent version) should
 
674
    // be avoided because when two or more windows are either in 'TopLevel' or 'Fullscreen'
 
675
    // mode only the last window gets all key event even if it is not the active one.
 
676
    //
 
677
    // It is important to set the focus proxy to get all key events otherwise we would loose
 
678
    // control after redirecting the first key event to the GL widget.
 
679
    // We redirect these events in keyPressEvent() and keyReleaseEvent().
 
680
    if (oldmode == Child) {
 
681
        // To make a global shortcut working from this window we need to add
 
682
        // all existing actions from the mainwindow and its sub-widgets 
 
683
        QList<QAction*> acts = getMainWindow()->findChildren<QAction*>();
 
684
        this->addActions(acts);
 
685
        _viewer->getGLWidget()->setFocusProxy(this);
 
686
        // To be notfified for new actions
 
687
        qApp->installEventFilter(this);
 
688
    } else if (newmode == Child) {
 
689
        _viewer->getGLWidget()->setFocusProxy(0);
 
690
        qApp->removeEventFilter(this);
 
691
        QList<QAction*> acts = this->actions();
 
692
        for (QList<QAction*>::Iterator it = acts.begin(); it != acts.end(); ++it)
 
693
            this->removeAction(*it);
 
694
    }
 
695
}
 
696
 
 
697
bool View3DInventor::eventFilter(QObject* watched, QEvent* e)
 
698
{
 
699
    // As long as this widget is a top-level window (either in 'TopLevel' or 'FullScreen' mode) we
 
700
    // need to be notified when an action is added to a widget. This action must also be added to 
 
701
    // this window to allow to make use of its shortcut (if defined).
 
702
    // Note: We don't need to care about removing an action if its parent widget gets destroyed.
 
703
    // This does the action itself for us.
 
704
    if (watched != this && e->type() == QEvent::ActionAdded) {
 
705
        QActionEvent* a = static_cast<QActionEvent*>(e);
 
706
        QAction* action = a->action();
 
707
 
 
708
        if (!action->isSeparator()) {
 
709
            QList<QAction*> actions = this->actions();
 
710
            if (!actions.contains(action))
 
711
                this->addAction(action);
 
712
        }
 
713
    }
 
714
 
 
715
    return false;
 
716
}
 
717
 
 
718
void View3DInventor::keyPressEvent (QKeyEvent* e)
 
719
{
 
720
    ViewMode mode = MDIView::currentViewMode();
 
721
    if (mode != Child) {
 
722
        // If the widget is in fullscreen mode then we can return to normal mode either
 
723
        // by pressing the matching accelerator or ESC. 
 
724
        if (e->key() == Qt::Key_Escape) {
 
725
            setCurrentViewMode(Child);
 
726
        } else {
 
727
            // Note: The key events should be redirected directly to the GL widget and not to the main window
 
728
            // otherwise the first redirected key event always disappears in hyperspace.
 
729
            //
 
730
            // send the event to the GL widget that converts to and handles an SoEvent
 
731
            QWidget* w = _viewer->getGLWidget();
 
732
            QApplication::sendEvent(w,e);
 
733
        }
 
734
    } else {
 
735
        QMainWindow::keyPressEvent(e);
 
736
    }
 
737
}
 
738
 
 
739
void View3DInventor::keyReleaseEvent (QKeyEvent* e)
 
740
{
 
741
    ViewMode mode = MDIView::currentViewMode();
 
742
    if (mode != Child) {
 
743
        // send the event to the GL widget that converts to and handles an SoEvent
 
744
        QWidget* w = _viewer->getGLWidget();
 
745
        QApplication::sendEvent(w,e);
 
746
    } else {
 
747
        QMainWindow::keyReleaseEvent(e);
 
748
    }
 
749
}
 
750
 
 
751
void View3DInventor::focusInEvent (QFocusEvent * e)
 
752
{
 
753
    _viewer->getGLWidget()->setFocus();
 
754
}
 
755
 
 
756
#include "moc_View3DInventor.cpp"