Download src/Gui/PreferencePages/DlgSettingsLightSources.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 13.2 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Gui/PreferencePages/DlgSettingsLightSources.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Gui/PreferencePages/DlgSettingsLightSources.cpp
-
curl -L -o DlgSettingsLightSources.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Gui/PreferencePages/DlgSettingsLightSources.cpp
13.2 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /*************************************************************************** | |
| * Copyright (c) 2023 Werner Mayer <wmayer[at]users.sourceforge.net> * | |
| * * | |
| * This file is part of FreeCAD. * | |
| * * | |
| * FreeCAD is free software: you can redistribute it and/or modify it * | |
| * under the terms of the GNU Lesser General Public License as * | |
| * published by the Free Software Foundation, either version 2.1 of the * | |
| * License, or (at your option) any later version. * | |
| * * | |
| * FreeCAD is distributed in the hope that it will be useful, but * | |
| * WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * | |
| * Lesser General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Lesser General Public * | |
| * License along with FreeCAD. If not, see * | |
| * <https://www.gnu.org/licenses/>. * | |
| * * | |
| **************************************************************************/ | |
| using namespace Gui::Dialog; | |
| /* TRANSLATOR Gui::Dialog::DlgSettingsLightSources */ | |
| DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent) | |
| : PreferencePage(parent) | |
| , ui(new Ui_DlgSettingsLightSources) | |
| { | |
| ui->setupUi(this); | |
| view = ui->viewer; | |
| configureViewer(); | |
| const auto connectLightEvents = [this]( | |
| QuantitySpinBox* horizontalAngleSpinBox, | |
| QuantitySpinBox* verticalAngleSpinBox, | |
| QSpinBox* intensitySpinBox, | |
| ColorButton* colorButton, | |
| QCheckBox* enabledCheckbox, | |
| auto updateLightFunction | |
| ) { | |
| connect( | |
| horizontalAngleSpinBox, | |
| qOverload<double>(&QuantitySpinBox::valueChanged), | |
| this, | |
| updateLightFunction | |
| ); | |
| connect( | |
| verticalAngleSpinBox, | |
| qOverload<double>(&QuantitySpinBox::valueChanged), | |
| this, | |
| updateLightFunction | |
| ); | |
| connect(intensitySpinBox, qOverload<int>(&QSpinBox::valueChanged), this, updateLightFunction); | |
| connect(colorButton, &ColorButton::changed, this, updateLightFunction); | |
| connect(enabledCheckbox, &QCheckBox::checkStateChanged, this, updateLightFunction); | |
| connect(enabledCheckbox, &QCheckBox::stateChanged, this, updateLightFunction); | |
| }; | |
| const auto updateLight = [this]( | |
| SoDirectionalLight* light, | |
| QuantitySpinBox* horizontalAngleSpinBox, | |
| QuantitySpinBox* verticalAngleSpinBox, | |
| QSpinBox* intensitySpinBox, | |
| ColorButton* colorButton, | |
| QCheckBox* enabledCheckbox, | |
| std::function<void(bool)> setLightEnabled | |
| ) { | |
| light->color = Base::convertTo<SbColor>(colorButton->color()); | |
| light->intensity = Base::fromPercent(intensitySpinBox->value()); | |
| light->direction = Base::convertTo<SbVec3f>(azimuthElevationToDirection( | |
| horizontalAngleSpinBox->rawValue(), | |
| verticalAngleSpinBox->rawValue() | |
| )); | |
| setLightEnabled(enabledCheckbox->isChecked()); | |
| }; | |
| const auto updateHeadLight = [this, updateLight] { | |
| updateLight( | |
| view->getHeadlight(), | |
| ui->mainLightHorizontalAngle, | |
| ui->mainLightVerticalAngle, | |
| ui->mainLightIntensitySpinBox, | |
| ui->mainLightColor, | |
| ui->mainLightEnable, | |
| [this](bool enabled) { view->setHeadlightEnabled(enabled); } | |
| ); | |
| }; | |
| const auto updateFillLight = [this, updateLight] { | |
| updateLight( | |
| view->getFillLight(), | |
| ui->fillLightHorizontalAngle, | |
| ui->fillLightVerticalAngle, | |
| ui->fillLightIntensitySpinBox, | |
| ui->fillLightColor, | |
| ui->fillLightEnable, | |
| [this](bool enabled) { view->setFillLightEnabled(enabled); } | |
| ); | |
| }; | |
| const auto updateBackLight = [this, updateLight] { | |
| updateLight( | |
| view->getBacklight(), | |
| ui->backLightHorizontalAngle, | |
| ui->backLightVerticalAngle, | |
| ui->backLightIntensitySpinBox, | |
| ui->backLightColor, | |
| ui->backLightEnable, | |
| [this](bool enabled) { view->setBacklightEnabled(enabled); } | |
| ); | |
| }; | |
| connectLightEvents( | |
| ui->mainLightHorizontalAngle, | |
| ui->mainLightVerticalAngle, | |
| ui->mainLightIntensitySpinBox, | |
| ui->mainLightColor, | |
| ui->mainLightEnable, | |
| updateHeadLight | |
| ); | |
| connectLightEvents( | |
| ui->backLightHorizontalAngle, | |
| ui->backLightVerticalAngle, | |
| ui->backLightIntensitySpinBox, | |
| ui->backLightColor, | |
| ui->backLightEnable, | |
| updateBackLight | |
| ); | |
| connectLightEvents( | |
| ui->fillLightHorizontalAngle, | |
| ui->fillLightVerticalAngle, | |
| ui->fillLightIntensitySpinBox, | |
| ui->fillLightColor, | |
| ui->fillLightEnable, | |
| updateFillLight | |
| ); | |
| const auto updateAmbientLight = [this] { | |
| view->getEnvironment()->ambientColor = Base::convertTo<SbColor>(ui->ambientLightColor->color()); | |
| view->getEnvironment()->ambientIntensity = Base::fromPercent( | |
| ui->ambientLightIntensitySpinBox->value() | |
| ); | |
| }; | |
| connect( | |
| ui->ambientLightIntensitySpinBox, | |
| qOverload<int>(&QSpinBox::valueChanged), | |
| this, | |
| updateAmbientLight | |
| ); | |
| connect(ui->ambientLightColor, &ColorButton::changed, this, updateAmbientLight); | |
| connect(ui->zoomInButton, &QToolButton::clicked, this, &DlgSettingsLightSources::zoomIn); | |
| connect(ui->zoomOutButton, &QToolButton::clicked, this, &DlgSettingsLightSources::zoomOut); | |
| DlgSettingsLightSources::loadSettings(); | |
| } | |
| static inline SoMaterial* createMaterial(void) | |
| { | |
| const QColor ambientColor {0xff333333}, diffuseColor {0xffd2d2ff}, emissiveColor {0xff000000}, | |
| specularColor {0xffcccccc}; | |
| auto material = new SoMaterial(); | |
| material->ambientColor.setValue(Base::convertTo<SbColor>(ambientColor)); | |
| material->diffuseColor.setValue(Base::convertTo<SbColor>(diffuseColor)); | |
| material->emissiveColor.setValue(Base::convertTo<SbColor>(emissiveColor)); | |
| material->specularColor.setValue(Base::convertTo<SbColor>(specularColor)); | |
| material->shininess = 0.9f; | |
| return material; | |
| } | |
| static inline SoSphere* createSphere(void) | |
| { | |
| auto sphere = new SoSphere(); | |
| sphere->radius = 3; | |
| return sphere; | |
| } | |
| static inline SoComplexity* createGoodComplexity() | |
| { | |
| auto complexity = new SoComplexity(); | |
| complexity->value = 1.0; | |
| return complexity; | |
| } | |
| void DlgSettingsLightSources::configureViewer() | |
| { | |
| const SbVec3f defaultViewDirection {0.0f, 1.0f, 0.3f}; | |
| View3DSettings(hGrpView, view).applySettings(); | |
| view->setRedirectToSceneGraph(true); | |
| view->setViewing(true); | |
| view->setPopupMenuEnabled(false); | |
| view->setEnabledNaviCube(false); | |
| const auto root = static_cast<SoSeparator*>(view->getSceneGraph()); | |
| root->addChild(createGoodComplexity()); | |
| root->addChild(createMaterial()); | |
| root->addChild(createSphere()); | |
| const auto callback = new SoEventCallback(); | |
| root->addChild(callback); | |
| callback->addEventCallback( | |
| SoEvent::getClassTypeId(), | |
| []([[maybe_unused]] void* ud, SoEventCallback* cb) { cb->setHandled(); } | |
| ); | |
| view->setCameraType(SoOrthographicCamera::getClassTypeId()); | |
| view->setViewDirection(defaultViewDirection); | |
| view->viewAll(); | |
| camera = dynamic_cast<SoOrthographicCamera*>(view->getCamera()); | |
| const float cameraHeight = camera->height.getValue() * 2.0f; | |
| camera->height = cameraHeight; | |
| zoomStep = cameraHeight / 14.0f; | |
| } | |
| Base::Vector3d DlgSettingsLightSources::azimuthElevationToDirection(double azimuth, double elevation) | |
| { | |
| azimuth = Base::toRadians(azimuth); | |
| elevation = Base::toRadians(elevation); | |
| auto direction = Base::Vector3d { | |
| std::sin(azimuth) * std::cos(elevation), | |
| std::cos(azimuth) * std::cos(elevation), | |
| std::sin(elevation) | |
| }; | |
| direction.Normalize(); | |
| return direction; | |
| } | |
| std::pair<double, double> DlgSettingsLightSources::directionToAzimuthElevation(Base::Vector3d direction) | |
| { | |
| const auto azimuth = std::atan2(direction[0], direction[1]); | |
| const auto elevation = std::atan2( | |
| direction[2], | |
| std::sqrt(direction[1] * direction[1] + direction[0] * direction[0]) | |
| ); | |
| return {Base::toDegrees(azimuth), Base::toDegrees(elevation)}; | |
| } | |
| void DlgSettingsLightSources::saveSettings() | |
| { | |
| for (const auto& widget : findChildren<QWidget*>()) { | |
| if (const auto pref = dynamic_cast<PrefWidget*>(widget)) { | |
| pref->onSave(); | |
| } | |
| } | |
| const auto saveAngles = [this]( | |
| QuantitySpinBox* horizontalAngleSpinBox, | |
| QuantitySpinBox* verticalAngleSpinBox, | |
| const char* parameter | |
| ) { | |
| try { | |
| const auto direction = azimuthElevationToDirection( | |
| horizontalAngleSpinBox->rawValue(), | |
| verticalAngleSpinBox->rawValue() | |
| ); | |
| hGrp->SetASCII(parameter, Base::vectorToString(Base::convertTo<Base::Vector3f>(direction))); | |
| } | |
| catch (...) { | |
| } | |
| }; | |
| saveAngles(ui->mainLightHorizontalAngle, ui->mainLightVerticalAngle, "HeadlightDirection"); | |
| saveAngles(ui->backLightHorizontalAngle, ui->backLightVerticalAngle, "BacklightDirection"); | |
| saveAngles(ui->fillLightHorizontalAngle, ui->fillLightVerticalAngle, "FillLightDirection"); | |
| } | |
| void DlgSettingsLightSources::loadSettings() | |
| { | |
| for (const auto& widget : findChildren<QWidget*>()) { | |
| if (const auto pref = dynamic_cast<PrefWidget*>(widget)) { | |
| pref->onRestore(); | |
| } | |
| } | |
| const auto loadAngles = [this]( | |
| QuantitySpinBox* horizontalAngleSpinBox, | |
| QuantitySpinBox* verticalAngleSpinBox, | |
| const char* parameter | |
| ) { | |
| try { | |
| const auto direction = Base::stringToVector(hGrp->GetASCII(parameter)); | |
| const auto [azimuth, elevation] = directionToAzimuthElevation( | |
| Base::convertTo<Base::Vector3d>(direction) | |
| ); | |
| horizontalAngleSpinBox->setValue(azimuth); | |
| verticalAngleSpinBox->setValue(elevation); | |
| } | |
| catch (...) { | |
| } | |
| }; | |
| loadAngles(ui->mainLightHorizontalAngle, ui->mainLightVerticalAngle, "HeadlightDirection"); | |
| loadAngles(ui->backLightHorizontalAngle, ui->backLightVerticalAngle, "BacklightDirection"); | |
| loadAngles(ui->fillLightHorizontalAngle, ui->fillLightVerticalAngle, "FillLightDirection"); | |
| } | |
| void DlgSettingsLightSources::resetSettingsToDefaults() | |
| { | |
| PreferencePage::resetSettingsToDefaults(); | |
| hGrp->RemoveASCII("HeadlightDirection"); | |
| hGrp->RemoveASCII("BacklightDirection"); | |
| hGrp->RemoveASCII("FillLightDirection"); | |
| loadSettings(); | |
| configureViewer(); | |
| } | |
| void DlgSettingsLightSources::zoomIn() const | |
| { | |
| if (camera == nullptr) { | |
| return; | |
| } | |
| camera->height = camera->height.getValue() - zoomStep; | |
| } | |
| void DlgSettingsLightSources::zoomOut() const | |
| { | |
| if (camera == nullptr) { | |
| return; | |
| } | |
| camera->height = camera->height.getValue() + zoomStep; | |
| } | |
| void DlgSettingsLightSources::changeEvent(QEvent* event) | |
| { | |
| if (event->type() == QEvent::LanguageChange) { | |
| ui->retranslateUi(this); | |
| } | |
| PreferencePage::changeEvent(event); | |
| } | |