FreeCAD

Форк
0
/
Clipping.cpp 
399 строк · 12.6 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2013 Werner Mayer <wmayer[at]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
# include <Inventor/actions/SoGetBoundingBoxAction.h>
27
# include <Inventor/nodes/SoClipPlane.h>
28
# include <Inventor/nodes/SoGroup.h>
29
# include <Inventor/sensors/SoTimerSensor.h>
30
# include <QDockWidget>
31
# include <QPointer>
32
#endif
33

34
#include "Clipping.h"
35
#include "ui_Clipping.h"
36
#include "DockWindowManager.h"
37
#include "View3DInventor.h"
38
#include "View3DInventorViewer.h"
39

40
using namespace Gui::Dialog;
41

42
class Clipping::Private {
43
public:
44
    Ui_Clipping ui;
45
    QPointer<Gui::View3DInventor> view;
46
    SoGroup* node;
47
    SoClipPlane* clipX;
48
    SoClipPlane* clipY;
49
    SoClipPlane* clipZ;
50
    SoClipPlane* clipView;
51
    bool flipX{false};
52
    bool flipY{false};
53
    bool flipZ{false};
54
    SoTimerSensor* sensor;
55
    Private()
56
    {
57
        clipX = new SoClipPlane();
58
        clipX->on.setValue(false);
59
        clipX->plane.setValue(SbPlane(SbVec3f(1,0,0),0));
60
        clipX->ref();
61

62
        clipY = new SoClipPlane();
63
        clipY->on.setValue(false);
64
        clipY->plane.setValue(SbPlane(SbVec3f(0,1,0),0));
65
        clipY->ref();
66

67
        clipZ = new SoClipPlane();
68
        clipZ->on.setValue(false);
69
        clipZ->plane.setValue(SbPlane(SbVec3f(0,0,1),0));
70
        clipZ->ref();
71

72
        clipView = new SoClipPlane();
73
        clipView->on.setValue(false);
74
        clipView->plane.setValue(SbPlane(SbVec3f(0,0,1),0));
75
        clipView->ref();
76

77
        node = nullptr;
78
        sensor = new SoTimerSensor(moveCallback, this);
79
    }
80
    ~Private()
81
    {
82
        clipX->unref();
83
        clipY->unref();
84
        clipZ->unref();
85
        clipView->unref();
86
        delete sensor;
87
    }
88
    static void moveCallback(void * data, SoSensor * sensor)
89
    {
90
        Q_UNUSED(sensor);
91
        auto self = static_cast<Private*>(data);
92
        if (self->view) {
93
            Gui::View3DInventorViewer* view = self->view->getViewer();
94
            SoClipPlane* clip = self->clipView;
95
            SbPlane pln = clip->plane.getValue();
96
            clip->plane.setValue(SbPlane(view->getViewDirection(),pln.getDistanceFromOrigin()));
97
        }
98
    }
99
};
100

101
/* TRANSLATOR Gui::Dialog::Clipping */
102

103
Clipping::Clipping(Gui::View3DInventor* view, QWidget* parent)
104
  : QDialog(parent)
105
  , d(new Private)
106
{
107
    // create widgets
108
    d->ui.setupUi(this);
109
    setupConnections();
110

111
    d->ui.clipView->setRange(-INT_MAX,INT_MAX);
112
    d->ui.clipView->setSingleStep(0.1f);
113
    d->ui.clipX->setRange(-INT_MAX,INT_MAX);
114
    d->ui.clipX->setSingleStep(0.1f);
115
    d->ui.clipY->setRange(-INT_MAX,INT_MAX);
116
    d->ui.clipY->setSingleStep(0.1f);
117
    d->ui.clipZ->setRange(-INT_MAX,INT_MAX);
118
    d->ui.clipZ->setSingleStep(0.1f);
119

120
    d->ui.dirX->setRange(-INT_MAX,INT_MAX);
121
    d->ui.dirX->setSingleStep(0.1f);
122
    d->ui.dirY->setRange(-INT_MAX,INT_MAX);
123
    d->ui.dirY->setSingleStep(0.1f);
124
    d->ui.dirZ->setRange(-INT_MAX,INT_MAX);
125
    d->ui.dirZ->setSingleStep(0.1f);
126
    d->ui.dirZ->setValue(1.0f);
127

128
    d->view = view;
129
    View3DInventorViewer* viewer = view->getViewer();
130
    d->node = static_cast<SoGroup*>(viewer->getSceneGraph());
131
    d->node->ref();
132
    d->node->insertChild(d->clipX, 0);
133
    d->node->insertChild(d->clipY, 0);
134
    d->node->insertChild(d->clipZ, 0);
135
    d->node->insertChild(d->clipView, 0);
136

137
    SoGetBoundingBoxAction action(viewer->getSoRenderManager()->getViewportRegion());
138
    action.apply(viewer->getSceneGraph());
139
    SbBox3f box = action.getBoundingBox();
140

141
    if (!box.isEmpty()) {
142
        SbVec3f cnt = box.getCenter();
143
        d->ui.clipView->setValue(cnt[2]);
144
        d->ui.clipX->setValue(cnt[0]);
145
        d->ui.clipY->setValue(cnt[1]);
146
        d->ui.clipZ->setValue(cnt[2]);
147

148
        int minDecimals = 2;
149
        float lenx, leny,lenz;
150
        box.getSize(lenx, leny, lenz);
151
        int steps = 100;
152
        float minlen = std::min<float>(lenx, std::min<float>(leny, lenz));
153

154
        // determine the single step values
155
        {
156
            minlen = minlen / steps;
157
            int dim = static_cast<int>(log10(minlen));
158
            double singleStep = pow(10.0, dim);
159
            d->ui.clipView->setSingleStep(singleStep);
160
            minDecimals = std::max(minDecimals, -dim);
161
        }
162
        {
163
            lenx = lenx / steps;
164
            int dim = static_cast<int>(log10(lenx));
165
            double singleStep = pow(10.0, dim);
166
            d->ui.clipX->setSingleStep(singleStep);
167
        }
168
        {
169
            leny = leny / steps;
170
            int dim = static_cast<int>(log10(leny));
171
            double singleStep = pow(10.0, dim);
172
            d->ui.clipY->setSingleStep(singleStep);
173
        }
174
        {
175
            lenz = lenz / steps;
176
            int dim = static_cast<int>(log10(lenz));
177
            double singleStep = pow(10.0, dim);
178
            d->ui.clipZ->setSingleStep(singleStep);
179
        }
180

181
        // set decimals
182
        d->ui.clipView->setDecimals(minDecimals);
183
        d->ui.clipX->setDecimals(minDecimals);
184
        d->ui.clipY->setDecimals(minDecimals);
185
        d->ui.clipZ->setDecimals(minDecimals);
186
    }
187
}
188

189
Clipping* Clipping::makeDockWidget(Gui::View3DInventor* view)
190
{
191
    // embed this dialog into a QDockWidget
192
    auto clipping = new Clipping(view);
193
    Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
194
    QDockWidget* dw = pDockMgr->addDockWindow("Clipping", clipping, Qt::LeftDockWidgetArea);
195
    dw->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable);
196
    dw->show();
197

198
    return clipping;
199
}
200

201
/** Destroys the object and frees any allocated resources */
202
Clipping::~Clipping()
203
{
204
    d->node->removeChild(d->clipX);
205
    d->node->removeChild(d->clipY);
206
    d->node->removeChild(d->clipZ);
207
    d->node->removeChild(d->clipView);
208
    d->node->unref();
209
    delete d;
210
}
211

212
void Clipping::setupConnections()
213
{
214
    connect(d->ui.groupBoxX, &QGroupBox::toggled,
215
            this, &Clipping::onGroupBoxXToggled);
216
    connect(d->ui.groupBoxY, &QGroupBox::toggled,
217
            this, &Clipping::onGroupBoxYToggled);
218
    connect(d->ui.groupBoxZ, &QGroupBox::toggled,
219
            this, &Clipping::onGroupBoxZToggled);
220
    connect(d->ui.clipX, qOverload<double>(&QDoubleSpinBox::valueChanged),
221
            this, &Clipping::onClipXValueChanged);
222
    connect(d->ui.clipY, qOverload<double>(&QDoubleSpinBox::valueChanged),
223
            this, &Clipping::onClipYValueChanged);
224
    connect(d->ui.clipZ, qOverload<double>(&QDoubleSpinBox::valueChanged),
225
            this, &Clipping::onClipZValueChanged);
226
    connect(d->ui.flipClipX, &QPushButton::clicked,
227
            this, &Clipping::onFlipClipXClicked);
228
    connect(d->ui.flipClipY, &QPushButton::clicked,
229
            this, &Clipping::onFlipClipYClicked);
230
    connect(d->ui.flipClipZ, &QPushButton::clicked,
231
            this, &Clipping::onFlipClipZClicked);
232
    connect(d->ui.groupBoxView, &QGroupBox::toggled,
233
            this, &Clipping::onGroupBoxViewToggled);
234
    connect(d->ui.clipView, qOverload<double>(&QDoubleSpinBox::valueChanged),
235
            this, &Clipping::onClipViewValueChanged);
236
    connect(d->ui.fromView, &QPushButton::clicked,
237
            this, &Clipping::onFromViewClicked);
238
    connect(d->ui.adjustViewdirection, &QCheckBox::toggled,
239
            this, &Clipping::onAdjustViewdirectionToggled);
240
    connect(d->ui.dirX, qOverload<double>(&QDoubleSpinBox::valueChanged),
241
            this, &Clipping::onDirXValueChanged);
242
    connect(d->ui.dirY, qOverload<double>(&QDoubleSpinBox::valueChanged),
243
            this, &Clipping::onDirYValueChanged);
244
    connect(d->ui.dirZ, qOverload<double>(&QDoubleSpinBox::valueChanged),
245
            this, &Clipping::onDirZValueChanged);
246
}
247

248
void Clipping::reject()
249
{
250
    QDialog::reject();
251
    auto dw = qobject_cast<QDockWidget*>(parent());
252
    if (dw) {
253
        dw->deleteLater();
254
    }
255
}
256

257
void Clipping::onGroupBoxXToggled(bool on)
258
{
259
    if (on) {
260
        d->ui.groupBoxView->setChecked(false);
261
    }
262

263
    d->clipX->on.setValue(on);
264
}
265

266
void Clipping::onGroupBoxYToggled(bool on)
267
{
268
    if (on) {
269
        d->ui.groupBoxView->setChecked(false);
270
    }
271

272
    d->clipY->on.setValue(on);
273
}
274

275
void Clipping::onGroupBoxZToggled(bool on)
276
{
277
    if (on) {
278
        d->ui.groupBoxView->setChecked(false);
279
    }
280

281
    d->clipZ->on.setValue(on);
282
}
283

284
void Clipping::onClipXValueChanged(double val)
285
{
286
    SbPlane pln = d->clipX->plane.getValue();
287
    d->clipX->plane.setValue(SbPlane(pln.getNormal(),d->flipX ? -val : val));
288
}
289

290
void Clipping::onClipYValueChanged(double val)
291
{
292
    SbPlane pln = d->clipY->plane.getValue();
293
    d->clipY->plane.setValue(SbPlane(pln.getNormal(),d->flipY ? -val : val));
294
}
295

296
void Clipping::onClipZValueChanged(double val)
297
{
298
    SbPlane pln = d->clipZ->plane.getValue();
299
    d->clipZ->plane.setValue(SbPlane(pln.getNormal(),d->flipZ ? -val : val));
300
}
301

302
void Clipping::onFlipClipXClicked()
303
{
304
    d->flipX = !d->flipX;
305
    SbPlane pln = d->clipX->plane.getValue();
306
    d->clipX->plane.setValue(SbPlane(-pln.getNormal(),-pln.getDistanceFromOrigin()));
307
}
308

309
void Clipping::onFlipClipYClicked()
310
{
311
    d->flipY = !d->flipY;
312
    SbPlane pln = d->clipY->plane.getValue();
313
    d->clipY->plane.setValue(SbPlane(-pln.getNormal(),-pln.getDistanceFromOrigin()));
314
}
315

316
void Clipping::onFlipClipZClicked()
317
{
318
    d->flipZ = !d->flipZ;
319
    SbPlane pln = d->clipZ->plane.getValue();
320
    d->clipZ->plane.setValue(SbPlane(-pln.getNormal(),-pln.getDistanceFromOrigin()));
321
}
322

323
void Clipping::onGroupBoxViewToggled(bool on)
324
{
325
    if (on) {
326
        d->ui.groupBoxX->setChecked(false);
327
        d->ui.groupBoxY->setChecked(false);
328
        d->ui.groupBoxZ->setChecked(false);
329
    }
330

331
    d->clipView->on.setValue(on);
332
}
333

334
void Clipping::onClipViewValueChanged(double val)
335
{
336
    SbPlane pln = d->clipView->plane.getValue();
337
    d->clipView->plane.setValue(SbPlane(pln.getNormal(),val));
338
}
339

340
void Clipping::onFromViewClicked()
341
{
342
    if (d->view) {
343
        Gui::View3DInventorViewer* view = d->view->getViewer();
344
        SbVec3f dir = view->getViewDirection();
345
        SbPlane pln = d->clipView->plane.getValue();
346
        d->clipView->plane.setValue(SbPlane(dir,pln.getDistanceFromOrigin()));
347
    }
348
}
349

350
void Clipping::onAdjustViewdirectionToggled(bool on)
351
{
352
    d->ui.dirX->setDisabled(on);
353
    d->ui.dirY->setDisabled(on);
354
    d->ui.dirZ->setDisabled(on);
355
    d->ui.fromView->setDisabled(on);
356

357
    if (on)
358
        d->sensor->schedule();
359
    else
360
        d->sensor->unschedule();
361
}
362

363
void Clipping::onDirXValueChanged(double)
364
{
365
    double x = d->ui.dirX->value();
366
    double y = d->ui.dirY->value();
367
    double z = d->ui.dirZ->value();
368

369
    SbPlane pln = d->clipView->plane.getValue();
370
    SbVec3f normal(x,y,z);
371
    if (normal.sqrLength() > 0.0f)
372
        d->clipView->plane.setValue(SbPlane(normal,pln.getDistanceFromOrigin()));
373
}
374

375
void Clipping::onDirYValueChanged(double)
376
{
377
    double x = d->ui.dirX->value();
378
    double y = d->ui.dirY->value();
379
    double z = d->ui.dirZ->value();
380

381
    SbPlane pln = d->clipView->plane.getValue();
382
    SbVec3f normal(x,y,z);
383
    if (normal.sqrLength() > 0.0f)
384
        d->clipView->plane.setValue(SbPlane(normal,pln.getDistanceFromOrigin()));
385
}
386

387
void Clipping::onDirZValueChanged(double)
388
{
389
    double x = d->ui.dirX->value();
390
    double y = d->ui.dirY->value();
391
    double z = d->ui.dirZ->value();
392

393
    SbPlane pln = d->clipView->plane.getValue();
394
    SbVec3f normal(x,y,z);
395
    if (normal.sqrLength() > 0.0f)
396
        d->clipView->plane.setValue(SbPlane(normal,pln.getDistanceFromOrigin()));
397
}
398

399
#include "moc_Clipping.cpp"
400

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

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

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

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