1
/***************************************************************************
2
* Copyright (c) 2023 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
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. *
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. *
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 *
21
***************************************************************************/
23
#include "PreCompiled.h"
26
# include <Inventor/fields/SoSFColor.h>
27
# include <Inventor/nodes/SoDirectionalLight.h>
28
# include <Inventor/nodes/SoOrthographicCamera.h>
29
# include <Inventor/nodes/SoPerspectiveCamera.h>
32
#include <Base/Builder3D.h>
36
#include "NavigationStyle.h"
37
#include "SoFCSelectionAction.h"
38
#include "View3DSettings.h"
39
#include "View3DInventorViewer.h"
43
View3DSettings::View3DSettings(ParameterGrp::handle hGrp,
44
View3DInventorViewer* view)
51
View3DSettings::View3DSettings(ParameterGrp::handle hGrp,
52
const std::vector<View3DInventorViewer *>& view)
59
View3DSettings::~View3DSettings()
64
int View3DSettings::stopAnimatingIfDeactivated() const
66
long defaultTimeout = 3000;
67
return hGrp->GetInt("stopAnimatingIfDeactivated", defaultTimeout);
70
void View3DSettings::applySettings()
72
// apply the user settings
73
OnChange(*hGrp,"EyeDistance");
74
OnChange(*hGrp,"CornerCoordSystem");
75
OnChange(*hGrp,"CornerCoordSystemSize");
76
OnChange(*hGrp,"AxisLetterColor");
77
OnChange(*hGrp,"ShowAxisCross");
78
OnChange(*hGrp,"UseNavigationAnimations");
79
OnChange(*hGrp,"UseSpinningAnimations");
80
OnChange(*hGrp,"Gradient");
81
OnChange(*hGrp,"RadialGradient");
82
OnChange(*hGrp,"BackgroundColor");
83
OnChange(*hGrp,"BackgroundColor2");
84
OnChange(*hGrp,"BackgroundColor3");
85
OnChange(*hGrp,"BackgroundColor4");
86
OnChange(*hGrp,"UseBackgroundColorMid");
87
OnChange(*hGrp,"ShowFPS");
88
OnChange(*hGrp,"ShowNaviCube");
89
OnChange(*hGrp,"UseVBO");
90
OnChange(*hGrp,"RenderCache");
91
OnChange(*hGrp,"Orthographic");
92
OnChange(*hGrp,"EnableHeadlight");
93
OnChange(*hGrp,"HeadlightColor");
94
OnChange(*hGrp,"HeadlightDirection");
95
OnChange(*hGrp,"HeadlightIntensity");
96
OnChange(*hGrp,"EnableBacklight");
97
OnChange(*hGrp,"BacklightColor");
98
OnChange(*hGrp,"BacklightDirection");
99
OnChange(*hGrp,"BacklightIntensity");
100
OnChange(*hGrp,"NavigationStyle");
101
OnChange(*hGrp,"OrbitStyle");
102
OnChange(*hGrp,"Sensitivity");
103
OnChange(*hGrp,"ResetCursorPosition");
104
OnChange(*hGrp,"DimensionsVisible");
105
OnChange(*hGrp,"Dimensions3dVisible");
106
OnChange(*hGrp,"DimensionsDeltaVisible");
107
OnChange(*hGrp,"PickRadius");
108
OnChange(*hGrp,"TransparentObjectRenderType");
111
void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason)
113
const ParameterGrp& rGrp = static_cast<ParameterGrp&>(rCaller);
114
if (strcmp(Reason,"EnableHeadlight") == 0) {
115
bool enable = rGrp.GetBool("EnableHeadlight", true);
116
for (auto _viewer : _viewers) {
117
_viewer->setHeadlightEnabled(enable);
120
else if (strcmp(Reason,"HeadlightColor") == 0) {
121
unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white)
123
SbColor headlightColor;
124
headlightColor.setPackedValue((uint32_t)headlight, transparency);
125
for (auto _viewer : _viewers) {
126
_viewer->getHeadlight()->color.setValue(headlightColor);
129
else if (strcmp(Reason,"HeadlightDirection") == 0) {
131
std::string pos = rGrp.GetASCII("HeadlightDirection");
132
Base::Vector3f dir = Base::to_vector(pos);
133
for (auto _viewer : _viewers) {
134
_viewer->getHeadlight()->direction.setValue(dir.x, dir.y, dir.z);
137
catch (const std::exception&) {
141
else if (strcmp(Reason,"HeadlightIntensity") == 0) {
142
long value = rGrp.GetInt("HeadlightIntensity", 100);
143
for (auto _viewer : _viewers) {
144
_viewer->getHeadlight()->intensity.setValue((float)value/100.0f);
147
else if (strcmp(Reason,"EnableBacklight") == 0) {
148
for (auto _viewer : _viewers) {
149
_viewer->setBacklightEnabled(rGrp.GetBool("EnableBacklight", false));
152
else if (strcmp(Reason,"BacklightColor") == 0) {
153
unsigned long backlight = rGrp.GetUnsigned("BacklightColor",ULONG_MAX); // default color (white)
155
SbColor backlightColor;
156
backlightColor.setPackedValue((uint32_t)backlight, transparency);
157
for (auto _viewer : _viewers) {
158
_viewer->getBacklight()->color.setValue(backlightColor);
161
else if (strcmp(Reason,"BacklightDirection") == 0) {
163
std::string pos = rGrp.GetASCII("BacklightDirection");
164
Base::Vector3f dir = Base::to_vector(pos);
165
for (auto _viewer : _viewers) {
166
_viewer->getBacklight()->direction.setValue(dir.x, dir.y, dir.z);
169
catch (const std::exception&) {
173
else if (strcmp(Reason,"BacklightIntensity") == 0) {
174
long value = rGrp.GetInt("BacklightIntensity", 100);
175
for (auto _viewer : _viewers) {
176
_viewer->getBacklight()->intensity.setValue((float)value/100.0f);
179
else if (strcmp(Reason,"EnablePreselection") == 0) {
180
const ParameterGrp& rclGrp = ((ParameterGrp&)rCaller);
181
SoFCEnableHighlightAction cAct(rclGrp.GetBool("EnablePreselection", true));
182
for (auto _viewer : _viewers) {
183
cAct.apply(_viewer->getSceneGraph());
186
else if (strcmp(Reason,"EnableSelection") == 0) {
187
const ParameterGrp& rclGrp = ((ParameterGrp&)rCaller);
188
SoFCEnableSelectionAction cAct(rclGrp.GetBool("EnableSelection", true));
189
for (auto _viewer : _viewers) {
190
cAct.apply(_viewer->getSceneGraph());
193
else if (strcmp(Reason,"HighlightColor") == 0) {
195
SbColor highlightColor(0.8f, 0.1f, 0.1f);
196
auto highlight = (unsigned long)(highlightColor.getPackedValue());
197
highlight = rGrp.GetUnsigned("HighlightColor", highlight);
198
highlightColor.setPackedValue((uint32_t)highlight, transparency);
199
SoSFColor col; col.setValue(highlightColor);
200
SoFCHighlightColorAction cAct(col);
201
for (auto _viewer : _viewers) {
202
cAct.apply(_viewer->getSceneGraph());
205
else if (strcmp(Reason,"SelectionColor") == 0) {
207
SbColor selectionColor(0.1f, 0.8f, 0.1f);
208
auto selection = (unsigned long)(selectionColor.getPackedValue());
209
selection = rGrp.GetUnsigned("SelectionColor", selection);
210
selectionColor.setPackedValue((uint32_t)selection, transparency);
211
SoSFColor col; col.setValue(selectionColor);
212
SoFCSelectionColorAction cAct(col);
213
for (auto _viewer : _viewers) {
214
cAct.apply(_viewer->getSceneGraph());
217
else if (strcmp(Reason,"NavigationStyle") == 0) {
218
if (!ignoreNavigationStyle) {
219
// check whether the simple or the full mouse model is used
220
std::string model = rGrp.GetASCII("NavigationStyle",CADNavigationStyle::getClassTypeId().getName());
221
Base::Type type = Base::Type::fromName(model.c_str());
222
for (auto _viewer : _viewers) {
223
_viewer->setNavigationType(type);
227
else if (strcmp(Reason,"OrbitStyle") == 0) {
228
int style = rGrp.GetInt("OrbitStyle",1);
229
for (auto _viewer : _viewers) {
230
_viewer->navigationStyle()->setOrbitStyle(NavigationStyle::OrbitStyle(style));
233
else if (strcmp(Reason,"Sensitivity") == 0) {
234
float val = rGrp.GetFloat("Sensitivity",2.0f);
235
for (auto _viewer : _viewers) {
236
_viewer->navigationStyle()->setSensitivity(val);
239
else if (strcmp(Reason,"ResetCursorPosition") == 0) {
240
bool on = rGrp.GetBool("ResetCursorPosition",false);
241
for (auto _viewer : _viewers) {
242
_viewer->navigationStyle()->setResetCursorPosition(on);
245
else if (strcmp(Reason,"InvertZoom") == 0) {
246
bool on = rGrp.GetBool("InvertZoom", true);
247
for (auto _viewer : _viewers) {
248
_viewer->navigationStyle()->setZoomInverted(on);
251
else if (strcmp(Reason,"ZoomAtCursor") == 0) {
252
bool on = rGrp.GetBool("ZoomAtCursor", true);
253
for (auto _viewer : _viewers) {
254
_viewer->navigationStyle()->setZoomAtCursor(on);
257
else if (strcmp(Reason,"ZoomStep") == 0) {
258
float val = rGrp.GetFloat("ZoomStep", 0.0f);
259
for (auto _viewer : _viewers) {
260
_viewer->navigationStyle()->setZoomStep(val);
263
else if (strcmp(Reason,"RotationMode") == 0) {
264
long mode = rGrp.GetInt("RotationMode", 1);
265
for (auto _viewer : _viewers) {
267
_viewer->navigationStyle()->setRotationCenterMode(NavigationStyle::RotationCenterMode::WindowCenter);
269
else if (mode == 1) {
270
_viewer->navigationStyle()->setRotationCenterMode(NavigationStyle::RotationCenterMode::ScenePointAtCursor |
271
NavigationStyle::RotationCenterMode::FocalPointAtCursor);
273
else if (mode == 2) {
274
_viewer->navigationStyle()->setRotationCenterMode(NavigationStyle::RotationCenterMode::ScenePointAtCursor |
275
NavigationStyle::RotationCenterMode::BoundingBoxCenter);
279
else if (strcmp(Reason,"EyeDistance") == 0) {
280
for (auto _viewer : _viewers) {
281
_viewer->getSoRenderManager()->setStereoOffset(rGrp.GetFloat("EyeDistance", 5.0));
284
else if (strcmp(Reason,"CornerCoordSystem") == 0) {
285
for (auto _viewer : _viewers) {
286
_viewer->setFeedbackVisibility(rGrp.GetBool("CornerCoordSystem", true));
289
else if (strcmp(Reason,"CornerCoordSystemSize") == 0) {
290
for (auto _viewer : _viewers) {
291
_viewer->setFeedbackSize(rGrp.GetInt("CornerCoordSystemSize", 10));
294
else if (strcmp(Reason,"AxisLetterColor") == 0) {
295
unsigned long backlight = rGrp.GetUnsigned("AxisLetterColor", 0x00000000); // default color (black)
298
color.setPackedValue((uint32_t)backlight, transparency);
299
for (auto _viewer : _viewers) {
300
_viewer->setAxisLetterColor(color);
303
else if (strcmp(Reason,"ShowAxisCross") == 0) {
304
for (auto _viewer : _viewers) {
305
_viewer->setAxisCross(rGrp.GetBool("ShowAxisCross", false));
308
else if (strcmp(Reason,"UseNavigationAnimations") == 0) {
309
for (auto _viewer : _viewers) {
310
_viewer->setAnimationEnabled(rGrp.GetBool("UseNavigationAnimations", true));
313
else if (strcmp(Reason,"UseSpinningAnimations") == 0) {
314
for (auto _viewer : _viewers) {
315
_viewer->setSpinningAnimationEnabled(rGrp.GetBool("UseSpinningAnimations", false));
318
else if (strcmp(Reason,"Gradient") == 0 || strcmp(Reason,"RadialGradient") == 0) {
319
View3DInventorViewer::Background background = View3DInventorViewer::Background::NoGradient;
320
if (rGrp.GetBool("Gradient", true)) {
321
background = View3DInventorViewer::Background::LinearGradient;
323
else if (rGrp.GetBool("RadialGradient", false)) {
324
background = View3DInventorViewer::Background::RadialGradient;
326
for (auto _viewer : _viewers) {
327
_viewer->setGradientBackground(background);
330
else if (strcmp(Reason,"ShowFPS") == 0) {
331
for (auto _viewer : _viewers) {
332
_viewer->setEnabledFPSCounter(rGrp.GetBool("ShowFPS", false));
335
else if (strcmp(Reason,"ShowNaviCube") == 0) {
336
for (auto _viewer : _viewers) {
337
_viewer->setEnabledNaviCube(rGrp.GetBool("ShowNaviCube", true));
340
else if (strcmp(Reason,"UseVBO") == 0) {
342
for (auto _viewer : _viewers) {
343
_viewer->setEnabledVBO(rGrp.GetBool("UseVBO", false));
347
else if (strcmp(Reason,"RenderCache") == 0) {
348
if (!ignoreRenderCache) {
349
for (auto _viewer : _viewers) {
350
_viewer->setRenderCache(rGrp.GetInt("RenderCache", 0));
354
else if (strcmp(Reason,"Orthographic") == 0) {
355
// check whether a perspective or orthogrphic camera should be set
356
if (rGrp.GetBool("Orthographic", true)) {
357
for (auto _viewer : _viewers) {
358
_viewer->setCameraType(SoOrthographicCamera::getClassTypeId());
362
for (auto _viewer : _viewers) {
363
_viewer->setCameraType(SoPerspectiveCamera::getClassTypeId());
367
else if (strcmp(Reason, "DimensionsVisible") == 0) {
368
if (!ignoreDimensions) {
369
if (rGrp.GetBool("DimensionsVisible", true)) {
370
for (auto _viewer : _viewers) {
371
_viewer->turnAllDimensionsOn();
375
for (auto _viewer : _viewers) {
376
_viewer->turnAllDimensionsOff();
381
else if (strcmp(Reason, "Dimensions3dVisible") == 0) {
382
if (!ignoreDimensions) {
383
if (rGrp.GetBool("Dimensions3dVisible", true)) {
384
for (auto _viewer : _viewers) {
385
_viewer->turn3dDimensionsOn();
389
for (auto _viewer : _viewers) {
390
_viewer->turn3dDimensionsOff();
395
else if (strcmp(Reason, "DimensionsDeltaVisible") == 0) {
396
if (!ignoreDimensions) {
397
if (rGrp.GetBool("DimensionsDeltaVisible", true)) {
398
for (auto _viewer : _viewers) {
399
_viewer->turnDeltaDimensionsOn();
403
for (auto _viewer : _viewers) {
404
_viewer->turnDeltaDimensionsOff();
409
else if (strcmp(Reason, "PickRadius") == 0) {
410
for (auto _viewer : _viewers) {
411
_viewer->setPickRadius(rGrp.GetFloat("PickRadius", 5.0f));
414
else if (strcmp(Reason, "TransparentObjectRenderType") == 0) {
415
if (!ignoreTransparent) {
416
long renderType = rGrp.GetInt("TransparentObjectRenderType", 0);
417
if (renderType == 0) {
418
for (auto _viewer : _viewers) {
419
_viewer->getSoRenderManager()->getGLRenderAction()
420
->setTransparentDelayedObjectRenderType(SoGLRenderAction::ONE_PASS);
423
else if (renderType == 1) {
424
for (auto _viewer : _viewers) {
425
_viewer->getSoRenderManager()->getGLRenderAction()
426
->setTransparentDelayedObjectRenderType(SoGLRenderAction::
427
NONSOLID_SEPARATE_BACKFACE_PASS);
433
unsigned long col1 = rGrp.GetUnsigned("BackgroundColor",3940932863UL);
434
unsigned long col2 = rGrp.GetUnsigned("BackgroundColor2",859006463UL); // default color (dark blue)
435
unsigned long col3 = rGrp.GetUnsigned("BackgroundColor3",2880160255UL); // default color (blue/grey)
436
unsigned long col4 = rGrp.GetUnsigned("BackgroundColor4",1869583359UL); // default color (blue/grey)
437
float r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
438
r1 = ((col1 >> 24) & 0xff) / 255.0; g1 = ((col1 >> 16) & 0xff) / 255.0; b1 = ((col1 >> 8) & 0xff) / 255.0;
439
r2 = ((col2 >> 24) & 0xff) / 255.0; g2 = ((col2 >> 16) & 0xff) / 255.0; b2 = ((col2 >> 8) & 0xff) / 255.0;
440
r3 = ((col3 >> 24) & 0xff) / 255.0; g3 = ((col3 >> 16) & 0xff) / 255.0; b3 = ((col3 >> 8) & 0xff) / 255.0;
441
r4 = ((col4 >> 24) & 0xff) / 255.0; g4 = ((col4 >> 16) & 0xff) / 255.0; b4 = ((col4 >> 8) & 0xff) / 255.0;
442
for (auto _viewer : _viewers) {
443
_viewer->setBackgroundColor(QColor::fromRgbF(r1, g1, b1));
444
if (!rGrp.GetBool("UseBackgroundColorMid",false)) {
445
_viewer->setGradientBackgroundColor(SbColor(r2, g2, b2),
446
SbColor(r3, g3, b3));
449
_viewer->setGradientBackgroundColor(SbColor(r2, g2, b2),
451
SbColor(r4, g4, b4));
457
// ----------------------------------------------------------------------------
459
NaviCubeSettings::NaviCubeSettings(ParameterGrp::handle hGrp,
460
View3DInventorViewer* view)
464
connectParameterChanged = hGrp->Manager()->signalParamChanged.connect(
465
[this](ParameterGrp*, ParameterGrp::ParamType, const char *Name, const char *) {
466
parameterChanged(Name);
470
NaviCubeSettings::~NaviCubeSettings()
472
connectParameterChanged.disconnect();
475
void NaviCubeSettings::applySettings()
477
parameterChanged("BaseColor");
478
parameterChanged("EmphaseColor");
479
parameterChanged("HiliteColor");
480
parameterChanged("CornerNaviCube");
481
parameterChanged("OffsetX"); // Updates OffsetY too
482
parameterChanged("CubeSize");
483
parameterChanged("ChamferSize");
484
parameterChanged("NaviRotateToNearest");
485
parameterChanged("NaviStepByTurn");
486
parameterChanged("BorderWidth");
487
parameterChanged("FontZoom");
488
parameterChanged("FontString");
489
parameterChanged("FontWeight");
490
parameterChanged("FontStretch");
491
parameterChanged("ShowCS");
492
parameterChanged("InactiveOpacity");
493
parameterChanged("TextFront"); // Updates all labels
496
void NaviCubeSettings::parameterChanged(const char* Name)
500
NaviCube* nc = _viewer->getNaviCube();
501
if (strcmp(Name, "CornerNaviCube") == 0) {
502
nc->setCorner(static_cast<NaviCube::Corner>(hGrp->GetInt("CornerNaviCube", 1)));
504
else if (strcmp(Name, "OffsetX") == 0 || strcmp(Name, "OffsetY") == 0) {
505
nc->setOffset(hGrp->GetInt("OffsetX", 0), hGrp->GetInt("OffsetY", 0));
507
else if (strcmp(Name, "ChamferSize") == 0) {
508
nc->setChamfer(hGrp->GetFloat("ChamferSize", 0.12f));
510
else if (strcmp(Name, "CubeSize") == 0) {
511
nc->setSize(hGrp->GetInt("CubeSize", 132));
513
else if (strcmp(Name, "NaviRotateToNearest") == 0) {
514
nc->setNaviRotateToNearest(hGrp->GetBool("NaviRotateToNearest", true));
516
else if (strcmp(Name, "NaviStepByTurn") == 0) {
517
nc->setNaviStepByTurn(hGrp->GetInt("NaviStepByTurn", 8));
519
else if (strcmp(Name, "FontZoom") == 0) {
520
nc->setFontZoom(hGrp->GetFloat("FontZoom", 0.3));
522
else if (strcmp(Name, "FontString") == 0) {
523
nc->setFont(hGrp->GetASCII("FontString"));
525
else if (strcmp(Name, "FontWeight") == 0) {
526
nc->setFontWeight(hGrp->GetInt("FontWeight", 0));
528
else if (strcmp(Name, "FontStretch") == 0) {
529
nc->setFontStretch(hGrp->GetInt("FontStretch", 0));
531
else if (strcmp(Name, "BaseColor") == 0) {
532
unsigned long col = hGrp->GetUnsigned("BaseColor", 3806916544);
533
nc->setBaseColor(App::Color::fromPackedRGBA<QColor>(col));
534
// update default contrast colors
535
parameterChanged("EmphaseColor");
537
else if (strcmp(Name, "EmphaseColor") == 0) {
538
App::Color bc((uint32_t)hGrp->GetUnsigned("BaseColor", 3806916544));
539
unsigned long d = bc.r + bc.g + bc.b >= 1.5f ? 255 : 4294967295;
540
unsigned long col = hGrp->GetUnsigned("EmphaseColor", d);
541
nc->setEmphaseColor(App::Color::fromPackedRGBA<QColor>(col));
543
else if (strcmp(Name, "HiliteColor") == 0) {
544
unsigned long col = hGrp->GetUnsigned("HiliteColor", 2867003391);
545
nc->setHiliteColor(App::Color::fromPackedRGBA<QColor>(col));
547
else if (strcmp(Name, "BorderWidth") == 0) {
548
nc->setBorderWidth(hGrp->GetFloat("BorderWidth", 1.1));
550
else if (strcmp(Name, "ShowCS") == 0) {
551
nc->setShowCS(hGrp->GetBool("ShowCS", true));
553
else if (strcmp(Name, "InactiveOpacity") == 0) {
554
float opacity = static_cast<float>(hGrp->GetInt("InactiveOpacity", 50)) / 100;
555
nc->setInactiveOpacity(opacity);
557
else if (strcmp(Name, "TextTop") == 0 || strcmp(Name, "TextBottom") == 0
558
|| strcmp(Name, "TextFront") == 0 || strcmp(Name, "TextRear") == 0
559
|| strcmp(Name, "TextLeft") == 0 || strcmp(Name, "TextRight") == 0) {
560
std::vector<std::string> labels;
561
QByteArray frontByteArray = tr("FRONT").toUtf8();
562
labels.push_back(hGrp->GetASCII("TextFront", frontByteArray.constData()));
563
QByteArray topByteArray = tr("TOP").toUtf8();
564
labels.push_back(hGrp->GetASCII("TextTop", topByteArray.constData()));
565
QByteArray rightByteArray = tr("RIGHT").toUtf8();
566
labels.push_back(hGrp->GetASCII("TextRight", rightByteArray.constData()));
567
QByteArray rearByteArray = tr("REAR").toUtf8();
568
labels.push_back(hGrp->GetASCII("TextRear", rearByteArray.constData()));
569
QByteArray bottomByteArray = tr("BOTTOM").toUtf8();
570
labels.push_back(hGrp->GetASCII("TextBottom", bottomByteArray.constData()));
571
QByteArray leftByteArray = tr("LEFT").toUtf8();
572
labels.push_back(hGrp->GetASCII("TextLeft", leftByteArray.constData()));
573
nc->setNaviCubeLabels(labels);
575
_viewer->getSoRenderManager()->scheduleRedraw();