Merge pull request #19397 from kadet1090/three-point-lighting

Add three-point lighting
This commit is contained in:
Chris Hennes
2025-02-24 16:22:34 +00:00
committed by GitHub
23 changed files with 919 additions and 1088 deletions

View File

@@ -31,19 +31,7 @@
#include "Application.h"
#include "Material.h"
// Helper functions to consistently convert between float and long
namespace
{
float fromPercent(long value)
{
return std::roundf(value) / 100.0F;
}
long toPercent(float value)
{
return std::lround(100.0 * value);
}
} // namespace
#include <Base/Tools.h>
using namespace App;
@@ -351,9 +339,9 @@ App::Material Material::getDefaultAppearance()
};
App::Material mat(App::Material::DEFAULT);
mat.transparency = fromPercent(hGrp->GetInt("DefaultShapeTransparency", 0));
long shininess = toPercent(mat.shininess);
mat.shininess = fromPercent(hGrp->GetInt("DefaultShapeShininess", shininess));
mat.transparency = Base::fromPercent(hGrp->GetInt("DefaultShapeTransparency", 0));
long shininess = Base::toPercent(mat.shininess);
mat.shininess = Base::fromPercent(hGrp->GetInt("DefaultShapeShininess", shininess));
// This is handled in the material code when using the object appearance
bool randomColor = hGrp->GetBool("RandomColor", false);

View File

@@ -1253,7 +1253,7 @@ bool InventorLoader::isValid() const
namespace Base
{
BaseExport Vector3f to_vector(std::string str)
BaseExport Vector3f stringToVector(std::string str)
{
std::string_view view = str;
if (!boost::starts_with(view, "(") || !boost::ends_with(str, ")")) {
@@ -1282,4 +1282,9 @@ BaseExport Vector3f to_vector(std::string str)
return vec;
}
BaseExport std::string vectorToString(Vector3f vec)
{
return fmt::format("({},{},{})", vec.x, vec.y, vec.z);
}
} // namespace Base

View File

@@ -845,7 +845,14 @@ private:
* If it fails then a std::exception is thrown.
* Supported type names are float or double
*/
BaseExport Base::Vector3f to_vector(std::string);
BaseExport Base::Vector3f stringToVector(std::string);
/*!
* Expects a string of the form "(x,y,z)" and creates a vector from it.
* If it fails then a std::exception is thrown.
* Supported type names are float or double
*/
BaseExport std::string vectorToString(Vector3f);
} // namespace Base

View File

@@ -143,6 +143,16 @@ inline T toDegrees(T r)
return static_cast<T>((r / M_PI) * 180.0);
}
inline float fromPercent(const long value)
{
return std::roundf(value) / 100.0F;
}
inline long toPercent(float value)
{
return std::lround(100.0 * value);
}
template<class T>
inline T fmod(T numerator, T denominator)
{

View File

@@ -28,6 +28,8 @@
#include "ui_DlgMaterialProperties.h"
#include "ViewProvider.h"
#include <Base/Tools.h>
using namespace Gui::Dialog;
@@ -129,7 +131,7 @@ void DlgMaterialPropertiesImp::onSpecularColorChanged()
*/
void DlgMaterialPropertiesImp::onShininessValueChanged(int sh)
{
customMaterial.shininess = (float)sh / 100.0F;
customMaterial.shininess = Base::fromPercent(sh);
}
/**
@@ -137,7 +139,7 @@ void DlgMaterialPropertiesImp::onShininessValueChanged(int sh)
*/
void DlgMaterialPropertiesImp::onTransparencyValueChanged(int sh)
{
customMaterial.transparency = (float)sh / 100.0F;
customMaterial.transparency = Base::fromPercent(sh);
}
/**

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>499</width>
<height>520</height>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
@@ -48,11 +48,12 @@ lower right corner within opened files</string>
<item row="0" column="1">
<spacer name="horizontalSpacerCoord">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -63,7 +64,7 @@ lower right corner within opened files</string>
<string>Relative size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
@@ -73,6 +74,9 @@ lower right corner within opened files</string>
<string>Size of main coordinate system representation
in the corner -- in % of height/width of viewport</string>
</property>
<property name="suffix">
<string notr="true">%</string>
</property>
<property name="minimum">
<number>2</number>
</property>
@@ -82,9 +86,6 @@ in the corner -- in % of height/width of viewport</string>
<property name="value">
<number>10</number>
</property>
<property name="suffix">
<string notr="true">%</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>CornerCoordSystemSize</cstring>
</property>
@@ -105,7 +106,7 @@ in the corner -- in % of height/width of viewport</string>
<property name="toolTip">
<string>Axis letter and FPS counter color</string>
</property>
<property name="color" stdset="0">
<property name="color">
<color>
<red>0</red>
<green>0</green>
@@ -324,14 +325,76 @@ report this setting as enabled when seeking support on the FreeCAD forums</strin
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="renderCacheLabel">
<property name="text">
<string>Render cache</string>
<item row="1" column="1">
<widget class="QComboBox" name="comboAliasing">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>What kind of multisample anti-aliasing is used</string>
</property>
</widget>
</item>
<item row="0" column="4">
<item row="3" column="0">
<widget class="QLabel" name="markerSizeLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Marker size:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="aliasingLAbel">
<property name="text">
<string>Anti-Aliasing</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="transparentRenderLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Transparent objects:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::PrefComboBox" name="comboTransparentRender">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Render types of transparent objects</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>TransparentObjectRenderType</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
<item>
<property name="text">
<string>One pass</string>
</property>
</item>
<item>
<property name="text">
<string>Backface pass</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="renderCache">
<property name="minimumSize">
<size>
@@ -368,76 +431,21 @@ but slower response to any scene changes.</string>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="aliasingLAbel">
<item row="0" column="0">
<widget class="QLabel" name="renderCacheLabel">
<property name="text">
<string>Anti-Aliasing</string>
<string>Render cache</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QComboBox" name="comboAliasing">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>What kind of multisample anti-aliasing is used</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="transparentRenderLabel">
<property name="toolTip">
<string/>
</property>
<item row="4" column="0">
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Transparent objects:</string>
<string>Eye to eye distance for stereo modes</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="Gui::PrefComboBox" name="comboTransparentRender">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Render types of transparent objects</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>TransparentObjectRenderType</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
<item>
<property name="text">
<string>One pass</string>
</property>
</item>
<item>
<property name="text">
<string>Backface pass</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="markerSizeLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Marker size:</string>
</property>
</widget>
</item>
<item row="3" column="4">
<item row="3" column="1">
<widget class="QComboBox" name="boxMarkerSize">
<property name="minimumSize">
<size>
@@ -450,14 +458,7 @@ but slower response to any scene changes.</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Eye to eye distance for stereo modes</string>
</property>
</widget>
</item>
<item row="4" column="4">
<item row="4" column="1">
<widget class="Gui::PrefDoubleSpinBox" name="FloatSpinBox_EyeDistance">
<property name="minimumSize">
<size>
@@ -493,120 +494,6 @@ bounding box size of the 3D object that is currently displayed.</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="Gui::PrefCheckBox" name="checkBoxBacklight">
<property name="toolTip">
<string>Backlight is enabled with the defined color</string>
</property>
<property name="text">
<string>Backlight color</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>EnableBacklight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="Gui::PrefColorButton" name="backlightColor">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Backlight color</string>
</property>
<property name="color" stdset="0">
<color>
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>BacklightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="5" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="3">
<widget class="QLabel" name="backlightLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Intensity</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="Gui::PrefSlider" name="sliderIntensity">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Intensity of the backlight</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>BacklightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@@ -674,7 +561,7 @@ bounding box size of the 3D object that is currently displayed.</string>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -694,18 +581,8 @@ bounding box size of the 3D object that is currently displayed.</string>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefRadioButton</class>
<extends>QRadioButton</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
<class>Gui::PrefSpinBox</class>
<extends>QSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
@@ -714,8 +591,18 @@ bounding box size of the 3D object that is currently displayed.</string>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSlider</class>
<extends>QSlider</extends>
<class>Gui::PrefRadioButton</class>
<extends>QRadioButton</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
@@ -723,73 +610,40 @@ bounding box size of the 3D object that is currently displayed.</string>
<extends>QDoubleSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSpinBox</class>
<extends>QSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>checkBoxBacklight</sender>
<signal>toggled(bool)</signal>
<receiver>backlightColor</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>161</x>
<y>227</y>
</hint>
<hint type="destinationlabel">
<x>290</x>
<y>224</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBoxBacklight</sender>
<signal>toggled(bool)</signal>
<receiver>sliderIntensity</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>235</y>
</hint>
<hint type="destinationlabel">
<x>293</x>
<y>256</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBoxBacklight</sender>
<signal>toggled(bool)</signal>
<receiver>backlightLabel</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>82</x>
<y>507</y>
</hint>
<hint type="destinationlabel">
<x>316</x>
<y>507</y>
</hint>
</hints>
</connection>
<connection>
<sender>CheckBox_CornerCoordSystem</sender>
<signal>toggled(bool)</signal>
<receiver>SpinBox_CornerCoordSystemSize</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>CheckBox_CornerCoordSystem</sender>
<signal>toggled(bool)</signal>
<receiver>axisLetterColor</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -69,10 +69,7 @@ void DlgSettings3DViewImp::saveSettings()
ui->CheckBox_use_SW_OpenGL->onSave();
ui->CheckBox_useVBO->onSave();
ui->FloatSpinBox_EyeDistance->onSave();
ui->checkBoxBacklight->onSave();
ui->backlightColor->onSave();
ui->axisLetterColor->onSave();
ui->sliderIntensity->onSave();
ui->radioPerspective->onSave();
ui->radioOrthographic->onSave();
ui->xAxisColor->onSave();
@@ -89,10 +86,7 @@ void DlgSettings3DViewImp::loadSettings()
ui->CheckBox_use_SW_OpenGL->onRestore();
ui->CheckBox_useVBO->onRestore();
ui->FloatSpinBox_EyeDistance->onRestore();
ui->checkBoxBacklight->onRestore();
ui->backlightColor->onRestore();
ui->axisLetterColor->onRestore();
ui->sliderIntensity->onRestore();
ui->radioPerspective->onRestore();
ui->radioOrthographic->onRestore();
ui->comboTransparentRender->onRestore();

View File

@@ -24,12 +24,11 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/draggers/SoDirectionalLightDragger.h>
#include <Inventor/events/SoEvent.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoComplexity.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSphere.h>
@@ -37,7 +36,10 @@
#include "DlgSettingsLightSources.h"
#include "ui_DlgSettingsLightSources.h"
#include <App/Application.h>
#include <Utilities.h>
#include <Base/Builder3D.h>
#include <Base/Tools.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/View3DSettings.h>
@@ -46,273 +48,305 @@ using namespace Gui::Dialog;
/* TRANSLATOR Gui::Dialog::DlgSettingsLightSources */
DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent)
: PreferencePage(parent)
, ui(new Ui_DlgSettingsLightSources)
{
ui->setupUi(this);
view = ui->viewer;
createViewer();
}
static inline
SbVec3f getDirectionVector(const SbRotation &rotation)
static inline SbVec3f getDirectionVector(const SbRotation& rotation)
{
SbVec3f dir {0.0f, 0.0f, -1.0f};
rotation.multVec(dir, dir);
return dir;
}
static inline
void setLightDirection(const SbRotation &rotation, Gui::View3DInventorViewer *viewer)
DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent)
: PreferencePage(parent)
, ui(new Ui_DlgSettingsLightSources)
{
viewer->getHeadlight()->direction = getDirectionVector(rotation);
ui->setupUi(this);
view = ui->viewer;
configureViewer();
const auto connectLightEvents = [&](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::stateChanged, this, updateLightFunction);
};
const auto updateLight = [&](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 = [&] {
updateLight(view->getHeadlight(),
ui->mainLightHorizontalAngle,
ui->mainLightVerticalAngle,
ui->mainLightIntensitySpinBox,
ui->mainLightColor,
ui->mainLightEnable,
[&](bool enabled) {
view->setHeadlightEnabled(enabled);
});
};
const auto updateFillLight = [&] {
updateLight(view->getFillLight(),
ui->fillLightHorizontalAngle,
ui->fillLightVerticalAngle,
ui->fillLightIntensitySpinBox,
ui->fillLightColor,
ui->fillLightEnable,
[&](bool enabled) {
view->setFillLightEnabled(enabled);
});
};
const auto updateBackLight = [&] {
updateLight(view->getBacklight(),
ui->backLightHorizontalAngle,
ui->backLightVerticalAngle,
ui->backLightIntensitySpinBox,
ui->backLightColor,
ui->backLightEnable,
[&](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 = [&] {
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
void setLightDraggerDirection(const SbRotation &rotation, SoDirectionalLightDragger *light_dragger)
static inline SoMaterial* createMaterial(void)
{
light_dragger->rotation = rotation;
}
const QColor ambientColor {0xff333333}, diffuseColor {0xffd2d2ff}, emissiveColor {0xff000000},
specularColor {0xffcccccc};
static inline
void setValueSilently(QDoubleSpinBox *spn, const float val)
{
Q_ASSERT_X(spn, "setValueSilently", "QDoubleSpinBox has been deleted");
auto material = new SoMaterial();
spn->blockSignals(true);
spn->setValue(val);
spn->blockSignals(false);
}
void DlgSettingsLightSources::dragMotionCallback(void *data, SoDragger *drag)
{
auto lightdrag = dynamic_cast <SoDirectionalLightDragger *> (drag);
auto self = static_cast<DlgSettingsLightSources*>(data);
const SbRotation rotation = lightdrag->rotation.getValue();
setLightDirection(rotation, self->view);
setValueSilently(self->ui->q0_spnBox, rotation[0]);
setValueSilently(self->ui->q1_spnBox, rotation[1]);
setValueSilently(self->ui->q2_spnBox, rotation[2]);
setValueSilently(self->ui->q3_spnBox, rotation[3]);
const SbVec3f dir = getDirectionVector(rotation);
setValueSilently(self->ui->x_spnBox, dir[0]);
setValueSilently(self->ui->y_spnBox, dir[1]);
setValueSilently(self->ui->z_spnBox, dir[2]);
}
static inline
SoMaterial *createMaterial(void)
{
const QColor ambientColor {0xff333333},
diffuseColor {0xffd2d2ff},
emissiveColor {0xff000000},
specularColor {0xffcccccc};
auto material = new SoMaterial ();
material->ambientColor.setValue (ambientColor.redF(), ambientColor.greenF(), ambientColor.blueF());
material->diffuseColor.setValue (diffuseColor.redF(), diffuseColor.greenF(), diffuseColor.blueF());
material->emissiveColor.setValue(emissiveColor.redF(), emissiveColor.greenF(), emissiveColor.blueF());
material->specularColor.setValue(specularColor.redF(), specularColor.greenF(), specularColor.blueF());
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)
static inline SoSphere* createSphere(void)
{
auto sphere = new SoSphere();
sphere->radius = 2;
sphere->radius = 3;
return sphere;
}
void DlgSettingsLightSources::createViewer()
static inline SoComplexity* createGoodComplexity()
{
const QColor default_bg_color {180, 180, 180};
const SbVec3f default_view_direction {1.0f, 1.0f, -5.0f};
auto complexity = new SoComplexity();
complexity->value = 1.0;
return complexity;
}
void DlgSettingsLightSources::configureViewer()
{
const SbVec3f defaultViewDirection {0.0f, 1.0f, 0.3f};
View3DSettings(hGrp, view).applySettings();
// NOLINTBEGIN
view->setRedirectToSceneGraph(true);
view->setViewing(true);
view->setPopupMenuEnabled(false);
view->setBackgroundColor(default_bg_color);
view->setGradientBackground(Gui::View3DInventorViewer::NoGradient);
view->setEnabledNaviCube(false);
auto root = static_cast<SoSeparator*>(view->getSceneGraph());
root->addChild(createDragger());
const auto root = static_cast<SoSeparator*>(view->getSceneGraph());
root->addChild(createGoodComplexity());
root->addChild(createMaterial());
root->addChild(createSphere());
auto callback = new SoEventCallback();
const auto callback = new SoEventCallback();
root->addChild(callback);
callback->addEventCallback(SoEvent::getClassTypeId(),
[] (void* ud, SoEventCallback* cb) {
Q_UNUSED(ud)
cb->setHandled();
});
[]([[maybe_unused]] void* ud, SoEventCallback* cb) {
cb->setHandled();
});
view->setCameraType(SoOrthographicCamera::getClassTypeId());
view->setViewDirection(default_view_direction);
view->setViewDirection(defaultViewDirection);
view->viewAll();
camera = dynamic_cast <SoOrthographicCamera *> (view->getCamera());
const float camera_height = camera->height.getValue() * 2.0f;
camera->height = camera_height;
cam_step = camera_height / 14.0f;
// NOLINTEND
camera = dynamic_cast<SoOrthographicCamera*>(view->getCamera());
const float cameraHeight = camera->height.getValue() * 2.0f;
camera->height = cameraHeight;
zoomStep = cameraHeight / 14.0f;
}
SoDirectionalLightDragger* DlgSettingsLightSources::createDragger()
Base::Vector3d DlgSettingsLightSources::azimuthElevationToDirection(double azimuth,
double elevation)
{
// NOLINTBEGIN
lightDragger = new SoDirectionalLightDragger();
if (SoDragger* translator = dynamic_cast<SoDragger *>(lightDragger->getPart("translator", false))) {
translator->setPartAsDefault("xTranslator.translatorActive", nullptr);
translator->setPartAsDefault("yTranslator.translatorActive", nullptr);
translator->setPartAsDefault("zTranslator.translatorActive", nullptr);
translator->setPartAsDefault("xTranslator.translator", nullptr);
translator->setPartAsDefault("yTranslator.translator", nullptr);
translator->setPartAsDefault("zTranslator.translator", nullptr);
SoNode* node = translator->getPart("yzTranslator.translator", false);
if (node && node->isOfType(SoGroup::getClassTypeId())) {
auto ps = new SoPickStyle();
ps->style = SoPickStyle::UNPICKABLE;
static_cast<SoGroup*>(node)->insertChild(ps, 0);
}
}
azimuth = Base::toRadians(azimuth);
elevation = Base::toRadians(elevation);
lightDragger->addMotionCallback(dragMotionCallback, this);
return lightDragger;
// NOLINTEND
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()
{
ui->checkBoxLight1->onSave();
ui->light1Color->onSave();
ui->sliderIntensity1->onSave();
saveDirection();
for (const auto& widget : findChildren<QWidget*>()) {
if (const auto pref = dynamic_cast<PrefWidget*>(widget)) {
pref->onSave();
}
}
const auto saveAngles = [&](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()
{
ui->checkBoxLight1->onRestore();
ui->light1Color->onRestore();
ui->sliderIntensity1->onRestore();
loadDirection();
lightColor();
for (const auto& widget : findChildren<QWidget*>()) {
if (const auto pref = dynamic_cast<PrefWidget*>(widget)) {
pref->onRestore();
}
}
const auto loadAngles = [&](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()
{
ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter();
grp->SetFloat("HeadlightRotationX", 0.0);
grp->SetFloat("HeadlightRotationY", 0.0);
grp->SetFloat("HeadlightRotationZ", 0.0);
grp->SetFloat("HeadlightRotationW", 1.0);
grp->SetASCII("HeadlightDirection", "(0.0,0.0,-1.0)");
PreferencePage::resetSettingsToDefaults();
loadSettings();
configureViewer();
}
void DlgSettingsLightSources::saveDirection()
void DlgSettingsLightSources::zoomIn() const
{
if (lightDragger) {
const SbRotation rotation = lightDragger->rotation.getValue();
const SbVec3f dir = getDirectionVector(rotation);
const QString headlightDir = QStringLiteral("(%1,%2,%3)").arg(dir[0]).arg(dir[1]).arg(dir[2]);
ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter();
grp->SetFloat("HeadlightRotationX", rotation[0]);
grp->SetFloat("HeadlightRotationY", rotation[1]);
grp->SetFloat("HeadlightRotationZ", rotation[2]);
grp->SetFloat("HeadlightRotationW", rotation[3]);
grp->SetASCII("HeadlightDirection", qPrintable(headlightDir));
}
}
void DlgSettingsLightSources::loadDirection()
{
ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter();
SbRotation rotation = lightDragger->rotation.getValue();
auto get_q = [&grp](const char *name, const float def){return static_cast <float> (grp->GetFloat(name, def));};
const float q0 = get_q("HeadlightRotationX", rotation[0]),
q1 = get_q("HeadlightRotationY", rotation[1]),
q2 = get_q("HeadlightRotationZ", rotation[2]),
q3 = get_q("HeadlightRotationW", rotation[3]);
rotation.setValue(q0, q1, q2, q3);
setLightDirection(rotation, ui->viewer);
setLightDraggerDirection(rotation, lightDragger);
setValueSilently(ui->q0_spnBox, rotation[0]);
setValueSilently(ui->q1_spnBox, rotation[1]);
setValueSilently(ui->q2_spnBox, rotation[2]);
setValueSilently(ui->q3_spnBox, rotation[3]);
const SbVec3f dir = getDirectionVector(rotation);
setValueSilently(ui->x_spnBox, dir[0]);
setValueSilently(ui->y_spnBox, dir[1]);
setValueSilently(ui->z_spnBox, dir[2]);
}
void DlgSettingsLightSources::toggleLight(bool on)
{
if (view) {
view->setHeadlightEnabled(on);
}
}
void DlgSettingsLightSources::lightIntensity(int value)
{
if (view) {
view->getHeadlight()->intensity = static_cast <float> (value) / 100.0f;
}
}
void DlgSettingsLightSources::lightColor()
{
if (view) {
const QColor color = ui->light1Color->color();
view->getHeadlight()->color.setValue(color.redF(),
color.greenF(),
color.blueF());
}
}
void DlgSettingsLightSources::pushIn(void)
{
if (camera == nullptr)
if (camera == nullptr) {
return;
}
camera->height = camera->height.getValue() - cam_step;
camera->height = camera->height.getValue() - zoomStep;
}
void DlgSettingsLightSources::pullOut(void)
void DlgSettingsLightSources::zoomOut() const
{
if (camera == nullptr)
if (camera == nullptr) {
return;
}
camera->height = camera->height.getValue() + cam_step;
camera->height = camera->height.getValue() + zoomStep;
}
void DlgSettingsLightSources::changeEvent(QEvent* event)
@@ -323,41 +357,4 @@ void DlgSettingsLightSources::changeEvent(QEvent* event)
PreferencePage::changeEvent(event);
}
void DlgSettingsLightSources::updateDraggerQS()
{
const float q0 = ui->q0_spnBox->value(),
q1 = ui->q1_spnBox->value(),
q2 = ui->q2_spnBox->value(),
q3 = ui->q3_spnBox->value();
const SbRotation rotation {q0, q1, q2, q3};
setLightDirection(rotation, view);
setLightDraggerDirection(rotation, lightDragger);
const SbVec3f dir = getDirectionVector(rotation);
setValueSilently(ui->x_spnBox, dir[0]);
setValueSilently(ui->y_spnBox, dir[1]);
setValueSilently(ui->z_spnBox, dir[2]);
}
void DlgSettingsLightSources::updateDraggerXYZ()
{
const float x = ui->x_spnBox->value(),
y = ui->y_spnBox->value(),
z = ui->z_spnBox->value();
const SbRotation rotation {SbVec3f{0.0f, 0.0f, -1.0f}, SbVec3f{x, y, z}};
setLightDirection(rotation, view);
setLightDraggerDirection(rotation, lightDragger);
setValueSilently(ui->q0_spnBox, rotation[0]);
setValueSilently(ui->q1_spnBox, rotation[1]);
setValueSilently(ui->q2_spnBox, rotation[2]);
setValueSilently(ui->q3_spnBox, rotation[3]);
}
#include "moc_DlgSettingsLightSources.cpp"

View File

@@ -28,8 +28,12 @@
#include <Gui/PropertyPage.h>
#include <memory>
#include <QPointer>
#include <App/Application.h>
#include <Base/Parameter.h>
#include <Base/Vector3D.h>
class SoDragger;
class SbRotation;
class SoDirectionalLightDragger;
class SoOrthographicCamera;
@@ -56,32 +60,26 @@ public:
void resetSettingsToDefaults() override;
public Q_SLOTS:
void updateDraggerQS ();
void updateDraggerXYZ();
void toggleLight(bool on);
void lightIntensity(int value);
void lightColor();
void pushIn (void);
void pullOut(void);
void zoomIn() const;
void zoomOut() const;
protected:
void changeEvent(QEvent* event) override;
private:
void saveDirection();
void loadDirection();
void createViewer();
SoDirectionalLightDragger* createDragger();
static void dragMotionCallback(void *data, SoDragger *drag);
void configureViewer();
Base::Vector3d azimuthElevationToDirection(double azimuth, double elevation);
std::pair<double, double> directionToAzimuthElevation(Base::Vector3d direction);
private:
std::unique_ptr<Ui_DlgSettingsLightSources> ui;
QPointer <View3DInventorViewer> view;
SoDirectionalLightDragger* lightDragger = nullptr;
SoOrthographicCamera *camera = nullptr;
float cam_step = 3.0f;
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
float zoomStep = 3.0f;
};
} // namespace Dialog

View File

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>484</width>
<width>743</width>
<height>515</height>
</rect>
</property>
@@ -26,141 +26,10 @@
<string>Adjust the orientation of the directional light source by dragging the handle with the mouse or use the spin boxes for fine tuning.</string>
</property>
<property name="title">
<string>Direction</string>
<string>Preview</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="z_spnBox">
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="y_spnBox">
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="z_label">
<property name="text">
<string notr="true">z</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="x_label">
<property name="text">
<string notr="true">x</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QDoubleSpinBox" name="q1_spnBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QDoubleSpinBox" name="q2_spnBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QDoubleSpinBox" name="q0_spnBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="y_label">
<property name="text">
<string notr="true">y</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="q2_label">
<property name="text">
<string notr="true">q2</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="q0_label">
<property name="text">
<string notr="true">q0</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QDoubleSpinBox" name="q3_spnBox">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="q1_label">
<property name="text">
<string notr="true">q1</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="q3_label">
<property name="text">
<string notr="true">q3</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="x_spnBox">
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="5">
<item row="0" column="0" rowspan="2">
<widget class="Gui::View3DInventorViewer" name="viewer" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@@ -169,7 +38,7 @@
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
@@ -183,7 +52,7 @@
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -194,9 +63,9 @@
</spacer>
</item>
<item>
<widget class="QToolButton" name="pushInTB">
<widget class="QToolButton" name="zoomInButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Push In</string>
@@ -214,9 +83,9 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="pullOutTB">
<widget class="QToolButton" name="zoomOutButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Pull Out</string>
@@ -238,7 +107,7 @@
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -254,16 +123,72 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="bottomSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Light sources</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkBoxLight1">
<item row="0" column="4">
<widget class="QLabel" name="light1Label">
<property name="text">
<string>Light source</string>
<string>Color</string>
</property>
</widget>
</item>
<item row="4" column="6">
<widget class="Gui::PrefSpinBox" name="ambientLightIntensitySpinBox">
<property name="suffix">
<string>%</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>AmbientLightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="Gui::PrefColorButton" name="backLightColor">
<property name="color">
<color>
<red>245</red>
<green>245</green>
<blue>238</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>BacklightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::PrefCheckBox" name="mainLightEnable">
<property name="text">
<string>Main Light</string>
</property>
<property name="checked">
<bool>true</bool>
@@ -276,9 +201,226 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefColorButton" name="light1Color">
<property name="color" stdset="0">
<item row="2" column="2">
<widget class="Gui::QuantitySpinBox" name="backLightHorizontalAngle">
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>-130.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="Gui::QuantitySpinBox" name="backLightVerticalAngle">
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>-10.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="Gui::PrefCheckBox" name="backLightEnable">
<property name="text">
<string>Back Light</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>EnableBacklight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="Gui::QuantitySpinBox" name="fillLightHorizontalAngle">
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>-40.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="light1Label_2">
<property name="text">
<string>Vertical Angle</string>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="Gui::PrefColorButton" name="ambientLightColor">
<property name="color">
<color>
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>AmbientLightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="light1Label_3">
<property name="text">
<string>Horizontal Angle</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="Gui::PrefSpinBox" name="mainLightIntensitySpinBox">
<property name="suffix">
<string>%</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>90</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>HeadlightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="Gui::QuantitySpinBox" name="mainLightHorizontalAngle">
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="Gui::QuantitySpinBox" name="fillLightVerticalAngle">
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="Gui::PrefSpinBox" name="backLightIntensitySpinBox">
<property name="suffix">
<string>%</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>60</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>BacklightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="Gui::PrefCheckBox" name="fillLightEnable">
<property name="text">
<string>Fill Light</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>EnableFillLight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="3" column="6">
<widget class="Gui::PrefSpinBox" name="fillLightIntensitySpinBox">
<property name="suffix">
<string>%</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>40</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>FillLightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="light1Label_4">
<property name="text">
<string>Intensity</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="4">
<widget class="Gui::PrefColorButton" name="fillLightColor">
<property name="color">
<color>
<red>230</red>
<green>250</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>FillLightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="Gui::QuantitySpinBox" name="mainLightVerticalAngle">
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>-46.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="Gui::PrefColorButton" name="mainLightColor">
<property name="color">
<color>
<red>255</red>
<green>255</green>
@@ -293,83 +435,37 @@
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>115</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="light1Label">
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Intensity</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="Gui::PrefSlider" name="sliderIntensity1">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>HeadlightIntensity</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
<string>Ambient Light</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="bottomSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::QuantitySpinBox</class>
<extends>QAbstractSpinBox</extends>
<header>Gui/QuantitySpinBox.h</header>
</customwidget>
<customwidget>
<class>Gui::ColorButton</class>
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefColorButton</class>
<extends>Gui::ColorButton</extends>
<class>Gui::PrefSpinBox</class>
<extends>QSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSlider</class>
<extends>QSlider</extends>
<class>Gui::PrefColorButton</class>
<extends>Gui::ColorButton</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
@@ -384,262 +480,28 @@
</customwidget>
</customwidgets>
<tabstops>
<tabstop>checkBoxLight1</tabstop>
<tabstop>light1Color</tabstop>
<tabstop>sliderIntensity1</tabstop>
<tabstop>x_spnBox</tabstop>
<tabstop>y_spnBox</tabstop>
<tabstop>z_spnBox</tabstop>
<tabstop>q0_spnBox</tabstop>
<tabstop>q1_spnBox</tabstop>
<tabstop>q2_spnBox</tabstop>
<tabstop>q3_spnBox</tabstop>
<tabstop>mainLightEnable</tabstop>
<tabstop>mainLightHorizontalAngle</tabstop>
<tabstop>mainLightVerticalAngle</tabstop>
<tabstop>mainLightColor</tabstop>
<tabstop>mainLightIntensitySpinBox</tabstop>
<tabstop>backLightEnable</tabstop>
<tabstop>backLightHorizontalAngle</tabstop>
<tabstop>backLightVerticalAngle</tabstop>
<tabstop>backLightColor</tabstop>
<tabstop>backLightIntensitySpinBox</tabstop>
<tabstop>fillLightEnable</tabstop>
<tabstop>fillLightHorizontalAngle</tabstop>
<tabstop>fillLightVerticalAngle</tabstop>
<tabstop>fillLightColor</tabstop>
<tabstop>fillLightIntensitySpinBox</tabstop>
<tabstop>ambientLightColor</tabstop>
<tabstop>ambientLightIntensitySpinBox</tabstop>
</tabstops>
<resources>
<include location="../Icons/resource.qrc"/>
</resources>
<connections>
<connection>
<sender>checkBoxLight1</sender>
<signal>toggled(bool)</signal>
<receiver>light1Color</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>73</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>53</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBoxLight1</sender>
<signal>toggled(bool)</signal>
<receiver>light1Label</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>73</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>339</x>
<y>65</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBoxLight1</sender>
<signal>toggled(bool)</signal>
<receiver>sliderIntensity1</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>73</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>357</x>
<y>53</y>
</hint>
</hints>
</connection>
<connection>
<sender>q1_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerQS(void)</slot>
<hints>
<hint type="sourcelabel">
<x>399</x>
<y>168</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>q2_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerQS(void)</slot>
<hints>
<hint type="sourcelabel">
<x>399</x>
<y>200</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>q3_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerQS(void)</slot>
<hints>
<hint type="sourcelabel">
<x>399</x>
<y>232</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>q0_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerQS(void)</slot>
<hints>
<hint type="sourcelabel">
<x>422</x>
<y>128</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBoxLight1</sender>
<signal>toggled(bool)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>toggleLight(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>68</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderIntensity1</sender>
<signal>valueChanged(int)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>lightIntensity(int)</slot>
<hints>
<hint type="sourcelabel">
<x>404</x>
<y>52</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>light1Color</sender>
<signal>changed(void)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>lightColor(void)</slot>
<hints>
<hint type="sourcelabel">
<x>140</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>x_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerXYZ(void)</slot>
<hints>
<hint type="sourcelabel">
<x>186</x>
<y>141</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>y_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerXYZ(void)</slot>
<hints>
<hint type="sourcelabel">
<x>186</x>
<y>173</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>z_spnBox</sender>
<signal>valueChanged(double)</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>updateDraggerXYZ(void)</slot>
<hints>
<hint type="sourcelabel">
<x>186</x>
<y>205</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushInTB</sender>
<signal>clicked()</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>pushIn(void)</slot>
<hints>
<hint type="sourcelabel">
<x>126</x>
<y>224</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>pullOutTB</sender>
<signal>clicked()</signal>
<receiver>Gui::Dialog::DlgSettingsLightSources</receiver>
<slot>pullOut(void)</slot>
<hints>
<hint type="sourcelabel">
<x>126</x>
<y>255</y>
</hint>
<hint type="destinationlabel">
<x>241</x>
<y>257</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
<slots>
<slot>updateDraggerQS(void)</slot>
<slot>updateDraggerXYZ(void)</slot>

View File

@@ -24,6 +24,7 @@
#define GUI_UTILITIES_H
#include <vector>
#include <QColor>
#include <App/Material.h>
#include <Base/Converter.h>
#include <Base/ViewProj.h>
@@ -33,7 +34,6 @@
#include <Inventor/SbVec2f.h>
#include <Inventor/SbViewVolume.h>
class SbViewVolume;
class QAbstractItemView;
@@ -105,6 +105,18 @@ private:
const vec_type& v;
};
template <>
struct vec_traits<QColor> {
using vec_type = QColor;
using float_type = float;
explicit vec_traits(const vec_type& v) : v(v){}
inline std::tuple<float_type,float_type,float_type> get() const {
return std::make_tuple(v.redF(), v.greenF(), v.blueF());
}
private:
const vec_type& v;
};
template <>
inline SbMatrix convertTo<SbMatrix, Base::Matrix4D>(const Base::Matrix4D& vec2)
{

View File

@@ -130,6 +130,8 @@
#include "Navigation/NavigationAnimation.h"
#include "Utilities.h"
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoTransformSeparator.h>
#include <Inventor/So3DAnnotation.h>
@@ -435,12 +437,25 @@ void View3DInventorViewer::init()
// setup light sources
SoDirectionalLight* hl = this->getHeadlight();
environment = new SoEnvironment();
environment->ref();
environment->setName("environment");
backlight = new SoDirectionalLight();
backlight->ref();
backlight->setName("backlight");
backlight->direction.setValue(-hl->direction.getValue());
backlight->on.setValue(false); // by default off
fillLight = new SoDirectionalLight();
fillLight->ref();
fillLight->setName("filllight");
fillLight->direction.setValue(-0.60, -0.35, -0.79);
fillLight->intensity.setValue(0.6);
fillLight->color.setValue(0.95, 0.95, 1.0);
fillLight->on.setValue(false); // by default off
// Set up background scenegraph with image in it.
backgroundroot = new SoSeparator;
backgroundroot->ref();
@@ -470,10 +485,20 @@ void View3DInventorViewer::init()
cam->farDistance = 10;
// NOLINTEND
lightRotation = new SoRotation;
lightRotation->ref();
lightRotation->rotation.connectFrom(&cam->orientation);
this->foregroundroot->addChild(cam);
this->foregroundroot->addChild(lm);
this->foregroundroot->addChild(bc);
auto threePointLightingSeparator = new SoTransformSeparator;
threePointLightingSeparator->addChild(lightRotation);
threePointLightingSeparator->addChild(this->fillLight);
this->foregroundroot->addChild(cam);
// NOTE: For every mouse click event the SoFCUnifiedSelection searches for the picked
// point which causes a certain slow-down because for all objects the primitives
// must be created. Using an SoSeparator avoids this drawback.
@@ -482,6 +507,8 @@ void View3DInventorViewer::init()
// set the ViewProvider root node
pcViewProviderRoot = selectionRoot;
pcViewProviderRoot->addChild(threePointLightingSeparator);
pcViewProviderRoot->addChild(environment);
// increase refcount before passing it to setScenegraph(), to avoid
// premature destruction
@@ -633,6 +660,10 @@ View3DInventorViewer::~View3DInventorViewer()
this->objectGroup = nullptr;
this->backlight->unref();
this->backlight = nullptr;
this->fillLight->unref();
this->fillLight = nullptr;
this->environment->unref();
this->environment = nullptr;
inventorSelection.reset(nullptr);
@@ -1545,6 +1576,25 @@ bool View3DInventorViewer::isBacklightEnabled() const
return this->backlight->on.getValue();
}
SoDirectionalLight* View3DInventorViewer::getFillLight() const
{
return this->fillLight;
}
void View3DInventorViewer::setFillLightEnabled(bool on)
{
this->fillLight->on = on;
}
bool View3DInventorViewer::isFillLightEnabled() const
{
return this->fillLight->on.getValue();
}
SoEnvironment* View3DInventorViewer::getEnvironment() const
{
return this->environment;
}
void View3DInventorViewer::setSceneGraph(SoNode* root)
{
inherited::setSceneGraph(root);
@@ -3175,18 +3225,22 @@ void View3DInventorViewer::setCameraType(SoType type)
{
inherited::setCameraType(type);
SoCamera* cam = this->getSoRenderManager()->getCamera();
if (!cam) {
return;
}
if (type.isDerivedFrom(SoPerspectiveCamera::getClassTypeId())) {
// When doing a viewAll() for an orthographic camera and switching
// to perspective the scene looks completely strange because of the
// heightAngle. Setting it to 45 deg also causes an issue with a too
// close camera but we don't have this other ugly effect.
SoCamera* cam = this->getSoRenderManager()->getCamera();
if (!cam) {
return;
}
static_cast<SoPerspectiveCamera*>(cam)->heightAngle = (float)(M_PI / 4.0); // NOLINT
}
lightRotation->rotation.connectFrom(&cam->orientation);
}
void View3DInventorViewer::moveCameraTo(const SbRotation& orientation, const SbVec3f& position, int duration)

View File

@@ -46,6 +46,9 @@
#include "View3DInventorSelection.h"
#include "Quarter/SoQTQuarterAdaptor.h"
#include <Inventor/nodes/SoEnvironment.h>
#include <Inventor/nodes/SoRotation.h>
class SoTranslation;
class SoTransform;
@@ -146,6 +149,13 @@ public:
SoDirectionalLight* getBacklight() const;
void setBacklightEnabled(bool on);
bool isBacklightEnabled() const;
SoDirectionalLight* getFillLight() const;
void setFillLightEnabled(bool on);
bool isFillLightEnabled() const;
SoEnvironment* getEnvironment() const;
void setSceneGraph (SoNode *root) override;
bool searchNode(SoNode*) const;
@@ -496,7 +506,12 @@ private:
SoFCBackgroundGradient *pcBackGround;
SoSeparator * backgroundroot;
SoSeparator * foregroundroot;
SoDirectionalLight* backlight;
SoDirectionalLight* fillLight;
SoEnvironment* environment;
SoRotation* lightRotation;
// Scene graph root
SoSeparator * pcViewProviderRoot;

View File

@@ -38,6 +38,8 @@
#include "View3DSettings.h"
#include "View3DInventorViewer.h"
#include <Base/Tools.h>
using namespace Gui;
View3DSettings::View3DSettings(ParameterGrp::handle hGrp,
@@ -100,6 +102,12 @@ void View3DSettings::applySettings()
OnChange(*hGrp,"BacklightColor");
OnChange(*hGrp,"BacklightDirection");
OnChange(*hGrp,"BacklightIntensity");
OnChange(*hGrp,"EnableFillLight");
OnChange(*hGrp,"FillLightColor");
OnChange(*hGrp,"FillLightDirection");
OnChange(*hGrp,"FillLightIntensity");
OnChange(*hGrp,"AmbientLightColor");
OnChange(*hGrp,"AmbientLightIntensity");
OnChange(*hGrp,"NavigationStyle");
OnChange(*hGrp,"OrbitStyle");
OnChange(*hGrp,"Sensitivity");
@@ -121,7 +129,7 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
}
}
else if (strcmp(Reason,"HeadlightColor") == 0) {
unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white)
unsigned long headlight = rGrp.GetUnsigned("HeadlightColor", 0xFFFFFFFF); // default color (white)
float transparency;
SbColor headlightColor;
headlightColor.setPackedValue((uint32_t)headlight, transparency);
@@ -131,9 +139,9 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
}
else if (strcmp(Reason,"HeadlightDirection") == 0) {
try {
std::string pos = rGrp.GetASCII("HeadlightDirection");
std::string pos = rGrp.GetASCII("HeadlightDirection", defaultHeadLightDirection);
if (!pos.empty()) {
Base::Vector3f dir = Base::to_vector(pos);
Base::Vector3f dir = Base::stringToVector(pos);
for (auto _viewer : _viewers) {
_viewer->getHeadlight()->direction.setValue(dir.x, dir.y, dir.z);
}
@@ -144,18 +152,18 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
}
}
else if (strcmp(Reason,"HeadlightIntensity") == 0) {
long value = rGrp.GetInt("HeadlightIntensity", 100);
long value = rGrp.GetInt("HeadlightIntensity", 90);
for (auto _viewer : _viewers) {
_viewer->getHeadlight()->intensity.setValue((float)value/100.0f);
_viewer->getHeadlight()->intensity.setValue(Base::fromPercent(value));
}
}
else if (strcmp(Reason,"EnableBacklight") == 0) {
for (auto _viewer : _viewers) {
_viewer->setBacklightEnabled(rGrp.GetBool("EnableBacklight", false));
_viewer->setBacklightEnabled(rGrp.GetBool("EnableBacklight", true));
}
}
else if (strcmp(Reason,"BacklightColor") == 0) {
unsigned long backlight = rGrp.GetUnsigned("BacklightColor",ULONG_MAX); // default color (white)
unsigned long backlight = rGrp.GetUnsigned("BacklightColor", 0xF5F5EEFF);
float transparency;
SbColor backlightColor;
backlightColor.setPackedValue((uint32_t)backlight, transparency);
@@ -165,9 +173,9 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
}
else if (strcmp(Reason,"BacklightDirection") == 0) {
try {
std::string pos = rGrp.GetASCII("BacklightDirection");
std::string pos = rGrp.GetASCII("BacklightDirection", defaultBackLightDirection);
if (!pos.empty()) {
Base::Vector3f dir = Base::to_vector(pos);
Base::Vector3f dir = Base::stringToVector(pos);
for (auto _viewer : _viewers) {
_viewer->getBacklight()->direction.setValue(dir.x, dir.y, dir.z);
}
@@ -178,9 +186,58 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
}
}
else if (strcmp(Reason,"BacklightIntensity") == 0) {
long value = rGrp.GetInt("BacklightIntensity", 100);
long value = rGrp.GetInt("BacklightIntensity", 60);
for (auto _viewer : _viewers) {
_viewer->getBacklight()->intensity.setValue((float)value/100.0f);
_viewer->getBacklight()->intensity.setValue(Base::fromPercent(value));
}
}
else if (strcmp(Reason,"EnableFillLight") == 0) {
for (auto _viewer : _viewers) {
_viewer->setFillLightEnabled(rGrp.GetBool("EnableFillLight", true));
}
}
else if (strcmp(Reason,"FillLightColor") == 0) {
unsigned long backlight = rGrp.GetUnsigned("FillLightColor", 0xE6FAFFFF); // default color (white)
float transparency;
SbColor backlightColor;
backlightColor.setPackedValue((uint32_t)backlight, transparency);
for (auto _viewer : _viewers) {
_viewer->getFillLight()->color.setValue(backlightColor);
}
}
else if (strcmp(Reason,"FillLightDirection") == 0) {
try {
std::string pos = rGrp.GetASCII("FillLightDirection", defaultFillLightDirection);
if (!pos.empty()) {
Base::Vector3f dir = Base::stringToVector(pos);
for (auto _viewer : _viewers) {
_viewer->getFillLight()->direction.setValue(dir.x, dir.y, dir.z);
}
}
}
catch (const std::exception&) {
// ignore exception
}
}
else if (strcmp(Reason,"FillLightIntensity") == 0) {
long value = rGrp.GetInt("FillLightIntensity", 40);
for (auto _viewer : _viewers) {
_viewer->getFillLight()->intensity.setValue(Base::fromPercent(value));
}
}
else if (strcmp(Reason,"AmbientLightColor") == 0) {
unsigned long color = rGrp.GetUnsigned("AmbientLightColor", 0xFFFFFFFF);
float transparency;
SbColor backlightColor;
backlightColor.setPackedValue((uint32_t)color, transparency);
for (auto _viewer : _viewers) {
_viewer->getEnvironment()->ambientColor.setValue(backlightColor);
}
}
else if (strcmp(Reason,"AmbientLightIntensity") == 0) {
long value = rGrp.GetInt("AmbientLightIntensity", 20);
for (auto _viewer : _viewers) {
_viewer->getEnvironment()->ambientIntensity.setValue(Base::fromPercent(value));
}
}
else if (strcmp(Reason,"EnablePreselection") == 0) {

View File

@@ -33,6 +33,10 @@ class View3DInventorViewer;
class GuiExport View3DSettings: public ParameterGrp::ObserverType
{
public:
static constexpr auto defaultHeadLightDirection = "(0.6841049,-0.12062616,-0.7193398)";
static constexpr auto defaultFillLightDirection = "(-0.6403416,0.7631294,0.087155744)";
static constexpr auto defaultBackLightDirection = "(-0.7544065,-0.63302225,-0.17364818)";
View3DSettings(ParameterGrp::handle hGrp, View3DInventorViewer*);
View3DSettings(ParameterGrp::handle hGrp, const std::vector<View3DInventorViewer*>&);
~View3DSettings() override;

View File

@@ -49,21 +49,10 @@
#include "ViewProviderGeometryObject.h"
#include "ViewProviderGeometryObjectPy.h"
#include <Base/Tools.h>
using namespace Gui;
// Helper functions to consistently convert between float and long
namespace {
float fromPercent(long value)
{
return std::roundf(value) / 100.0F;
}
long toPercent(float value)
{
return std::lround(100.0 * value);
}
}
PROPERTY_SOURCE(Gui::ViewProviderGeometryObject, Gui::ViewProviderDragger)
const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};
@@ -71,7 +60,8 @@ const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};
ViewProviderGeometryObject::ViewProviderGeometryObject()
{
App::Material mat = App::Material::getDefaultAppearance();
long initialTransparency = toPercent(mat.transparency);
long initialTransparency = Base::toPercent(mat.transparency);
static const char* dogroup = "Display Options";
static const char* sgroup = "Selection";
@@ -140,8 +130,8 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
setSelectable(Sel);
}
else if (prop == &Transparency) {
long value = toPercent(ShapeAppearance.getTransparency());
float trans = fromPercent(Transparency.getValue());
long value = Base::toPercent(ShapeAppearance.getTransparency());
float trans = Base::fromPercent(Transparency.getValue());
if (value != Transparency.getValue()) {
ShapeAppearance.setTransparency(trans);
}
@@ -152,7 +142,7 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange)) {
getObject()->touch(true);
}
long value = toPercent(ShapeAppearance.getTransparency());
long value = Base::toPercent(ShapeAppearance.getTransparency());
if (value != Transparency.getValue()) {
Transparency.setValue(value);
}

View File

@@ -71,17 +71,6 @@ namespace
{
constexpr const int lowPrec = 2;
constexpr const int highPrec = 16;
int toPercent(float value)
{
return static_cast<int>(100 * value); // NOLINT
}
float fromPercent(int value)
{
return static_cast<float>(value) / 100.0F; // NOLINT
}
} // namespace
PropertyItemFactory& PropertyItemFactory::instance()
@@ -3658,7 +3647,7 @@ int PropertyMaterialItem::getShininess() const
}
auto val = value.value<Material>();
return toPercent(val.shininess);
return Base::toPercent(val.shininess);
}
void PropertyMaterialItem::setShininess(int s)
@@ -3669,7 +3658,7 @@ void PropertyMaterialItem::setShininess(int s)
}
auto mat = value.value<Material>();
mat.shininess = fromPercent(s);
mat.shininess = Base::fromPercent(s);
setValue(QVariant::fromValue<Material>(mat));
}
@@ -3681,7 +3670,7 @@ int PropertyMaterialItem::getTransparency() const
}
auto val = value.value<Material>();
return toPercent(val.transparency);
return Base::toPercent(val.transparency);
}
void PropertyMaterialItem::setTransparency(int t)
@@ -3692,7 +3681,7 @@ void PropertyMaterialItem::setTransparency(int t)
}
auto mat = value.value<Material>();
mat.transparency = fromPercent(t);
mat.transparency = Base::fromPercent(t);
setValue(QVariant::fromValue<Material>(mat));
}
@@ -3747,8 +3736,8 @@ QVariant PropertyMaterialItem::toolTip(const App::Property* prop) const
.arg(ec.red())
.arg(ec.green())
.arg(ec.blue())
.arg(toPercent(value.shininess))
.arg(toPercent(value.transparency));
.arg(Base::toPercent(value.shininess))
.arg(Base::toPercent(value.transparency));
return {data};
}
@@ -4085,7 +4074,7 @@ int PropertyMaterialListItem::getShininess() const
}
auto mat = list[0].value<Material>();
return toPercent(mat.shininess);
return Base::toPercent(mat.shininess);
}
void PropertyMaterialListItem::setShininess(int s)
@@ -4105,7 +4094,7 @@ void PropertyMaterialListItem::setShininess(int s)
}
auto mat = list[0].value<Material>();
mat.shininess = fromPercent(s);
mat.shininess = Base::fromPercent(s);
list[0] = QVariant::fromValue<Material>(mat);
setValue(list);
}
@@ -4127,7 +4116,7 @@ int PropertyMaterialListItem::getTransparency() const
}
auto mat = list[0].value<Material>();
return toPercent(mat.transparency);
return Base::toPercent(mat.transparency);
}
void PropertyMaterialListItem::setTransparency(int t)
@@ -4147,7 +4136,7 @@ void PropertyMaterialListItem::setTransparency(int t)
}
auto mat = list[0].value<Material>();
mat.transparency = fromPercent(t);
mat.transparency = Base::fromPercent(t);
list[0] = QVariant::fromValue<Material>(mat);
setValue(list);
}
@@ -4235,8 +4224,8 @@ QVariant PropertyMaterialListItem::toolTip(const App::Property* prop) const
.arg(ec.red())
.arg(ec.green())
.arg(ec.blue())
.arg(toPercent(value.shininess))
.arg(toPercent(value.transparency));
.arg(Base::toPercent(value.shininess))
.arg(Base::toPercent(value.transparency));
return {data};
}

View File

@@ -69,6 +69,8 @@
#include "ViewProviderAnalysis.h"
#include "ViewProviderFemPostObject.h"
#include <Base/Tools.h>
using namespace FemGui;
namespace sp = std::placeholders;
@@ -659,7 +661,7 @@ void ViewProviderFemPostObject::WriteColorData(bool ResetColorBarRange)
if (Field.getEnumVector().empty() || Field.getValue() == 0) {
m_material->diffuseColor.setValue(SbColor(0.8, 0.8, 0.8));
float trans = float(Transparency.getValue()) / 100.0;
float trans = Base::fromPercent(Transparency.getValue());
m_material->transparency.setValue(trans);
m_materialBinding->value = SoMaterialBinding::OVERALL;
m_materialBinding->touch();
@@ -696,7 +698,7 @@ void ViewProviderFemPostObject::WriteColorData(bool ResetColorBarRange)
SbColor* diffcol = m_material->diffuseColor.startEditing();
SbColor* edgeDiffcol = m_matPlainEdges->diffuseColor.startEditing();
float overallTransp = Transparency.getValue() / 100.0f;
float overallTransp = Base::fromPercent(Transparency.getValue());
m_material->transparency.setNum(numPts);
m_matPlainEdges->transparency.setNum(numPts);
float* transp = m_material->transparency.startEditing();
@@ -737,7 +739,7 @@ void ViewProviderFemPostObject::WriteColorData(bool ResetColorBarRange)
void ViewProviderFemPostObject::WriteTransparency()
{
float trans = static_cast<float>(Transparency.getValue()) / 100.0;
float trans = Base::fromPercent(Transparency.getValue());
float* value = m_material->transparency.startEditing();
float* edgeValue = m_matPlainEdges->transparency.startEditing();
// m_material and m_matPlainEdges field containers have same size

View File

@@ -38,6 +38,8 @@
#include "ModelManager.h"
#include "ModelUuids.h"
#include <Base/Tools.h>
using namespace Materials;
@@ -174,8 +176,8 @@ std::shared_ptr<App::Material> MaterialManager::defaultAppearance()
long initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
long initialShininess = hGrp->GetInt("DefaultShapeShininess", 90);
mat.shininess = ((float)initialShininess / 100.0F);
mat.transparency = ((float)initialTransparency / 100.0F);
mat.shininess = Base::fromPercent(initialShininess);
mat.transparency = Base::fromPercent(initialTransparency);
return std::make_shared<App::Material>(mat);
}

View File

@@ -329,7 +329,7 @@ void ViewProviderMesh::onChanged(const App::Property* prop)
pcMatBinding->value = SoMaterialBinding::OVERALL;
}
if (prop == &LineTransparency) {
float trans = LineTransparency.getValue() / 100.0F;
float trans = Base::fromPercent(LineTransparency.getValue());
pLineColor->transparency = trans;
}
else if (prop == &LineWidth) {
@@ -590,7 +590,7 @@ void ViewProviderMesh::tryColorPerVertexOrFace(bool on)
pcMatBinding->value = SoMaterialBinding::OVERALL;
const App::Color& c = ShapeAppearance.getDiffuseColor();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
pcShapeMaterial->transparency.setValue(Transparency.getValue() / 100.0F);
pcShapeMaterial->transparency.setValue(Base::fromPercent(Transparency.getValue()));
}
}

View File

@@ -33,6 +33,8 @@
#include "ViewProvider.h"
#include <Base/Tools.h>
using namespace PartGui;
@@ -88,7 +90,7 @@ void ViewProviderPart::applyTransparency(float transparency, std::vector<App::Co
for (auto& j : colors) {
// transparency hasn't been set for this face
if (j.a == 0.0) {
j.setTransparency(transparency/100.0F); // transparency comes in percent
j.setTransparency(Base::fromPercent(transparency)); // transparency comes in percent
}
}
}
@@ -101,7 +103,7 @@ void ViewProviderPart::applyTransparency(float transparency, std::vector<App::Ma
for (auto& j : colors) {
// transparency hasn't been set for this face
if (j.transparency == 0.0) {
j.transparency = transparency / 100.0F; // transparency comes in percent
j.transparency = Base::fromPercent(transparency); // transparency comes in percent
}
}
}

View File

@@ -97,19 +97,6 @@ FC_LOG_LEVEL_INIT("Part", true, true)
using namespace PartGui;
// Helper functions to consistently convert between float and long
namespace {
float fromPercent(long value)
{
return std::roundf(value) / 100.0F;
}
long toPercent(float value)
{
return std::lround(100.0 * value);
}
}
PROPERTY_SOURCE(PartGui::ViewProviderPartExt, Gui::ViewProviderGeometryObject)
@@ -364,9 +351,9 @@ void ViewProviderPartExt::onChanged(const App::Property* prop)
}
else if (prop == &Transparency) {
const App::Material& Mat = ShapeAppearance[0];
long value = toPercent(Mat.transparency);
long value = Base::toPercent(Mat.transparency);
if (value != Transparency.getValue()) {
float trans = fromPercent(Transparency.getValue());
float trans = Base::fromPercent(Transparency.getValue());
ShapeAppearance.setTransparency(trans);
}
}
@@ -676,7 +663,7 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
if(!element || !element[0]) {
auto color = ShapeAppearance.getDiffuseColor();
color.setTransparency(Transparency.getValue()/100.0F);
color.setTransparency(Base::fromPercent(Transparency.getValue()));
ret["Face"] = color;
ret["Edge"] = LineColor.getValue();
ret["Vertex"] = PointColor.getValue();
@@ -687,7 +674,7 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
auto size = ShapeAppearance.getSize();
if(element[4]=='*') {
auto color = ShapeAppearance.getDiffuseColor();
color.setTransparency(Transparency.getValue()/100.0F);
color.setTransparency(Base::fromPercent(Transparency.getValue()));
bool singleColor = true;
for(int i=0;i<size;++i) {
if (ShapeAppearance.getDiffuseColor(i) != color) {
@@ -699,7 +686,7 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
}
if(size && singleColor) {
color = ShapeAppearance.getDiffuseColor(0);
color.setTransparency(Transparency.getValue()/100.0F);
color.setTransparency(Base::fromPercent(100.0F));
ret.clear();
}
ret["Face"] = color;
@@ -710,7 +697,7 @@ std::map<std::string,App::Color> ViewProviderPartExt::getElementColors(const cha
else
ret[element] = ShapeAppearance.getDiffuseColor();
if(size==1)
ret[element].setTransparency(Transparency.getValue()/100.0F);
ret[element].setTransparency(Base::fromPercent(Transparency.getValue()));
}
} else if (boost::starts_with(element,"Edge")) {
auto size = LineColorArray.getSize();

View File

@@ -3303,7 +3303,7 @@ void ViewProviderSketch::unsetEdit(int ModNum)
// Resets the override draw style mode when leaving the sketch edit mode.
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
auto disableShadedView = hGrp->GetBool("DisableShadedView", true);
auto disableShadedView = hGrp->GetBool("DisableShadedView", false);
if (disableShadedView) {
Gui::View3DInventorViewer* viewer =
static_cast<Gui::View3DInventor*>(mdi)->getViewer();
@@ -3400,7 +3400,7 @@ void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int Mo
// Sets the view mode to no shading to prevent visibility issues against parallel surfaces with shininess when entering the sketch mode.
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
auto disableShadedView = hGrp->GetBool("DisableShadedView", true);
auto disableShadedView = hGrp->GetBool("DisableShadedView", false);
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");