Merge branch 'main' into modernize-type-check

This commit is contained in:
Chris Hennes
2023-10-25 16:07:28 -05:00
committed by GitHub
50 changed files with 2407 additions and 1148 deletions
+8
View File
@@ -319,6 +319,7 @@ SET(Gui_UIC_SRCS
PreferencePages/DlgSettingsEditor.ui
PreferencePages/DlgSettingsGeneral.ui
DlgSettingsImage.ui
PreferencePages/DlgSettingsLightSources.ui
PreferencePages/DlgSettingsMacro.ui
PreferencePages/DlgSettingsNavigation.ui
PreferencePages/DlgSettingsNotificationArea.ui
@@ -565,6 +566,7 @@ SET(Dialog_Settings_CPP_SRCS
PreferencePages/DlgSettingsEditor.cpp
PreferencePages/DlgSettingsGeneral.cpp
DlgSettingsImageImp.cpp
PreferencePages/DlgSettingsLightSources.cpp
PreferencePages/DlgSettingsMacroImp.cpp
PreferencePages/DlgSettingsNavigation.cpp
PreferencePages/DlgSettingsNotificationArea.cpp
@@ -586,6 +588,7 @@ SET(Dialog_Settings_HPP_SRCS
PreferencePages/DlgSettingsEditor.h
PreferencePages/DlgSettingsGeneral.h
DlgSettingsImageImp.h
PreferencePages/DlgSettingsLightSources.h
PreferencePages/DlgSettingsMacroImp.h
PreferencePages/DlgSettingsNavigation.h
PreferencePages/DlgSettingsNotificationArea.h
@@ -609,6 +612,7 @@ SET(Dialog_Settings_SRCS
PreferencePages/DlgSettingsEditor.ui
PreferencePages/DlgSettingsGeneral.ui
DlgSettingsImage.ui
PreferencePages/DlgSettingsLightSources.ui
PreferencePages/DlgSettingsMacro.ui
PreferencePages/DlgSettingsNavigation.ui
PreferencePages/DlgSettingsNotificationArea.ui
@@ -835,6 +839,8 @@ SET(View3D_CPP_SRCS
View3DPy.cpp
View3DViewerPy.cpp
NaviCube.cpp
NavigationAnimator.cpp
NavigationAnimation.cpp
)
SET(View3D_SRCS
${View3D_CPP_SRCS}
@@ -857,6 +863,8 @@ SET(View3D_SRCS
CoinRiftWidget.h
View3DViewerPy.h
NaviCube.h
NavigationAnimator.h
NavigationAnimation.h
)
SOURCE_GROUP("View3D" FILES ${View3D_SRCS})
+5 -4
View File
@@ -91,7 +91,7 @@ void DemoMode::reset()
view->getViewer()->stopAnimating();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/View");
hGrp->Notify("UseAutoRotation");
hGrp->Notify("UseNavigationAnimations");
}
void DemoMode::accept()
@@ -150,7 +150,7 @@ Gui::View3DInventor* DemoMode::activeView() const
float DemoMode::getSpeed(int v) const
{
float speed = (static_cast<float>(v)) / 50.0f; // let 2.0 be the maximum speed
float speed = (static_cast<float>(v)) / 10.0f; // let 10.0 be the maximum speed
return speed;
}
@@ -273,8 +273,9 @@ void DemoMode::startAnimation(Gui::View3DInventor* view)
{
if (!view->getViewer()->isAnimationEnabled())
view->getViewer()->setAnimationEnabled(true);
view->getViewer()->startAnimating(getDirection(view),
getSpeed(ui->speedSlider->value()));
view->getViewer()->startSpinningAnimation(getDirection(view),
getSpeed(ui->speedSlider->value()));
}
void DemoMode::onTimerCheckToggled(bool on)
-1
View File
@@ -1821,7 +1821,6 @@ MDIView *Document::createView(const Base::Type& typeId)
view3D->setWindowTitle(title);
view3D->setWindowModified(this->isModified());
view3D->setWindowIcon(QApplication::windowIcon());
view3D->resize(400, 300);
if (!cameraSettings.empty()) {
+36 -8
View File
@@ -51,6 +51,7 @@ EditableDatumLabel::EditableDatumLabel(View3DInventorViewer* view,
: isSet(false)
, autoDistance(autoDistance)
, autoDistanceReverse(false)
, value(0.0)
, viewer(view)
, spinBox(nullptr)
, cameraSensor(nullptr)
@@ -94,7 +95,7 @@ EditableDatumLabel::~EditableDatumLabel()
void EditableDatumLabel::activate()
{
if (!viewer) {
if (!viewer || isActive()) {
return;
}
@@ -130,8 +131,12 @@ void EditableDatumLabel::deactivate()
}
}
void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj)
void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool visibleToMouse)
{
if (isInEdit()) {
return;
}
QWidget* mdi = viewer->parentWidget();
label->string = " ";
@@ -147,6 +152,10 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj)
spinBox->installEventFilter(eventFilteringObj);
}
if (!visibleToMouse) {
setSpinboxVisibleToMouse(visibleToMouse);
}
spinBox->show();
setSpinboxValue(val);
//Note: adjustSize apparently uses the Min/Max values to set the size. So if we don't set them to INT_MAX, the spinbox are much too big.
@@ -156,6 +165,7 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj)
connect(spinBox, qOverload<double>(&QuantitySpinBox::valueChanged),
this, [this](double value) {
this->isSet = true;
this->value = value;
Q_EMIT this->valueChanged(value);
});
}
@@ -163,20 +173,35 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj)
void EditableDatumLabel::stopEdit()
{
if (spinBox) {
// write the spinbox value in the label.
Base::Quantity quantity = spinBox->value();
double factor{};
QString unitStr;
QString valueStr;
valueStr = quantity.getUserString(factor, unitStr);
label->string = SbString(valueStr.toUtf8().constData());
spinBox->deleteLater();
spinBox = nullptr;
}
}
bool EditableDatumLabel::isInEdit()
bool EditableDatumLabel::isActive() const
{
return spinBox;
return cameraSensor != nullptr;
}
bool EditableDatumLabel::isInEdit() const
{
return spinBox != nullptr;
}
double EditableDatumLabel::getValue()
double EditableDatumLabel::getValue() const
{
return spinBox->rawValue();
// We use value rather than spinBox->rawValue() in case edit stopped.
return value;
}
void EditableDatumLabel::setSpinboxValue(double val, const Base::Unit& unit)
@@ -188,6 +213,7 @@ void EditableDatumLabel::setSpinboxValue(double val, const Base::Unit& unit)
QSignalBlocker block(spinBox);
spinBox->setValue(Base::Quantity(val, unit));
value = val;
positionSpinbox();
if (spinBox->hasFocus()) {
@@ -311,11 +337,13 @@ void EditableDatumLabel::setLabelDistance(double val)
label->param1 = float(val);
}
// NOLINTNEXTLINE
void EditableDatumLabel::setLabelStartAngle(double val)
{
label->param2 = float(val);
}
// NOLINTNEXTLINE
void EditableDatumLabel::setLabelRange(double val)
{
label->param3 = float(val);
@@ -340,9 +368,9 @@ void EditableDatumLabel::setLabelAutoDistanceReverse(bool val)
autoDistanceReverse = val;
}
void EditableDatumLabel::setSpinboxInvisibleToMouse(bool val)
void EditableDatumLabel::setSpinboxVisibleToMouse(bool val)
{
spinBox->setAttribute(Qt::WA_TransparentForMouseEvents, val);
spinBox->setAttribute(Qt::WA_TransparentForMouseEvents, !val);
}
#include "moc_EditableDatumLabel.cpp"
+6 -4
View File
@@ -51,10 +51,11 @@ public:
void activate();
void deactivate();
void startEdit(double val, QObject* eventFilteringObj = nullptr);
void startEdit(double val, QObject* eventFilteringObj = nullptr, bool visibleToMouse = false);
void stopEdit();
bool isInEdit();
double getValue();
bool isActive() const;
bool isInEdit() const;
double getValue() const;
void setSpinboxValue(double val, const Base::Unit& unit = Base::Unit::Length);
void setPlacement(const Base::Placement& plc);
void setColor(SbColor color);
@@ -68,13 +69,14 @@ public:
void setLabelRange(double val);
void setLabelRecommendedDistance();
void setLabelAutoDistanceReverse(bool val);
void setSpinboxInvisibleToMouse(bool val);
void setSpinboxVisibleToMouse(bool val);
// NOLINTBEGIN
SoDatumLabel* label;
bool isSet;
bool autoDistance;
bool autoDistanceReverse;
double value;
// NOLINTEND
Q_SIGNALS:
+1
View File
@@ -86,6 +86,7 @@
#include <Inventor/details/SoPointDetail.h>
#include <Inventor/draggers/SoCenterballDragger.h>
#include <Inventor/draggers/SoDirectionalLightDragger.h>
#include <Inventor/draggers/SoDragger.h>
#include <Inventor/draggers/SoTrackballDragger.h>
#include <Inventor/draggers/SoTransformerDragger.h>
+167
View File
@@ -0,0 +1,167 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2023 Bas Ruigrok (Rexbas) <[email protected]> *
* *
* 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/>. *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "NavigationAnimation.h"
#include <Inventor/nodes/SoCamera.h>
using namespace Gui;
NavigationAnimation::NavigationAnimation(NavigationStyle* navigation)
: navigation(navigation)
{}
void NavigationAnimation::updateCurrentValue(const QVariant& value)
{
if (state() == QAbstractAnimation::State::Stopped) {
return;
}
update(value);
}
void NavigationAnimation::onStop([[maybe_unused]] bool finished)
{}
FixedTimeAnimation::FixedTimeAnimation(NavigationStyle* navigation, const SbRotation& orientation,
const SbVec3f& rotationCenter, const SbVec3f& translation,
int duration)
: NavigationAnimation(navigation)
, targetOrientation(orientation)
, targetTranslation(translation)
, rotationCenter(rotationCenter)
{
setDuration(duration);
setStartValue(0.0);
setEndValue(duration * 1.0);
}
void FixedTimeAnimation::initialize()
{
prevAngle = 0;
prevTranslation = SbVec3f(0, 0, 0);
// Find an axis and angle to rotate from the camera orientation to the target orientation using post-multiplication
SbVec3f rotationAxisPost;
float angle;
SbRotation(navigation->getCamera()->orientation.getValue().inverse() * targetOrientation).getValue(rotationAxisPost, angle);
if (angle > M_PI) {
angle -= 2 * M_PI;
}
// Convert post-multiplication axis to a pre-multiplication axis
navigation->getCamera()->orientation.getValue().inverse().multVec(rotationAxisPost, rotationAxis);
angularVelocity = angle / duration();
linearVelocity = targetTranslation / duration();
}
/**
* @param value The elapsed time
*/
void FixedTimeAnimation::update(const QVariant& value)
{
SoCamera* camera = navigation->getCamera();
if (!camera) {
return;
}
float angle = value.toFloat() * angularVelocity;
SbVec3f translation = value.toFloat() * linearVelocity;
SbRotation rotation(rotationAxis, angle - prevAngle);
camera->position = camera->position.getValue() - prevTranslation;
navigation->reorientCamera(camera, rotation, rotationCenter);
camera->position = camera->position.getValue() + translation;
prevAngle = angle;
prevTranslation = translation;
}
/**
* @param finished True when the animation is finished, false when interrupted
*/
void FixedTimeAnimation::onStop(bool finished)
{
if (finished) {
SoCamera* camera = navigation->getCamera();
if (!camera) {
return;
}
// Set exact target orientation
camera->orientation = targetOrientation;
camera->position = camera->position.getValue() + targetTranslation - prevTranslation;
}
}
/**
* @param navigation The navigation style
* @param axis The rotation axis in screen coordinates
* @param velocity The angular velocity in radians per second
*/
SpinningAnimation::SpinningAnimation(NavigationStyle* navigation, const SbVec3f& axis,
float velocity)
: NavigationAnimation(navigation)
, rotationAxis(axis)
{
setDuration((2 * M_PI / velocity) * 1000.0);
setStartValue(0.0);
setEndValue(2 * M_PI);
setLoopCount(-1);
}
void SpinningAnimation::initialize()
{
prevAngle = 0;
navigation->setViewing(true);
navigation->setViewingMode(NavigationStyle::SPINNING);
}
/**
* @param value The angle in radians
*/
void SpinningAnimation::update(const QVariant& value)
{
SoCamera* camera = navigation->getCamera();
if (!camera) {
return;
}
SbRotation deltaRotation = SbRotation(rotationAxis, value.toFloat() - prevAngle);
navigation->reorientCamera(camera, deltaRotation);
prevAngle = value.toFloat();
}
/**
* @param finished True when the animation is finished, false when interrupted
*/
void SpinningAnimation::onStop([[maybe_unused]] bool finished)
{
if (navigation->getViewingMode() != NavigationStyle::SPINNING) {
return;
}
navigation->setViewingMode(navigation->isViewing() ? NavigationStyle::IDLE : NavigationStyle::INTERACT);
}
+99
View File
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2023 Bas Ruigrok (Rexbas) <[email protected]> *
* *
* 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/>. *
* *
***************************************************************************/
#ifndef GUI_NAVIGATIONANIMATION_H
#define GUI_NAVIGATIONANIMATION_H
#include "NavigationStyle.h"
#include <Inventor/SbRotation.h>
#include <Inventor/SbVec3f.h>
#include <QVariantAnimation>
namespace Gui
{
class GuiExport NavigationAnimation : protected QVariantAnimation
{
Q_OBJECT
public:
explicit NavigationAnimation(NavigationStyle* navigation);
Q_SIGNALS:
void interrupted();
protected:
NavigationStyle* navigation;
virtual void initialize() = 0;
virtual void update(const QVariant& value) = 0;
virtual void onStop(bool finished);
private:
void updateCurrentValue(const QVariant& value) override;
friend class NavigationAnimator;
friend class QObject;
};
class GuiExport FixedTimeAnimation : public NavigationAnimation
{
public:
explicit FixedTimeAnimation(NavigationStyle* navigation, const SbRotation& orientation,
const SbVec3f& rotationCenter, const SbVec3f& translation,
int duration);
private:
float angularVelocity; // [rad/ms]
SbVec3f linearVelocity; // [/ms]
SbRotation targetOrientation;
SbVec3f targetTranslation;
float prevAngle;
SbVec3f prevTranslation;
SbVec3f rotationCenter;
SbVec3f rotationAxis;
void initialize() override;
void update(const QVariant& value) override;
void onStop(bool finished) override;
};
class GuiExport SpinningAnimation : public NavigationAnimation
{
public:
explicit SpinningAnimation(NavigationStyle* navigation, const SbVec3f& axis, float velocity);
private:
SbVec3f rotationAxis;
float prevAngle;
void initialize() override;
void update(const QVariant& value) override;
void onStop(bool finished) override;
};
} // namespace Gui
#endif // GUI_NAVIGATIONANIMATION_H
+92
View File
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2023 Bas Ruigrok (Rexbas) <[email protected]> *
* *
* 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/>. *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "NavigationAnimator.h"
#include "NavigationAnimation.h"
#include <QEventLoop>
using namespace Gui;
NavigationAnimator::NavigationAnimator()
: activeAnimation(nullptr)
{}
NavigationAnimator::~NavigationAnimator()
{
stop();
}
/**
* @brief Start an animation
*
* @param animation The animation to start
*/
void NavigationAnimator::start(const std::shared_ptr<NavigationAnimation>& animation)
{
stop();
activeAnimation = animation;
activeAnimation->initialize();
connect(activeAnimation.get(), &NavigationAnimation::finished, this, [this]() {
activeAnimation->onStop(true);
activeAnimation.reset();
});
activeAnimation->start();
}
/**
* @brief Start an animation and wait for it to finish
*
* @param animation The animation to start
* @return True if the animation finished, false if interrupted
*/
bool NavigationAnimator::startAndWait(const std::shared_ptr<NavigationAnimation>& animation)
{
stop();
bool finished = true;
QEventLoop loop;
connect(animation.get(), &NavigationAnimation::finished, &loop, &QEventLoop::quit);
connect(animation.get(), &NavigationAnimation::interrupted, &loop, [&finished, &loop]() {
finished = false;
loop.quit();
});
start(animation);
loop.exec();
return finished;
}
/**
* @brief Stops an active animation and releases shared ownership of the animation
*/
void NavigationAnimator::stop()
{
if (activeAnimation && activeAnimation->state() != QAbstractAnimation::State::Stopped) {
disconnect(activeAnimation.get(), &NavigationAnimation::finished, 0, 0);
Q_EMIT activeAnimation->interrupted();
activeAnimation->stop();
activeAnimation->onStop(false);
activeAnimation.reset();
}
}
+52
View File
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2023 Bas Ruigrok (Rexbas) <[email protected]> *
* *
* 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/>. *
* *
***************************************************************************/
#ifndef GUI_NAVIGATIONANIMATOR_H
#define GUI_NAVIGATIONANIMATOR_H
#include "NavigationStyle.h"
#include <QObject>
#include <memory>
namespace Gui
{
class NavigationAnimation;
class GuiExport NavigationAnimator : public QObject
{
Q_OBJECT
public:
NavigationAnimator();
~NavigationAnimator();
void start(const std::shared_ptr<NavigationAnimation>& animation);
bool startAndWait(const std::shared_ptr<NavigationAnimation>& animation);
void stop();
private:
std::shared_ptr<NavigationAnimation> activeAnimation;
};
} // namespace Gui
#endif // GUI_NAVIGATIONANIMATOR_H
+120 -253
View File
@@ -45,40 +45,13 @@
#include "Application.h"
#include "MenuManager.h"
#include "MouseSelection.h"
#include "NavigationAnimator.h"
#include "NavigationAnimation.h"
#include "SoMouseWheelEvent.h"
#include "View3DInventorViewer.h"
using namespace Gui;
namespace Gui {
struct NavigationStyleP {
int animationsteps;
int animationdelta;
SbVec3f focal1, focal2;
SbVec3f rotationCenter;
SbBool rotationCenterFound;
NavigationStyle::RotationCenterModes rotationCenterMode;
SbRotation endRotation;
SoTimerSensor * animsensor;
float sensitivity;
SbBool resetcursorpos;
NavigationStyleP()
{
this->animationsteps = 0;
this->animationdelta = 0;
this->animsensor = nullptr;
this->sensitivity = 2.0f;
this->resetcursorpos = false;
this->rotationCenterFound = false;
this->rotationCenterMode = NavigationStyle::RotationCenterMode::ScenePointAtCursor |
NavigationStyle::RotationCenterMode::FocalPointAtCursor;
}
static void viewAnimationCB(void * data, SoSensor * sensor);
};
}
class FCSphereSheetProjector : public SbSphereSheetProjector {
using inherited = SbSphereSheetProjector;
@@ -184,25 +157,19 @@ const Base::Type& NavigationStyleEvent::style() const
return t;
}
#define PRIVATE(ptr) (ptr->pimpl)
#define PUBLIC(ptr) (ptr->pub)
TYPESYSTEM_SOURCE_ABSTRACT(Gui::NavigationStyle,Base::BaseClass)
NavigationStyle::NavigationStyle() : viewer(nullptr), mouseSelection(nullptr)
{
PRIVATE(this) = new NavigationStyleP();
PRIVATE(this)->animsensor = new SoTimerSensor(NavigationStyleP::viewAnimationCB, this);
this->rotationCenterMode = NavigationStyle::RotationCenterMode::ScenePointAtCursor
| NavigationStyle::RotationCenterMode::FocalPointAtCursor;
initialize();
}
NavigationStyle::~NavigationStyle()
{
finalize();
if (PRIVATE(this)->animsensor->isScheduled())
PRIVATE(this)->animsensor->unschedule();
delete PRIVATE(this)->animsensor;
delete PRIVATE(this);
delete this->animator;
}
NavigationStyle& NavigationStyle::operator = (const NavigationStyle& ns)
@@ -222,12 +189,15 @@ void NavigationStyle::setViewer(View3DInventorViewer* view)
void NavigationStyle::initialize()
{
this->animator = new NavigationAnimator();
this->sensitivity = 2.0f;
this->resetcursorpos = false;
this->currentmode = NavigationStyle::IDLE;
this->prevRedrawTime = SbTime::getTimeOfDay();
this->spinanimatingallowed = true;
this->spinsamplecounter = 0;
this->spinincrement = SbRotation::identity();
this->spinRotation.setValue(SbVec3f(0, 0, -1), 0);
this->rotationCenterFound = false;
// FIXME: use a smaller sphere than the default one to have a larger
// area close to the borders that gives us "z-axis rotation"?
@@ -357,167 +327,72 @@ SbBool NavigationStyle::lookAtPoint(const SbVec2s screenpos)
return true;
}
void NavigationStyle::lookAtPoint(const SbVec3f& pos)
void NavigationStyle::lookAtPoint(const SbVec3f& position)
{
SoCamera* cam = viewer->getSoRenderManager()->getCamera();
if (!cam)
return;
PRIVATE(this)->rotationCenterFound = false;
// Find global coordinates of focal point.
SbVec3f direction;
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
PRIVATE(this)->focal1 = cam->position.getValue() +
cam->focalDistance.getValue() * direction;
PRIVATE(this)->focal2 = pos;
// avoid to interfere with spinning (fixes #3101462)
if (this->isAnimating())
this->stopAnimating();
if (PRIVATE(this)->animsensor->isScheduled()) {
PRIVATE(this)->animsensor->unschedule();
this->interactiveCountDec();
}
if (isAnimationEnabled()) {
SbRotation cam_rot = cam->orientation.getValue();
// get the amount of movement
SbVec3f dir1 = direction, dir2;
dir2 = pos - cam->position.getValue();
dir2.normalize();
SbRotation rot(dir1, dir2);
float val = 0.5f*(1.0f + dir1.dot(dir2)); // value in range [0,1]
int div = (int)(val * 20.0f);
int steps = 20-div; // do it with max. 20 steps
// check whether a movement is required
if (steps > 0) {
PRIVATE(this)->endRotation = cam_rot;
this->spinRotation = cam_rot;
PRIVATE(this)->animationsteps = 5;
PRIVATE(this)->animationdelta = std::max<int>(100/steps, 5);
PRIVATE(this)->animsensor->setBaseTime(SbTime::getTimeOfDay());
PRIVATE(this)->animsensor->schedule();
this->interactiveCountInc();
}
else {
// set to the given position
SbVec3f direction;
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
cam->position = pos - cam->focalDistance.getValue() * direction;
}
}
else {
// set to the given position
SbVec3f direction;
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
cam->position = pos - cam->focalDistance.getValue() * direction;
}
this->rotationCenterFound = false;
translateCamera(position - getFocalPoint());
}
void NavigationStyle::setCameraOrientation(const SbRotation& rot, SbBool moveToCenter)
SoCamera* NavigationStyle::getCamera() const
{
SoCamera* cam = viewer->getSoRenderManager()->getCamera();
if (!cam)
return this->viewer->getCamera();
}
void NavigationStyle::setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter)
{
SoCamera* camera = getCamera();
if (!camera)
return;
// Find global coordinates of focal point.
SbVec3f direction;
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
PRIVATE(this)->focal1 = cam->position.getValue() +
cam->focalDistance.getValue() * direction;
PRIVATE(this)->focal2 = PRIVATE(this)->focal1;
animator->stop();
SbVec3f focalPoint = getFocalPoint();
SbVec3f translation(0, 0, 0);
if (moveToCenter) {
SoGetBoundingBoxAction action(viewer->getSoRenderManager()->getViewportRegion());
action.apply(viewer->getSceneGraph());
SbBox3f box = action.getBoundingBox();
if (!box.isEmpty()) {
rot.multVec(SbVec3f(0, 0, -1), direction);
//float s = (this->focal1 - box.getCenter()).dot(direction);
//this->focal2 = box.getCenter() + s * direction;
// setting the center of the overall bounding box as the future focal point
// seems to be a satisfactory solution
PRIVATE(this)->focal2 = box.getCenter();
translation = box.getCenter() - focalPoint;
}
}
// avoid to interfere with spinning (fixes #3101462)
if (this->isAnimating())
this->stopAnimating();
if (PRIVATE(this)->animsensor->isScheduled()) {
PRIVATE(this)->animsensor->unschedule();
this->interactiveCountDec();
}
// Start an animation or set the pose directly
if (isAnimationEnabled()) {
// get the amount of movement
SbVec3f dir1, dir2;
SbRotation cam_rot = cam->orientation.getValue();
cam_rot.multVec(SbVec3f(0, 0, -1), dir1);
rot.multVec(SbVec3f(0, 0, -1), dir2);
float val = 0.5f*(1.0f + dir1.dot(dir2)); // value in range [0,1]
int div = (int)(val * 20.0f);
int steps = 20-div; // do it with max. 20 steps
// check whether a movement is required
if (steps > 0) {
PRIVATE(this)->endRotation = rot; // this is the final camera orientation
this->spinRotation = cam_rot;
PRIVATE(this)->animationsteps = 5;
PRIVATE(this)->animationdelta = std::max<int>(100/steps, 5);
PRIVATE(this)->animsensor->setBaseTime(SbTime::getTimeOfDay());
PRIVATE(this)->animsensor->schedule();
this->interactiveCountInc();
}
else {
// due to possible round-off errors make sure that the
// exact orientation is set
cam->orientation.setValue(rot);
cam->position = PRIVATE(this)->focal2 - cam->focalDistance.getValue() * direction;
}
viewer->startAnimation(orientation, focalPoint, translation);
}
else {
// set to the given rotation
cam->orientation.setValue(rot);
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
cam->position = PRIVATE(this)->focal2 - cam->focalDistance.getValue() * direction;
// Distance from rotation center to camera position in camera coordinate system
SbVec3f rotationCenterDistanceCam = camera->focalDistance.getValue() * SbVec3f(0, 0, 1);
// Set to the given orientation
camera->orientation = orientation;
// Distance from rotation center to new camera position in global coordinate system
SbVec3f newRotationCenterDistance;
camera->orientation.getValue().multVec(rotationCenterDistanceCam, newRotationCenterDistance);
// Reposition camera so the rotation center stays in the same place
// Optionally add translation to move to center
camera->position = focalPoint + newRotationCenterDistance + translation;
}
}
void NavigationStyleP::viewAnimationCB(void * data, SoSensor * sensor)
void NavigationStyle::translateCamera(const SbVec3f& translation)
{
Q_UNUSED(sensor);
auto that = static_cast<NavigationStyle*>(data);
if (PRIVATE(that)->animationsteps > 0) {
// here the camera rotates from the current rotation to a given
// rotation (e.g. the standard views). To get this movement animated
// we calculate an interpolated rotation and update the view after
// each step
float step = std::min<float>((float)PRIVATE(that)->animationsteps/100.0f, 1.0f);
SbRotation slerp = SbRotation::slerp(that->spinRotation, PRIVATE(that)->endRotation, step);
SbVec3f focalpoint = (1.0f-step)*PRIVATE(that)->focal1 + step*PRIVATE(that)->focal2;
SoCamera* cam = that->viewer->getSoRenderManager()->getCamera();
if (!cam) // no camera
return;
SoCamera* camera = getCamera();
if (!camera)
return;
SbVec3f direction;
cam->orientation.setValue(slerp);
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
cam->position = focalpoint - cam->focalDistance.getValue() * direction;
animator->stop();
PRIVATE(that)->animationsteps += PRIVATE(that)->animationdelta;
if (PRIVATE(that)->animationsteps > 100) {
// now we have reached the end of the movement
PRIVATE(that)->animationsteps=0;
PRIVATE(that)->animsensor->unschedule();
that->interactiveCountDec();
// set to the actual given rotation
cam->orientation.setValue(PRIVATE(that)->endRotation);
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
cam->position = PRIVATE(that)->focal2 - cam->focalDistance.getValue() * direction;
}
// Start an animation or set the pose directly
if (isAnimationEnabled()) {
viewer->startAnimation(camera->orientation.getValue(), SbVec3f(0, 0, 0), translation);
}
else {
camera->position = camera->position.getValue() + translation;
}
}
@@ -604,29 +479,41 @@ void NavigationStyle::viewAll()
}
}
/** Rotate the camera by the given amount, then reposition it so we're
* still pointing at the same focal point.
/** Rotate the camera by the given amount, then reposition it so we're still pointing at the same
* focal point
*/
void NavigationStyle::reorientCamera(SoCamera * cam, const SbRotation & rot)
void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotation)
{
if (!cam)
reorientCamera(camera, rotation, getFocalPoint());
}
/** Rotate the camera by the given amount, then reposition it so the rotation center stays in the
* same place
*/
void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter)
{
if (!camera) {
return;
// Find global coordinates of focal point.
SbVec3f direction;
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
SbVec3f focalpoint = cam->position.getValue() +
cam->focalDistance.getValue() * direction;
// Set new orientation value by accumulating the new rotation.
cam->orientation = rot * cam->orientation.getValue();
// Fix issue with near clipping in orthogonal view
if (cam->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) {
cam->focalDistance = static_cast<SoOrthographicCamera*>(cam)->height;
}
// Reposition camera so we are still pointing at the same old focal point.
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
cam->position = focalpoint - cam->focalDistance.getValue() * direction;
// Distance from rotation center to camera position in camera coordinate system
SbVec3f rotationCenterDistanceCam;
camera->orientation.getValue().inverse().multVec(camera->position.getValue() - rotationCenter, rotationCenterDistanceCam);
// Set new orientation value by accumulating the new rotation
camera->orientation = rotation * camera->orientation.getValue();
// Fix issue with near clipping in orthogonal view
if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) {
camera->focalDistance = static_cast<SoOrthographicCamera*>(camera)->height;
}
// Distance from rotation center to new camera position in global coordinate system
SbVec3f newRotationCenterDistance;
camera->orientation.getValue().multVec(rotationCenterDistanceCam, newRotationCenterDistance);
// Reposition camera so the rotation center stays in the same place
camera->position = rotationCenter + newRotationCenterDistance;
}
void NavigationStyle::panCamera(SoCamera * cam, float aspectratio, const SbPlane & panplane,
@@ -684,7 +571,7 @@ void NavigationStyle::panToCenter(const SbPlane & pplane, const SbVec2f & currpo
const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion();
float ratio = vp.getViewportAspectRatio();
panCamera(viewer->getSoRenderManager()->getCamera(), ratio, pplane, SbVec2f(0.5,0.5), currpos);
PRIVATE(this)->rotationCenterFound = false;
this->rotationCenterFound = false;
}
/** Dependent on the camera type this will either shrink or expand the
@@ -695,6 +582,9 @@ void NavigationStyle::zoom(SoCamera * cam, float diffvalue)
{
if (!cam) // can happen for empty scenegraph
return;
animator->stop();
SoType t = cam->getTypeId();
SbName tname = t.getName();
@@ -862,14 +752,14 @@ void NavigationStyle::doRotate(SoCamera * camera, float angle, const SbVec2f& po
SbVec3f NavigationStyle::getRotationCenter(SbBool& found) const
{
found = PRIVATE(this)->rotationCenterFound;
return PRIVATE(this)->rotationCenter;
found = this->rotationCenterFound;
return this->rotationCenter;
}
void NavigationStyle::setRotationCenter(const SbVec3f& cnt)
{
PRIVATE(this)->rotationCenter = cnt;
PRIVATE(this)->rotationCenterFound = true;
this->rotationCenter = cnt;
this->rotationCenterFound = true;
}
SbVec3f NavigationStyle::getFocalPoint() const
@@ -901,8 +791,8 @@ void NavigationStyle::spin(const SbVec2f & pointerpos)
lastpos[0] = float(this->log.position[1][0]) / float(std::max((int)(glsize[0]-1), 1));
lastpos[1] = float(this->log.position[1][1]) / float(std::max((int)(glsize[1]-1), 1));
if (PRIVATE(this)->rotationCenterMode && PRIVATE(this)->rotationCenterFound) {
SbVec3f hitpoint = PRIVATE(this)->rotationCenter;
if (this->rotationCenterMode && this->rotationCenterFound) {
SbVec3f hitpoint = this->rotationCenter;
// set to the given position
SbVec3f direction;
@@ -929,7 +819,7 @@ void NavigationStyle::spin(const SbVec2f & pointerpos)
r.invert();
this->reorientCamera(viewer->getSoRenderManager()->getCamera(), r);
if (PRIVATE(this)->rotationCenterMode && PRIVATE(this)->rotationCenterFound) {
if (this->rotationCenterMode && this->rotationCenterFound) {
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(vp.getViewportAspectRatio());
SbPlane panplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
@@ -1015,7 +905,7 @@ SbBool NavigationStyle::doSpin()
float radians;
rot.getValue(axis, radians);
if ((radians > 0.01f) && (deltatime < 0.300)) {
this->spinRotation = rot;
viewer->startSpinningAnimation(axis, radians * 5);
return true;
}
}
@@ -1030,14 +920,14 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev)
this->localPos = ev->getPosition();
// mode is WindowCenter
if (!PRIVATE(this)->rotationCenterMode) {
if (!this->rotationCenterMode) {
setRotationCenter(getFocalPoint());
}
//Option to get point on model (slow) or always on focal plane (fast)
//
// mode is ScenePointAtCursor to get exact point if possible
if (PRIVATE(this)->rotationCenterMode & NavigationStyle::RotationCenterMode::ScenePointAtCursor) {
if (this->rotationCenterMode & NavigationStyle::RotationCenterMode::ScenePointAtCursor) {
SoRayPickAction rpaction(viewer->getSoRenderManager()->getViewportRegion());
rpaction.setPoint(this->localPos);
rpaction.setRadius(viewer->getPickRadius());
@@ -1051,7 +941,7 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev)
}
// mode is FocalPointAtCursor or a ScenePointAtCursor failed
if (PRIVATE(this)->rotationCenterMode & NavigationStyle::RotationCenterMode::FocalPointAtCursor) {
if (this->rotationCenterMode & NavigationStyle::RotationCenterMode::FocalPointAtCursor) {
// get the intersection point of the ray and the focal plane
const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion();
float ratio = vp.getViewportAspectRatio();
@@ -1072,7 +962,7 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev)
}
// mode is BoundingBoxCenter or a ScenePointAtCursor failed
if (PRIVATE(this)->rotationCenterMode & NavigationStyle::RotationCenterMode::BoundingBoxCenter) {
if (this->rotationCenterMode & NavigationStyle::RotationCenterMode::BoundingBoxCenter) {
const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion();
float ratio = vp.getViewportAspectRatio();
@@ -1128,20 +1018,6 @@ void NavigationStyle::moveCursorPosition()
}
}
void NavigationStyle::updateAnimation()
{
SbTime now = SbTime::getTimeOfDay();
double secs = now.getValue() - prevRedrawTime.getValue();
this->prevRedrawTime = now;
if (this->isAnimating()) {
// here the camera rotates around a fix axis
SbRotation deltaRotation = this->spinRotation;
deltaRotation.scaleAngle(secs * 5.0);
this->reorientCamera(viewer->getSoRenderManager()->getCamera(), deltaRotation);
}
}
void NavigationStyle::redraw()
{
if (mouseSelection)
@@ -1168,7 +1044,7 @@ void
NavigationStyle::setAnimationEnabled(const SbBool enable)
{
this->spinanimatingallowed = enable;
if (!enable && this->isAnimating()) { this->stopAnimating(); }
if (!enable && this->isAnimating()) { animator->stop(); }
}
/*!
@@ -1191,52 +1067,39 @@ SbBool NavigationStyle::isAnimating() const
return this->currentmode == NavigationStyle::SPINNING;
}
/*!
* Starts programmatically the viewer in animation mode. The given axis direction
* is always in screen coordinates, not in world coordinates.
*/
void NavigationStyle::startAnimating(const SbVec3f& axis, float velocity)
void NavigationStyle::startAnimating(const std::shared_ptr<NavigationAnimation>& animation, bool wait) const
{
if (!isAnimationEnabled())
return;
this->prevRedrawTime = SbTime::getTimeOfDay();
this->spinincrement = SbRotation::identity();
SbRotation rot;
rot.setValue(axis, velocity);
this->setViewing(true);
this->setViewingMode(NavigationStyle::SPINNING);
this->spinRotation = rot;
if (wait) {
animator->startAndWait(animation);
}
else {
animator->start(animation);
}
}
void NavigationStyle::stopAnimating()
void NavigationStyle::stopAnimating() const
{
if (this->currentmode != NavigationStyle::SPINNING) {
return;
}
this->setViewingMode(this->isViewing() ?
NavigationStyle::IDLE : NavigationStyle::INTERACT);
animator->stop();
}
void NavigationStyle::setSensitivity(float val)
{
PRIVATE(this)->sensitivity = val;
this->sensitivity = val;
}
float NavigationStyle::getSensitivity() const
{
return PRIVATE(this)->sensitivity;
return this->sensitivity;
}
void NavigationStyle::setResetCursorPosition(SbBool on)
{
PRIVATE(this)->resetcursorpos = on;
this->resetcursorpos = on;
}
SbBool NavigationStyle::isResetCursorPosition() const
{
return PRIVATE(this)->resetcursorpos;
return this->resetcursorpos;
}
void NavigationStyle::setZoomInverted(SbBool on)
@@ -1266,12 +1129,12 @@ SbBool NavigationStyle::isZoomAtCursor() const
void NavigationStyle::setRotationCenterMode(NavigationStyle::RotationCenterModes mode)
{
PRIVATE(this)->rotationCenterMode = mode;
this->rotationCenterMode = mode;
}
NavigationStyle::RotationCenterModes NavigationStyle::getRotationCenterMode() const
{
return PRIVATE(this)->rotationCenterMode;
return this->rotationCenterMode;
}
void NavigationStyle::startSelection(AbstractMouseSelection* mouse)
@@ -1415,6 +1278,7 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode)
case DRAGGING:
// Set up initial projection point for the projector object when
// first starting a drag operation.
animator->stop();
viewer->showRotationCenter(true);
this->spinprojector->project(this->lastmouseposition);
this->interactiveCountInc();
@@ -1428,15 +1292,18 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode)
break;
case PANNING:
animator->stop();
pan(viewer->getSoRenderManager()->getCamera());
this->interactiveCountInc();
break;
case ZOOMING:
animator->stop();
this->interactiveCountInc();
break;
case BOXZOOM:
animator->stop();
this->interactiveCountInc();
break;
+23 -13
View File
@@ -38,7 +38,7 @@
#include <Base/BaseClass.h>
#include <Gui/Namespace.h>
#include <FCGlobal.h>
#include <memory>
// forward declarations
class SoEvent;
@@ -52,7 +52,9 @@ class SbSphereSheetProjector;
namespace Gui {
class View3DInventorViewer;
class NavigationAnimator;
class AbstractMouseSelection;
class NavigationAnimation;
/**
* @author Werner Mayer
@@ -122,9 +124,9 @@ public:
void setAnimationEnabled(const SbBool enable);
SbBool isAnimationEnabled() const;
void startAnimating(const SbVec3f& axis, float velocity);
void stopAnimating();
SbBool isAnimating() const;
void startAnimating(const std::shared_ptr<NavigationAnimation>& animation, bool wait = false) const;
void stopAnimating() const;
void setSensitivity(float);
float getSensitivity() const;
@@ -144,11 +146,14 @@ public:
void setRotationCenter(const SbVec3f& cnt);
SbVec3f getFocalPoint() const;
void updateAnimation();
void redraw();
void setCameraOrientation(const SbRotation& rot, SbBool moveTocenter=false);
void lookAtPoint(const SbVec3f&);
SoCamera* getCamera() const;
void setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter = false);
void translateCamera(const SbVec3f& translation);
void reorientCamera(SoCamera* camera, const SbRotation& rotation);
void reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter);
void boxZoom(const SbBox2s& box);
virtual void viewAll();
@@ -173,6 +178,9 @@ public:
void setOrbitStyle(OrbitStyle style);
OrbitStyle getOrbitStyle() const;
SbBool isViewing() const;
void setViewing(SbBool);
SbVec3f getRotationCenter(SbBool&) const;
protected:
@@ -183,15 +191,13 @@ protected:
void interactiveCountDec();
int getInteractiveCount() const;
SbBool isViewing() const;
void setViewing(SbBool);
SbBool isSeekMode() const;
void setSeekMode(SbBool enable);
SbBool seekToPoint(const SbVec2s screenpos);
void seekToPoint(const SbVec3f& scenepos);
SbBool lookAtPoint(const SbVec2s screenpos);
void lookAtPoint(const SbVec3f& position);
void reorientCamera(SoCamera * camera, const SbRotation & rot);
void panCamera(SoCamera * camera,
float vpaspect,
const SbPlane & panplane,
@@ -233,13 +239,13 @@ protected:
} log;
View3DInventorViewer* viewer{nullptr};
NavigationAnimator* animator;
ViewerMode currentmode;
SoMouseButtonEvent mouseDownConsumedEvent;
SbVec2f lastmouseposition;
SbVec2s globalPos;
SbVec2s localPos;
SbPlane panningplane;
SbTime prevRedrawTime;
SbTime centerTime;
SbBool lockrecenter;
SbBool menuenabled;
@@ -261,13 +267,17 @@ protected:
SbBool spinanimatingallowed;
int spinsamplecounter;
SbRotation spinincrement;
SbRotation spinRotation;
SbSphereSheetProjector * spinprojector;
//@}
private:
struct NavigationStyleP* pimpl;
friend struct NavigationStyleP;
friend class NavigationAnimator;
SbVec3f rotationCenter;
SbBool rotationCenterFound;
NavigationStyle::RotationCenterModes rotationCenterMode;
float sensitivity;
SbBool resetcursorpos;
};
/** Sub-classes of this class appear in the preference dialog where users can
+2 -1
View File
@@ -32,7 +32,8 @@
<FCBool Name="ShowFPS" Value="0"/>
<FCBool Name="ShowNaviCube" Value="1"/>
<FCBool Name="ShowSelectionBoundingBox" Value="0"/>
<FCBool Name="UseAutoRotation" Value="0"/>
<FCBool Name="UseNavigationAnimations" Value="1"/>
<FCFloat Name="AnimationDuration" Value="0.25"/>
<FCBool Name="UseVBO" Value="0"/>
<FCFloat Name="ViewScalingFactor" Value="1.0"/>
<FCBool Name="ZoomAtCursor" Value="1"/>
@@ -0,0 +1,229 @@
// 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/>. *
* *
**************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QColor>
#include <QEvent>
#include <QGridLayout>
#include <Inventor/draggers/SoDirectionalLightDragger.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoSeparator.h>
#endif
#include "DlgSettingsLightSources.h"
#include "ui_DlgSettingsLightSources.h"
#include <Gui/View3DInventorViewer.h>
using namespace Gui::Dialog;
/* TRANSLATOR Gui::Dialog::DlgSettingsLightSources */
DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent)
: PreferencePage(parent)
, ui(new Ui_DlgSettingsLightSources)
{
ui->setupUi(this);
setupConnection();
}
DlgSettingsLightSources::~DlgSettingsLightSources()
{
delete view;
}
void DlgSettingsLightSources::setupConnection()
{
connect(ui->checkBoxLight1, &QCheckBox::toggled,
this, &DlgSettingsLightSources::toggleLight);
connect(ui->sliderIntensity1, &QSlider::valueChanged,
this, &DlgSettingsLightSources::lightIntensity);
connect(ui->light1Color, &Gui::ColorButton::changed,
this, &DlgSettingsLightSources::lightColor);
}
void DlgSettingsLightSources::showEvent(QShowEvent* event)
{
Q_UNUSED(event)
if (!view) {
QGroupBox* box = ui->groupBoxLight;
QWidget* widget = createViewer(box);
auto grid = new QGridLayout(box);
grid->addWidget(widget);
box->setLayout(grid);
loadDirection();
}
}
void DlgSettingsLightSources::dragMotionCallback(void *data, SoDragger *drag)
{
auto lightdrag = static_cast<SoDirectionalLightDragger*>(drag); // NOLINT
auto self = static_cast<DlgSettingsLightSources*>(data);
SbRotation rotation = lightdrag->rotation.getValue();
SbVec3f dir(0, 0, -1);
rotation.multVec(dir, dir);
self->view->getHeadlight()->direction = dir;
}
QWidget* DlgSettingsLightSources::createViewer(QWidget* parent)
{
// NOLINTBEGIN
view = new Gui::View3DInventorViewer(parent);
view->setRedirectToSceneGraph(true);
view->setViewing(true);
view->setPopupMenuEnabled(false);
view->setBackgroundColor(QColor(255, 255, 255));
view->setGradientBackground(Gui::View3DInventorViewer::NoGradient);
view->setEnabledNaviCube(false);
auto root = static_cast<SoSeparator*>(view->getSceneGraph());
root->addChild(createDragger());
view->setCameraType(SoOrthographicCamera::getClassTypeId());
view->setViewDirection(SbVec3f(1, 1, -5));
view->viewAll();
// NOLINTEND
const int size = 250;
view->resize(size, size);
return view;
}
SoDirectionalLightDragger* DlgSettingsLightSources::createDragger()
{
// 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);
}
}
lightDragger->addMotionCallback(dragMotionCallback, this);
return lightDragger;
// NOLINTEND
}
void DlgSettingsLightSources::saveSettings()
{
ui->checkBoxLight1->onSave();
ui->light1Color->onSave();
ui->sliderIntensity1->onSave();
saveDirection();
}
void DlgSettingsLightSources::loadSettings()
{
ui->checkBoxLight1->onRestore();
ui->light1Color->onRestore();
ui->sliderIntensity1->onRestore();
}
void DlgSettingsLightSources::saveDirection()
{
if (lightDragger) {
ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter();
SbRotation rotation = lightDragger->rotation.getValue();
grp->SetFloat("HeadlightRotationX", rotation[0]);
grp->SetFloat("HeadlightRotationY", rotation[1]);
grp->SetFloat("HeadlightRotationZ", rotation[2]);
grp->SetFloat("HeadlightRotationW", rotation[3]);
SbVec3f dir(0, 0, -1);
rotation.multVec(dir, dir);
QString headlightDir = QString::fromLatin1("(%1,%2,%3)").arg(dir[0]).arg(dir[1]).arg(dir[2]);
grp->SetASCII("HeadlightDirection", headlightDir.toLatin1());
}
}
void DlgSettingsLightSources::loadDirection()
{
ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter();
SbRotation rotation = lightDragger->rotation.getValue();
// NOLINTBEGIN
float q1 = float(grp->GetFloat("HeadlightRotationX", rotation[0]));
float q2 = float(grp->GetFloat("HeadlightRotationY", rotation[1]));
float q3 = float(grp->GetFloat("HeadlightRotationZ", rotation[2]));
float q4 = float(grp->GetFloat("HeadlightRotationW", rotation[3]));
// NOLINTEND
rotation.setValue(q1, q2, q3, q4);
lightDragger->rotation.setValue(rotation);
SbVec3f direction(0, 0, -1);
rotation.multVec(direction, direction);
view->getHeadlight()->direction = direction;
}
void DlgSettingsLightSources::toggleLight(bool on)
{
if (view) {
view->setHeadlightEnabled(on);
}
}
void DlgSettingsLightSources::lightIntensity(int value)
{
if (view) {
float intensity = float(value) / 100.0F;
view->getHeadlight()->intensity = intensity;
}
}
void DlgSettingsLightSources::lightColor()
{
if (view) {
QColor color = ui->light1Color->color();
float red = float(color.redF());
float green = float(color.greenF());
float blue = float(color.blueF());
view->getHeadlight()->color = SbColor(red, green, blue);
}
}
void DlgSettingsLightSources::changeEvent(QEvent* event)
{
if (event->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
}
PreferencePage::changeEvent(event);
}
#include "moc_DlgSettingsLightSources.cpp"
@@ -0,0 +1,79 @@
// 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/>. *
* *
**************************************************************************/
#ifndef GUI_DIALOG_DLGSETTINGSLIGHTSOURCES_H
#define GUI_DIALOG_DLGSETTINGSLIGHTSOURCES_H
#include <Gui/PropertyPage.h>
#include <memory>
class SoDragger;
class SoDirectionalLightDragger;
namespace Gui {
class View3DInventorViewer;
namespace Dialog {
class Ui_DlgSettingsLightSources;
/**
* The DlgSettingsLightSources class implements a preference page to change settings
* for the light sources of a 3D view.
* @author Werner Mayer
*/
class DlgSettingsLightSources : public PreferencePage
{
Q_OBJECT
public:
explicit DlgSettingsLightSources(QWidget* parent = nullptr);
~DlgSettingsLightSources() override;
void saveSettings() override;
void loadSettings() override;
protected:
void changeEvent(QEvent* event) override;
void showEvent(QShowEvent* event) override;
private:
void setupConnection();
void toggleLight(bool on);
void lightIntensity(int value);
void lightColor();
void saveDirection();
void loadDirection();
QWidget* createViewer(QWidget* parent);
SoDirectionalLightDragger* createDragger();
static void dragMotionCallback(void *data, SoDragger *drag);
private:
std::unique_ptr<Ui_DlgSettingsLightSources> ui;
View3DInventorViewer* view = nullptr;
SoDirectionalLightDragger* lightDragger = nullptr;
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGSETTINGSLIGHTSOURCES_H
@@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgSettingsLightSources</class>
<widget class="QWidget" name="Gui::Dialog::DlgSettingsLightSources">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>484</width>
<height>515</height>
</rect>
</property>
<property name="windowTitle">
<string>Light Sources</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<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">
<property name="text">
<string>Light source</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>EnableHeadlight</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefColorButton" name="light1Color">
<property name="color">
<color>
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>HeadlightColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer">
<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">
<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>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBoxLight">
<property name="title">
<string>Lights</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>428</width>
<height>376</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::ColorButton</class>
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefColorButton</class>
<extends>Gui::ColorButton</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSlider</class>
<extends>QSlider</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>
<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>284</x>
<y>53</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>
</connections>
</ui>
@@ -88,7 +88,8 @@ void DlgSettingsNavigation::saveSettings()
ui->rotationCenterSize->onSave();
ui->rotationCenterColor->onSave();
ui->spinBoxZoomStep->onSave();
ui->checkBoxUseAutoRotation->onSave();
ui->checkBoxNavigationAnimations->onSave();
ui->spinBoxAnimationDuration->onSave();
ui->qspinNewDocScale->onSave();
ui->prefStepByTurn->onSave();
ui->naviCubeCorner->onSave();
@@ -115,7 +116,7 @@ void DlgSettingsNavigation::saveSettings()
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
if (ui->naviCubeFontName->currentIndex()) {
hGrp->SetASCII("FontString", ui->naviCubeFontName->currentText().toLatin1());
hGrp->SetASCII("FontString", ui->naviCubeFontName->currentText().toLatin1());
} else {
hGrp->RemoveASCII("FontString");
}
@@ -129,7 +130,8 @@ void DlgSettingsNavigation::loadSettings()
ui->rotationCenterSize->onRestore();
ui->rotationCenterColor->onRestore();
ui->spinBoxZoomStep->onRestore();
ui->checkBoxUseAutoRotation->onRestore();
ui->checkBoxNavigationAnimations->onRestore();
ui->spinBoxAnimationDuration->onRestore();
ui->qspinNewDocScale->onRestore();
ui->prefStepByTurn->onRestore();
ui->naviCubeCorner->onRestore();
@@ -191,7 +193,7 @@ void DlgSettingsNavigation::loadSettings()
QStringList familyNames = QFontDatabase::families(QFontDatabase::Any);
#endif
ui->naviCubeFontName->addItems(familyNames);
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/NaviCube");
int indexFamilyNames = familyNames.indexOf(
@@ -566,27 +566,91 @@ The value is the diameter of the sphere to fit on the screen.</string>
</widget>
</item>
<item row="5" column="0">
<widget class="Gui::PrefCheckBox" name="checkBoxUseAutoRotation">
<widget class="Gui::PrefCheckBox" name="checkBoxNavigationAnimations">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Enable animated rotations</string>
<string>Enable navigation animations</string>
</property>
<property name="text">
<string>Enable animation</string>
<string>Enable navigation animations</string>
</property>
<property name="checked">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>UseAutoRotation</cstring>
<cstring>UseNavigationAnimations</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="navigationAnimationsLabel">
<property name="toolTip">
<string>Duration of navigation animations that have a fixed duration</string>
</property>
<property name="text">
<string>Animation duration</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="Gui::PrefSpinBox" name="spinBoxAnimationDuration">
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>The duration of navigation animations in milliseconds</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>50</number>
</property>
<property name="value">
<number>250</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>AnimationDuration</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="Gui::PrefCheckBox" name="checkBoxZoomAtCursor">
<property name="toolTip">
@@ -609,7 +673,7 @@ The value is the diameter of the sphere to fit on the screen.</string>
<item row="6" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string> Zoom step</string>
<string>Zoom step</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+139 -100
View File
@@ -42,7 +42,8 @@
#include "SoQTQuarterAdaptor.h"
// NOLINTBEGIN
// clang-format off
static unsigned char fps2dfont[][12] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //
{ 0, 0, 12, 12, 0, 8, 12, 12, 12, 12, 12, 0 }, // !
@@ -140,21 +141,37 @@ static unsigned char fps2dfont[][12] = {
{ 0, 48, 8, 8, 8, 16, 12, 16, 8, 8, 8, 48 }, // }
{ 0, 0, 0, 0, 0, 0, 78, 57, 0, 0, 0, 0 } // ~
};
// clang-format on
// NOLINTEND
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(QWidget* parent, const QtGLWidget* sharewidget, Qt::WindowFlags f)
: QuarterWidget(parent, sharewidget, f), matrixaction(SbViewportRegion(100,100))
constexpr const int defaultSize = 100;
// NOLINTBEGIN(readability-implicit-bool-conversion)
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(QWidget* parent,
const QtGLWidget* sharewidget,
Qt::WindowFlags flags)
: QuarterWidget(parent, sharewidget, flags)
, matrixaction(SbViewportRegion(defaultSize, defaultSize))
{
init();
}
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(const QtGLFormat& format, QWidget* parent, const QtGLWidget* shareWidget, Qt::WindowFlags f)
: QuarterWidget(format, parent, shareWidget, f), matrixaction(SbViewportRegion(100,100))
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(const QtGLFormat& format,
QWidget* parent,
const QtGLWidget* shareWidget,
Qt::WindowFlags flags)
: QuarterWidget(format, parent, shareWidget, flags)
, matrixaction(SbViewportRegion(defaultSize, defaultSize))
{
init();
}
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(QtGLContext* context, QWidget* parent, const QtGLWidget* sharewidget, Qt::WindowFlags f)
: QuarterWidget(context, parent, sharewidget, f), matrixaction(SbViewportRegion(100,100))
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::SoQTQuarterAdaptor(QtGLContext* context,
QWidget* parent,
const QtGLWidget* sharewidget,
Qt::WindowFlags flags)
: QuarterWidget(context, parent, sharewidget, flags)
, matrixaction(SbViewportRegion(defaultSize, defaultSize))
{
init();
}
@@ -166,10 +183,11 @@ SIM::Coin3D::Quarter::SoQTQuarterAdaptor::~SoQTQuarterAdaptor()
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::init()
{
// NOLINTBEGIN
m_interactionnesting = 0;
m_seekdistance = 50.0f;
m_seekdistance = 50.0F;
m_seekdistanceabs = false;
m_seekperiod = 2.0f;
m_seekperiod = 2.0F;
m_inseekmode = false;
m_storedcamera = nullptr;
m_viewingflag = false;
@@ -179,6 +197,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::init()
getSoEventManager()->setNavigationState(SoEventManager::NO_NAVIGATION);
resetFrameCounter();
// NOLINTEND
}
@@ -198,7 +217,7 @@ QWidget* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getWidget() const
{
//we keep the function from SoQt as we want to introduce the QGraphicsView and then the GLWidget
//is separated from the Widget used in layouts again
return const_cast<SoQTQuarterAdaptor*>(this);
return const_cast<SoQTQuarterAdaptor*>(this); // NOLINT
}
QWidget* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getGLWidget() const
@@ -221,38 +240,39 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setCameraType(SoType type)
SbBool oldisperspective = cam ? cam->getTypeId().isDerivedFrom(perspectivetype) : false;
SbBool newisperspective = type.isDerivedFrom(perspectivetype);
if (oldisperspective == newisperspective) // Same old, same old..
// Same old, same old..
if (oldisperspective == newisperspective) {
return;
}
SoCamera* currentcam = getSoRenderManager()->getCamera();
SoCamera* newcamera = (SoCamera*)type.createInstance();
SoCamera* newcamera = static_cast<SoCamera*>(type.createInstance()); // NOLINT
// Transfer and convert values from one camera type to the other.
if(newisperspective) {
convertOrtho2Perspective((SoOrthographicCamera*)currentcam,
(SoPerspectiveCamera*)newcamera);
convertOrtho2Perspective(dynamic_cast<SoOrthographicCamera*>(currentcam),
dynamic_cast<SoPerspectiveCamera*>(newcamera));
}
else {
convertPerspective2Ortho((SoPerspectiveCamera*)currentcam,
(SoOrthographicCamera*)newcamera);
convertPerspective2Ortho(dynamic_cast<SoPerspectiveCamera*>(currentcam),
dynamic_cast<SoOrthographicCamera*>(newcamera));
}
getSoRenderManager()->setCamera(newcamera);
getSoEventManager()->setCamera(newcamera);
//if the superscene has a camera we need to replace it too
SoSeparator* superscene = (SoSeparator*) getSoRenderManager()->getSceneGraph();
auto superscene = dynamic_cast<SoSeparator*>(getSoRenderManager()->getSceneGraph());
SoSearchAction sa;
sa.setInterest(SoSearchAction::FIRST);
sa.setType(SoCamera::getClassTypeId());
sa.apply(superscene);
if(sa.getPath()) {
if (sa.getPath()) {
SoNode* node = sa.getPath()->getTail();
SoGroup* parent = (SoGroup*) sa.getPath()->getNodeFromTail(1);
SoGroup* parent = static_cast<SoGroup*>(sa.getPath()->getNodeFromTail(1)); // NOLINT
if(node && node->isOfType(SoCamera::getClassTypeId())) {
if (node && node->isOfType(SoCamera::getClassTypeId())) {
parent->replaceChild(node, newcamera);
}
}
@@ -274,7 +294,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertOrtho2Perspective(const So
SbRotation camrot = in->orientation.getValue();
float focaldist = in->height.getValue() / (2.0*tan(M_PI / 8.0));
float focaldist = float(in->height.getValue() / (2.0*tan(M_PI / 8.0))); // NOLINT
SbVec3f offset(0,0,focaldist-in->focalDistance.getValue());
@@ -284,7 +304,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertOrtho2Perspective(const So
out->focalDistance.setValue(focaldist);
// 45° is the default value of this field in SoPerspectiveCamera.
out->heightAngle = (float)(M_PI / 4.0);
out->heightAngle = (float)(M_PI / 4.0); // NOLINT
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertPerspective2Ortho(const SoPerspectiveCamera* in,
@@ -298,7 +318,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::convertPerspective2Ortho(const So
float focaldist = in->focalDistance.getValue();
out->height = 2.0f * focaldist * (float)tan(in->heightAngle.getValue() / 2.0);
out->height = 2.0F * focaldist * (float)tan(in->heightAngle.getValue() / 2.0); // NOLINT
}
SoCamera* SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getCamera() const
@@ -311,9 +331,8 @@ const SbViewportRegion & SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getViewportRe
return getSoRenderManager()->getViewportRegion();
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setViewing(SbBool enable)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setViewing(bool enable)
{
m_viewingflag = enable;
// Turn off the selection indicators when we go back from picking
@@ -321,12 +340,13 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setViewing(SbBool enable)
if (m_viewingflag) {
SoGLRenderAction* action = getSoRenderManager()->getGLRenderAction();
if (action)
if (action) {
SoLocateHighlight::turnOffCurrentHighlight(action);
}
}
}
SbBool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isViewing() const
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isViewing() const
{
return m_viewingflag;
}
@@ -336,14 +356,14 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::interactiveCountInc()
// Catch problems with missing interactiveCountDec() calls.
assert(m_interactionnesting < 100);
if(++m_interactionnesting == 1) {
if (++m_interactionnesting == 1) {
m_interactionStartCallback.invokeCallbacks(this);
}
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::interactiveCountDec()
{
if(--m_interactionnesting <= 0) {
if (--m_interactionnesting <= 0) {
m_interactionEndCallback.invokeCallbacks(this);
m_interactionnesting = 0;
}
@@ -354,26 +374,27 @@ int SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getInteractiveCount() const
return m_interactionnesting;
}
// clang-format off
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::addStartCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
{
m_interactionStartCallback.addCallback((SoCallbackListCB*)func, data);
m_interactionStartCallback.addCallback((SoCallbackListCB*)func, data); // NOLINT
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::removeStartCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
{
m_interactionStartCallback.removeCallback((SoCallbackListCB*)func, data);
m_interactionStartCallback.removeCallback((SoCallbackListCB*)func, data); // NOLINT
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::addFinishCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
{
m_interactionEndCallback.addCallback((SoCallbackListCB*)func, data);
m_interactionEndCallback.addCallback((SoCallbackListCB*)func, data); // NOLINT
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::removeFinishCallback(SIM::Coin3D::Quarter::SoQTQuarterAdaptorCB* func, void* data)
{
m_interactionEndCallback.removeCallback((SoCallbackListCB*)func, data);
m_interactionEndCallback.removeCallback((SoCallbackListCB*)func, data); // NOLINT
}
// clang-format on
float SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getSeekDistance() const
{
@@ -385,14 +406,14 @@ float SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getSeekTime() const
return m_seekperiod;
}
SbBool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isSeekMode() const
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isSeekMode() const
{
return m_inseekmode;
}
SbBool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isSeekValuePercentage() const
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::isSeekValuePercentage() const
{
return m_seekdistanceabs ? false : true;
return !m_seekdistanceabs;
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setPickRadius(float pickRadius)
@@ -400,14 +421,14 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setPickRadius(float pickRadius)
this->pickRadius = pickRadius;
SoEventManager* evm = this->getSoEventManager();
if (evm){
SoHandleEventAction* a = evm->getHandleEventAction();
if (a){
a->setPickRadius(pickRadius);
SoHandleEventAction* hea = evm->getHandleEventAction();
if (hea){
hea->setPickRadius(pickRadius);
}
}
}
SbBool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec2s screenpos)
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec2s& screenpos)
{
SoRayPickAction rpaction(getSoRenderManager()->getViewportRegion());
@@ -417,7 +438,7 @@ SbBool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec2s scree
SoPickedPoint* picked = rpaction.getPickedPoint();
if(!picked) {
if (!picked) {
this->interactiveCountInc(); // decremented in setSeekMode(false)
this->setSeekMode(false);
return false;
@@ -439,7 +460,8 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec3f& scenep
// move point to the camera coordinate system, consider
// transformations before camera in the scene graph
SbMatrix cameramatrix, camerainverse;
SbMatrix cameramatrix;
SbMatrix camerainverse;
getCameraCoordinateSystem(getSoRenderManager()->getCamera(),
getSceneGraph(),
cameramatrix,
@@ -448,8 +470,9 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seekToPoint(const SbVec3f& scenep
float fd = m_seekdistance;
if(!m_seekdistanceabs)
fd *= (hitpoint - getSoRenderManager()->getCamera()->position.getValue()).length()/100.0f;
if(!m_seekdistanceabs) {
fd *= (hitpoint - getSoRenderManager()->getCamera()->position.getValue()).length()/100.0F;
}
getSoRenderManager()->getCamera()->focalDistance = fd;
@@ -479,7 +502,7 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekDistance(const float dista
m_seekdistance = distance;
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekMode(SbBool enable)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekMode(bool enable)
{
if(!enable && m_seeksensor->isScheduled()) {
m_seeksensor->unschedule();
@@ -494,12 +517,15 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekTime(const float seconds)
m_seekperiod = seconds;
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekValueAsPercentage(const SbBool on)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setSeekValueAsPercentage(bool on)
{
m_seekdistanceabs = on ? false : true;
m_seekdistanceabs = !on;
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getCameraCoordinateSystem(SoCamera* camera, SoNode* root, SbMatrix& matrix, SbMatrix& inverse)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getCameraCoordinateSystem(SoCamera* camera,
SoNode* root,
SbMatrix& matrix,
SbMatrix& inverse)
{
searchaction.reset();
searchaction.setSearchingAll(true);
@@ -518,30 +544,33 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::getCameraCoordinateSystem(SoCamer
searchaction.reset();
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seeksensorCB(void* data, SoSensor* s)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::seeksensorCB(void* data, SoSensor* sensor)
{
SoQTQuarterAdaptor* thisp = (SoQTQuarterAdaptor*) data;
SoQTQuarterAdaptor* thisp = static_cast<SoQTQuarterAdaptor*>(data); // NOLINT
SbTime currenttime = SbTime::getTimeOfDay();
SoTimerSensor* sensor = (SoTimerSensor*)s;
SoTimerSensor* timer = static_cast<SoTimerSensor*>(sensor); // NOLINT
float t =
float((currenttime - sensor->getBaseTime()).getValue()) / thisp->m_seekperiod;
float par = float((currenttime - timer->getBaseTime()).getValue()) / thisp->m_seekperiod;
if((t > 1.0f) || (t + sensor->getInterval().getValue() > 1.0f)) t = 1.0f;
if ((par > 1.0F) || (par + timer->getInterval().getValue() > 1.0F)) {
par = 1.0F;
}
SbBool end = (t == 1.0f);
bool end = (par == 1.0F);
t = (float)((1.0 - cos(M_PI*t)) * 0.5);
par = (float)((1.0 - cos(M_PI * par)) * 0.5); // NOLINT
thisp->getSoRenderManager()->getCamera()->position = thisp->m_camerastartposition +
(thisp->m_cameraendposition - thisp->m_camerastartposition) * t;
(thisp->m_cameraendposition - thisp->m_camerastartposition) * par;
thisp->getSoRenderManager()->getCamera()->orientation =
SbRotation::slerp(thisp->m_camerastartorient,
thisp->m_cameraendorient,
t);
par);
if(end) thisp->setSeekMode(false);
if (end) {
thisp->setSeekMode(false);
}
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::saveHomePosition()
@@ -551,15 +580,15 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::saveHomePosition()
return;
}
SoType t = cam->getTypeId();
assert(t.isDerivedFrom(SoNode::getClassTypeId()));
assert(t.canCreateInstance());
SoType type = cam->getTypeId();
assert(type.isDerivedFrom(SoNode::getClassTypeId()));
assert(type.canCreateInstance());
if(m_storedcamera) {
m_storedcamera->unref();
}
m_storedcamera = (SoNode*)t.createInstance();
m_storedcamera = static_cast<SoNode*>(type.createInstance()); // NOLINT
m_storedcamera->ref();
m_storedcamera->copyFieldValues(getSoRenderManager()->getCamera());
@@ -576,27 +605,27 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::resetToHomePosition()
return;
}
SoType t = getSoRenderManager()->getCamera()->getTypeId();
SoType s = m_storedcamera->getTypeId();
SoType ttype = getSoRenderManager()->getCamera()->getTypeId();
SoType stype = m_storedcamera->getTypeId();
// most common case
if(t == s) {
if (ttype == stype) {
// We copy the field data directly, instead of using
// SoFieldContainer::copyContents(), for the reason described in
// detail in So@Gui@Viewer::saveHomePosition().
getSoRenderManager()->getCamera()->copyFieldValues(m_storedcamera);
}
// handle common case #1
else if(t == SoOrthographicCamera::getClassTypeId() &&
s == SoPerspectiveCamera::getClassTypeId()) {
convertPerspective2Ortho((SoPerspectiveCamera*)m_storedcamera,
(SoOrthographicCamera*)getSoRenderManager()->getCamera());
else if(ttype == SoOrthographicCamera::getClassTypeId() &&
stype == SoPerspectiveCamera::getClassTypeId()) {
convertPerspective2Ortho(dynamic_cast<SoPerspectiveCamera*>(m_storedcamera),
dynamic_cast<SoOrthographicCamera*>(getSoRenderManager()->getCamera()));
}
// handle common case #2
else if(t == SoPerspectiveCamera::getClassTypeId() &&
s == SoOrthographicCamera::getClassTypeId()) {
convertOrtho2Perspective((SoOrthographicCamera*)m_storedcamera,
(SoPerspectiveCamera*)getSoRenderManager()->getCamera());
else if(ttype == SoPerspectiveCamera::getClassTypeId() &&
stype == SoOrthographicCamera::getClassTypeId()) {
convertOrtho2Perspective(dynamic_cast<SoOrthographicCamera*>(m_storedcamera),
dynamic_cast<SoPerspectiveCamera*>(getSoRenderManager()->getCamera()));
}
// otherwise, cameras have changed in ways we don't understand since
@@ -606,7 +635,9 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::resetToHomePosition()
void
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::draw2DString(const char* str, SbVec2s glsize, SbVec2f position)
SIM::Coin3D::Quarter::SoQTQuarterAdaptor::draw2DString(const char* str,
SbVec2s glsize,
SbVec2f position)
{
// Store GL state.
glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT);
@@ -651,17 +682,19 @@ SIM::Coin3D::Quarter::SoQTQuarterAdaptor::draw2DString(const char* str, SbVec2s
glPopAttrib();
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::printString(const char* s)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::printString(const char* str)
{
int i,n;
n = strlen(s);
// NOLINTBEGIN
std::size_t len = strlen(str);
for(i = 0; i < n; i++)
glBitmap(8, 12, 0.0, 2.0, 10.0, 0.0, fps2dfont[s[i] - 32]);
for(std::size_t i = 0; i < len; i++) {
glBitmap(8, 12, 0.0, 2.0, 10.0, 0.0, fps2dfont[str[i] - 32]);
}
// NOLINTEND
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::moveCameraScreen(const SbVec2f& screenpos) {
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::moveCameraScreen(const SbVec2f& screenpos)
{
SoCamera* cam = getSoRenderManager()->getCamera();
assert(cam);
@@ -669,11 +702,12 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::moveCameraScreen(const SbVec2f& s
SbViewVolume vv = cam->getViewVolume(getGLWidget()->width() / getGLWidget()->height());
SbPlane panplane = vv.getPlane(cam->focalDistance.getValue());
constexpr const float mid = 0.5F;
SbLine line;
vv.projectPointToLine(screenpos + SbVec2f(0.5, 0.5f), line);
vv.projectPointToLine(screenpos + SbVec2f(mid, mid), line);
SbVec3f current_planept;
panplane.intersect(line, current_planept);
vv.projectPointToLine(SbVec2f(0.5f, 0.5f), line);
vv.projectPointToLine(SbVec2f(mid, mid), line);
SbVec3f old_planept;
panplane.intersect(line, old_planept);
@@ -682,30 +716,31 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::moveCameraScreen(const SbVec2f& s
cam->position = cam->position.getValue() - (current_planept - old_planept);
}
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::processSoEvent(const SoEvent* event) {
bool SIM::Coin3D::Quarter::SoQTQuarterAdaptor::processSoEvent(const SoEvent* event)
{
const SoType type(event->getTypeId());
constexpr const float delta = 0.1F;
if(type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
const SoKeyboardEvent* keyevent = static_cast<const SoKeyboardEvent*>(event);
const SoKeyboardEvent* keyevent = static_cast<const SoKeyboardEvent*>(event); // NOLINT
if(keyevent->getState() == SoButtonEvent::DOWN) {
switch(keyevent->getKey()) {
case SoKeyboardEvent::LEFT_ARROW:
moveCameraScreen(SbVec2f(-0.1f, 0.0f));
moveCameraScreen(SbVec2f(-delta, 0.0F));
return true;
case SoKeyboardEvent::UP_ARROW:
moveCameraScreen(SbVec2f(0.0f, 0.1f));
moveCameraScreen(SbVec2f(0.0F, delta));
return true;
case SoKeyboardEvent::RIGHT_ARROW:
moveCameraScreen(SbVec2f(0.1f, 0.0f));
moveCameraScreen(SbVec2f(delta, 0.0F));
return true;
case SoKeyboardEvent::DOWN_ARROW:
moveCameraScreen(SbVec2f(0.0f, -0.1f));
moveCameraScreen(SbVec2f(0.0F, -delta));
return true;
default:
@@ -730,31 +765,35 @@ void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::paintEvent(QPaintEvent* event)
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::resetFrameCounter()
{
this->framecount = 0;
this->frametime = 0.0f;
this->drawtime = 0.0f;
this->frametime = 0.0F;
this->drawtime = 0.0F;
this->starttime = SbTime::getTimeOfDay().getValue();
this->framesPerSecond = SbVec2f(0, 0);
}
SbVec2f SIM::Coin3D::Quarter::SoQTQuarterAdaptor::addFrametime(double starttime)
{
constexpr const double FPS_FACTOR = 0.7;
constexpr const double FIVE_SECS = 5000.0;
constexpr const float ONE_SEC = 1000.0F;
this->framecount++;
double timeofday = SbTime::getTimeOfDay().getValue();
// draw time is the actual time spent on rendering
double drawtime = timeofday - starttime;
#define FPS_FACTOR 0.7
this->drawtime = (drawtime*FPS_FACTOR) + this->drawtime*(1.0-FPS_FACTOR);
this->drawtime = (drawtime*FPS_FACTOR) + this->drawtime*(1.0 - FPS_FACTOR);
// frame time is the time spent since the last frame. There could an
// indefinite pause between the last frame because the scene is not
// changing. So we limit the skew to 5 second.
double frametime = std::min(timeofday-this->starttime, std::max(drawtime,5000.0));
this->frametime = (frametime*FPS_FACTOR) + this->frametime*(1.0-FPS_FACTOR);
double frametime = std::min(timeofday-this->starttime, std::max(drawtime, FIVE_SECS));
this->frametime = (frametime*FPS_FACTOR) + this->frametime*(1.0 - FPS_FACTOR);
this->starttime = timeofday;
return {1000 * float(this->drawtime), 1.0F / float(this->frametime)};
return {ONE_SEC * float(this->drawtime), 1.0F / float(this->frametime)};
}
// NOLINTEND(readability-implicit-bool-conversion)
#include "moc_SoQTQuarterAdaptor.cpp"
+47 -35
View File
@@ -47,9 +47,17 @@ class QUARTER_DLL_API SoQTQuarterAdaptor : public QuarterWidget {
Q_OBJECT
public:
explicit SoQTQuarterAdaptor(QWidget* parent = nullptr, const QtGLWidget* sharewidget = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
explicit SoQTQuarterAdaptor(const QtGLFormat& format, QWidget* parent = nullptr, const QtGLWidget* shareWidget = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
explicit SoQTQuarterAdaptor(QtGLContext* context, QWidget* parent = nullptr, const QtGLWidget* sharewidget = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
explicit SoQTQuarterAdaptor(QWidget* parent = nullptr,
const QtGLWidget* sharewidget = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags());
explicit SoQTQuarterAdaptor(const QtGLFormat& format,
QWidget* parent = nullptr,
const QtGLWidget* shareWidget = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags());
explicit SoQTQuarterAdaptor(QtGLContext* context,
QWidget* parent = nullptr,
const QtGLWidget* sharewidget = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags());
~SoQTQuarterAdaptor() override;
//the functions available in soqtviewer but missing in quarter
@@ -63,8 +71,8 @@ public:
const SbViewportRegion & getViewportRegion() const;
virtual void setViewing(SbBool enable);
SbBool isViewing() const;
virtual void setViewing(bool enable);
bool isViewing() const;
void interactiveCountInc();
void interactiveCountDec();
@@ -75,72 +83,76 @@ public:
void removeStartCallback(SoQTQuarterAdaptorCB* func, void* data = nullptr);
void removeFinishCallback(SoQTQuarterAdaptorCB* func, void* data = nullptr);
virtual void setSeekMode(SbBool enable);
SbBool isSeekMode() const;
SbBool seekToPoint(const SbVec2s screenpos);
virtual void setSeekMode(bool enable);
bool isSeekMode() const;
bool seekToPoint(const SbVec2s& screenpos);
void seekToPoint(const SbVec3f& scenepos);
void setSeekTime(const float seconds);
void setSeekTime(float seconds);
float getSeekTime() const;
void setSeekDistance(const float distance);
void setSeekDistance(float distance);
float getSeekDistance() const;
void setSeekValueAsPercentage(const SbBool on);
SbBool isSeekValuePercentage() const;
void setSeekValueAsPercentage(bool on);
bool isSeekValuePercentage() const;
virtual float getPickRadius() const {return this->pickRadius;}
virtual void setPickRadius(float pickRadius);
virtual void saveHomePosition();
virtual void resetToHomePosition();
virtual bool hasHomePosition() const {return m_storedcamera;}
virtual bool hasHomePosition() const
{
return m_storedcamera != nullptr;
}
void setSceneGraph(SoNode* root) override {
void setSceneGraph(SoNode* root) override
{
QuarterWidget::setSceneGraph(root);
}
bool processSoEvent(const SoEvent* event) override;
void paintEvent(QPaintEvent*) override;
void paintEvent(QPaintEvent* event) override;
//this functions still need to be ported
virtual void afterRealizeHook() {} //enables spacenav and joystick in soqt, dunno if this is needed
private:
void init();
void convertPerspective2Ortho(const SoPerspectiveCamera* in, SoOrthographicCamera* out);
void convertOrtho2Perspective(const SoOrthographicCamera* in, SoPerspectiveCamera* out);
static void convertPerspective2Ortho(const SoPerspectiveCamera* in, SoOrthographicCamera* out);
static void convertOrtho2Perspective(const SoOrthographicCamera* in, SoPerspectiveCamera* out);
void getCameraCoordinateSystem(SoCamera * camera, SoNode * root, SbMatrix & matrix, SbMatrix & inverse);
static void seeksensorCB(void * data, SoSensor * s);
static void seeksensorCB(void * data, SoSensor * sensor);
void moveCameraScreen(const SbVec2f & screenpos);
void resetFrameCounter();
SbVec2f addFrametime(double ft);
bool m_viewingflag;
int m_interactionnesting;
bool m_viewingflag = false;
int m_interactionnesting = 0;
SoCallbackList m_interactionStartCallback;
SoCallbackList m_interactionEndCallback;
double frametime;
double drawtime;
double starttime;
int framecount;
double frametime = 0.0;
double drawtime = 0.0;
double starttime = 0.0;
int framecount = 0.0;
// Seek functionality
SoTimerSensor* m_seeksensor;
float m_seekperiod;
SbBool m_inseekmode;
SoTimerSensor* m_seeksensor = nullptr;
float m_seekperiod = 0.0F;
bool m_inseekmode = false;
SbVec3f m_camerastartposition, m_cameraendposition;
SbRotation m_camerastartorient, m_cameraendorient;
float m_seekdistance;
SbBool m_seekdistanceabs;
float m_seekdistance = 0.0F;
bool m_seekdistanceabs = false;
SoSearchAction searchaction;
SoGetMatrixAction matrixaction;
float pickRadius;
float pickRadius = 0.0F;
// Home position storage.
SoNode * m_storedcamera;
SoNode * m_storedcamera = nullptr;
protected:
void draw2DString(const char * str, SbVec2s glsize, SbVec2f position);
void printString(const char * s);
SbVec2f framesPerSecond;
static void draw2DString(const char * str, SbVec2s glsize, SbVec2f position);
static void printString(const char * str);
SbVec2f framesPerSecond; // NOLINT
};
} //Quarter
+1 -1
View File
@@ -529,7 +529,7 @@ void InteractiveScale::collectPoint(const SbVec3f& pos3d)
midPoint = (points[0] + points[1]) / 2;
measureLabel->startEdit(getDistance(points[1]), this);
measureLabel->startEdit(getDistance(points[1]), this, true);
Q_EMIT enableApplyBtn();
}
+3
View File
@@ -57,6 +57,7 @@
#include "View3DInventor.h"
#include "View3DSettings.h"
#include "Application.h"
#include "BitmapFactory.h"
#include "Camera.h"
#include "Document.h"
#include "FileDialog.h"
@@ -134,6 +135,8 @@ View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent,
stopSpinTimer = new QTimer(this);
connect(stopSpinTimer, &QTimer::timeout, this, &View3DInventor::stopAnimating);
setWindowIcon(Gui::BitmapFactory().pixmap("Document"));
}
View3DInventor::~View3DInventor()
File diff suppressed because it is too large Load Diff
+60 -58
View File
@@ -54,11 +54,11 @@ class SoShapeHints;
class SoMaterial;
class SoRotationXYZ;
class SbSphereSheetProjector;
class SoEventCallback;
class SoEventCallback; // NOLINT
class SbBox2s;
class SoVectorizeAction;
class QImage;
class SoGroup;
class SoGroup; // NOLINT
class SoPickStyle;
class NaviCube;
class SoClipPlane;
@@ -153,38 +153,40 @@ public:
void onSelectionChanged(const SelectionChanges &Reason) override;
SoDirectionalLight* getBacklight() const;
void setBacklight(SbBool on);
SbBool isBacklight() const;
void setBacklightEnabled(bool on);
bool isBacklightEnabled() const;
void setSceneGraph (SoNode *root) override;
SbBool searchNode(SoNode*) const;
bool searchNode(SoNode*) const;
void setAnimationEnabled(const SbBool enable);
SbBool isAnimationEnabled() const;
void setAnimationEnabled(bool enable);
bool isAnimationEnabled() const;
void setPopupMenuEnabled(const SbBool on);
SbBool isPopupMenuEnabled() const;
void setPopupMenuEnabled(bool on);
bool isPopupMenuEnabled() const;
void startAnimating(const SbVec3f& axis, float velocity);
void startAnimation(const SbRotation& orientation, const SbVec3f& rotationCenter,
const SbVec3f& translation, int duration = -1, bool wait = false);
void startSpinningAnimation(const SbVec3f& axis, float velocity);
void stopAnimating();
SbBool isAnimating() const;
bool isAnimating() const;
void setFeedbackVisibility(const SbBool enable);
SbBool isFeedbackVisible() const;
void setFeedbackVisibility(bool enable);
bool isFeedbackVisible() const;
void setFeedbackSize(const int size);
void setFeedbackSize(int size);
int getFeedbackSize() const;
/// Get the preferred samples from the user settings
static int getNumSamples();
void setRenderType(const RenderType type);
void setRenderType(RenderType type);
RenderType getRenderType() const;
void renderToFramebuffer(QtGLFramebufferObject*);
QImage grabFramebuffer();
void imageFromFramebuffer(int width, int height, int samples,
const QColor& bgcolor, QImage& img);
void setViewing(SbBool enable) override;
virtual void setCursorEnabled(SbBool enable);
void setViewing(bool enable) override;
virtual void setCursorEnabled(bool enable);
void addGraphicsItem(GLGraphicsItem*);
void removeGraphicsItem(GLGraphicsItem*);
@@ -195,11 +197,11 @@ public:
/** @name Handling of view providers */
//@{
/// Checks if the view provider is a top-level object of the scene
SbBool hasViewProvider(ViewProvider*) const;
bool hasViewProvider(ViewProvider*) const;
/// Checks if the view provider is part of the scene.
/// In contrast to hasViewProvider() this method also checks if the view
/// provider is a child of another view provider
SbBool containsViewProvider(const ViewProvider*) const;
bool containsViewProvider(const ViewProvider*) const;
/// adds an ViewProvider to the view, e.g. from a feature
void addViewProvider(ViewProvider*);
/// remove a ViewProvider
@@ -210,9 +212,9 @@ public:
/// get all view providers of given type
std::vector<ViewProvider*> getViewProvidersOfType(const Base::Type& typeId) const;
/// set the ViewProvider in special edit mode
void setEditingViewProvider(Gui::ViewProvider* p, int ModNum);
void setEditingViewProvider(Gui::ViewProvider* vp, int ModNum);
/// return whether a view provider is edited
SbBool isEditingViewProvider() const;
bool isEditingViewProvider() const;
/// reset from edit mode
void resetEditingViewProvider();
void setupEditingRoot(SoNode *node=nullptr, const Base::Matrix4D *mat=nullptr);
@@ -235,10 +237,10 @@ public:
/** @name Making pictures */
//@{
/**
* Creates an image with width \a w and height \a h of the current scene graph
* using a multi-sampling of \a s and exports the rendered scenegraph to an image.
* Creates an image with width \a width and height \a height of the current scene graph
* using a multi-sampling of \a sample and exports the rendered scenegraph to an image.
*/
void savePicture(int w, int h, int s, const QColor&, QImage&) const;
void savePicture(int width, int height, int sample, const QColor& bg, QImage& img) const;
void saveGraphic(int pagesize, const QColor&, SoVectorizeAction* va) const;
//@}
/**
@@ -255,8 +257,8 @@ public:
std::vector<SbVec2f> getGLPolygon(SelectionRole* role=nullptr) const;
std::vector<SbVec2f> getGLPolygon(const std::vector<SbVec2s>&) const;
const std::vector<SbVec2s>& getPolygon(SelectionRole* role=nullptr) const;
void setSelectionEnabled(const SbBool enable);
SbBool isSelectionEnabled() const;
void setSelectionEnabled(bool enable);
bool isSelectionEnabled() const;
//@}
/// Returns the screen coordinates of the origin of the path's tail object
@@ -265,14 +267,14 @@ public:
/** @name Edit methods */
//@{
void setEditing(SbBool edit);
SbBool isEditing() const { return this->editing; }
void setEditing(bool edit);
bool isEditing() const { return this->editing; }
void setEditingCursor (const QCursor& cursor);
void setComponentCursor(const QCursor& cursor);
void setRedirectToSceneGraph(SbBool redirect) { this->redirected = redirect; }
SbBool isRedirectedToSceneGraph() const { return this->redirected; }
void setRedirectToSceneGraphEnabled(SbBool enable) { this->allowredir = enable; }
SbBool isRedirectToSceneGraphEnabled() const { return this->allowredir; }
void setRedirectToSceneGraph(bool redirect) { this->redirected = redirect; }
bool isRedirectedToSceneGraph() const { return this->redirected; }
void setRedirectToSceneGraphEnabled(bool enable) { this->allowredir = enable; }
bool isRedirectToSceneGraphEnabled() const { return this->allowredir; }
//@}
/** @name Pick actions */
@@ -281,7 +283,7 @@ public:
bool pickPoint(const SbVec2s& pos,SbVec3f &point,SbVec3f &norm) const;
SoPickedPoint* pickPoint(const SbVec2s& pos) const;
const SoPickedPoint* getPickedPoint(SoEventCallback * n) const;
SbBool pubSeekToPoint(const SbVec2s& pos);
bool pubSeekToPoint(const SbVec2s& pos);
void pubSeekToPoint(const SbVec3f& pos);
//@}
@@ -373,9 +375,9 @@ public:
* \a true the reorientation is animated, otherwise its directly
* set.
*/
void setCameraOrientation(const SbRotation& rot, SbBool moveTocenter=false);
void setCameraType(SoType t) override;
void moveCameraTo(const SbRotation& rot, const SbVec3f& pos, int steps, int ms);
void setCameraOrientation(const SbRotation& orientation, bool moveToCenter = false);
void setCameraType(SoType type) override;
void moveCameraTo(const SbRotation& orientation, const SbVec3f& position, int duration = -1);
/**
* Zooms the viewport to the size of the bounding box.
*/
@@ -410,17 +412,17 @@ public:
const SbColor& midColor);
void setNavigationType(Base::Type);
void setAxisCross(bool b);
void setAxisCross(bool on);
bool hasAxisCross();
void showRotationCenter(bool show);
void setEnabledFPSCounter(bool b);
void setEnabledNaviCube(bool b);
void setEnabledFPSCounter(bool on);
void setEnabledNaviCube(bool on);
bool isEnabledNaviCube() const;
void setNaviCubeCorner(int);
NaviCube* getNaviCube() const;
void setEnabledVBO(bool b);
void setEnabledVBO(bool on);
bool isEnabledVBO() const;
void setRenderCache(int);
@@ -436,21 +438,21 @@ public:
virtual PyObject *getPyObject();
protected:
GLenum getInternalTextureFormat() const;
static GLenum getInternalTextureFormat();
void renderScene();
void renderFramebuffer();
void renderGLImage();
void animatedViewAll(int steps, int ms);
void actualRedraw() override;
void setSeekMode(SbBool enable) override;
void setSeekMode(bool on) override;
void afterRealizeHook() override;
bool processSoEvent(const SoEvent * ev) override;
void dropEvent (QDropEvent * e) override;
void dragEnterEvent (QDragEnterEvent * e) override;
void dragMoveEvent(QDragMoveEvent *e) override;
void dragLeaveEvent(QDragLeaveEvent *e) override;
SbBool processSoEventBase(const SoEvent * const ev);
void printDimension();
void dropEvent (QDropEvent * ev) override;
void dragEnterEvent (QDragEnterEvent * ev) override;
void dragMoveEvent(QDragMoveEvent* ev) override;
void dragLeaveEvent(QDragLeaveEvent* ev) override;
bool processSoEventBase(const SoEvent * const ev);
void printDimension() const;
void selectAll();
private:
@@ -463,13 +465,13 @@ private:
static void interactionLoggerCB(void * ud, SoAction* action);
private:
static void selectCB(void * closure, SoPath * p);
static void deselectCB(void * closure, SoPath * p);
static SoPath * pickFilterCB(void * data, const SoPickedPoint * pick);
static void selectCB(void * viewer, SoPath * path);
static void deselectCB(void * viewer, SoPath * path);
static SoPath * pickFilterCB(void * viewer, const SoPickedPoint * pp);
void initialize();
void drawAxisCross();
static void drawArrow();
void drawSingleBackground(const QColor&);
static void drawSingleBackground(const QColor&);
void setCursorRepresentation(int mode);
void aboutToDestroyGLContext() override;
void createStandardCursors(double);
@@ -504,11 +506,11 @@ private:
RenderType renderType;
QtGLFramebufferObject* framebuffer;
QImage glImage;
SbBool shading;
bool shading;
SoSwitch *dimensionRoot;
// small axis cross in the corner
SbBool axiscrossEnabled;
bool axiscrossEnabled;
int axiscrossSize;
// big one in the middle
SoShapeScale* axisCross;
@@ -519,12 +521,12 @@ private:
//stuff needed to draw the fps counter
bool fpsEnabled;
bool vboEnabled;
SbBool naviCubeEnabled;
bool naviCubeEnabled;
SbBool editing;
bool editing;
QCursor editCursor, zoomCursor, panCursor, spinCursor;
SbBool redirected;
SbBool allowredir;
bool redirected;
bool allowredir;
std::string overrideMode;
Gui::Document* guiDocument = nullptr;
+8 -8
View File
@@ -777,10 +777,10 @@ Py::Object View3DInventorPy::getCameraOrientation()
Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args)
{
PyObject* p=nullptr;
int steps = 20;
int ms = 30;
if (!PyArg_ParseTuple(args.ptr(), "|O!ii",&Base::PlacementPy::Type,&p,&steps,&ms))
PyObject* p = nullptr;
int steps; // Unused but kept as parameter to not break the Python interface
int duration = -1; // Duration in ms, will be replaced with User parameter:BaseApp/Preferences/View/AnimationDuration when not explicitly provided
if (!PyArg_ParseTuple(args.ptr(), "|O!ii", &Base::PlacementPy::Type, &p, &steps, &duration))
throw Py::Exception();
if (p) {
@@ -791,7 +791,7 @@ Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args)
rot.getValue(q0,q1,q2,q3);
getView3DIventorPtr()->getViewer()->moveCameraTo(
SbRotation((float)q0, (float)q1, (float)q2, (float)q3),
SbVec3f((float)pos.x, (float)pos.y, (float)pos.z), steps, ms);
SbVec3f((float)pos.x, (float)pos.y, (float)pos.z), duration);
}
SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
@@ -810,11 +810,11 @@ Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args)
Py::Object View3DInventorPy::startAnimating(const Py::Tuple& args)
{
float x,y,z;
float x, y, z;
float velocity;
if (!PyArg_ParseTuple(args.ptr(), "ffff", &x,&y,&z,&velocity))
if (!PyArg_ParseTuple(args.ptr(), "ffff", &x, &y, &z, &velocity))
throw Py::Exception();
getView3DIventorPtr()->getViewer()->startAnimating(SbVec3f(x,y,z),velocity);
getView3DIventorPtr()->getViewer()->startSpinningAnimation(SbVec3f(x, y, z), velocity);
return Py::None();
}
+12 -5
View File
@@ -74,7 +74,7 @@ void View3DSettings::applySettings()
OnChange(*hGrp,"CornerCoordSystem");
OnChange(*hGrp,"CornerCoordSystemSize");
OnChange(*hGrp,"ShowAxisCross");
OnChange(*hGrp,"UseAutoRotation");
OnChange(*hGrp,"UseNavigationAnimations");
OnChange(*hGrp,"Gradient");
OnChange(*hGrp,"RadialGradient");
OnChange(*hGrp,"BackgroundColor");
@@ -87,6 +87,7 @@ void View3DSettings::applySettings()
OnChange(*hGrp,"UseVBO");
OnChange(*hGrp,"RenderCache");
OnChange(*hGrp,"Orthographic");
OnChange(*hGrp,"EnableHeadlight");
OnChange(*hGrp,"HeadlightColor");
OnChange(*hGrp,"HeadlightDirection");
OnChange(*hGrp,"HeadlightIntensity");
@@ -108,7 +109,13 @@ void View3DSettings::applySettings()
void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason)
{
const ParameterGrp& rGrp = static_cast<ParameterGrp&>(rCaller);
if (strcmp(Reason,"HeadlightColor") == 0) {
if (strcmp(Reason,"EnableHeadlight") == 0) {
bool enable = rGrp.GetBool("EnableHeadlight", true);
for (auto _viewer : _viewers) {
_viewer->setHeadlightEnabled(enable);
}
}
else if (strcmp(Reason,"HeadlightColor") == 0) {
unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white)
float transparency;
SbColor headlightColor;
@@ -137,7 +144,7 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
}
else if (strcmp(Reason,"EnableBacklight") == 0) {
for (auto _viewer : _viewers) {
_viewer->setBacklight(rGrp.GetBool("EnableBacklight", false));
_viewer->setBacklightEnabled(rGrp.GetBool("EnableBacklight", false));
}
}
else if (strcmp(Reason,"BacklightColor") == 0) {
@@ -287,9 +294,9 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M
_viewer->setAxisCross(rGrp.GetBool("ShowAxisCross", false));
}
}
else if (strcmp(Reason,"UseAutoRotation") == 0) {
else if (strcmp(Reason,"UseNavigationAnimations") == 0) {
for (auto _viewer : _viewers) {
_viewer->setAnimationEnabled(rGrp.GetBool("UseAutoRotation", false));
_viewer->setAnimationEnabled(rGrp.GetBool("UseNavigationAnimations", true));
}
}
else if (strcmp(Reason,"Gradient") == 0 || strcmp(Reason,"RadialGradient") == 0) {
+4
View File
@@ -36,6 +36,7 @@
#include "PreferencePages/DlgSettingsEditor.h"
#include "PreferencePages/DlgSettingsGeneral.h"
#include "PreferencePages/DlgSettingsMacroImp.h"
#include "PreferencePages/DlgSettingsLightSources.h"
#include "PreferencePages/DlgSettingsNavigation.h"
#include "PreferencePages/DlgSettingsNotificationArea.h"
#include "PreferencePages/DlgSettingsPythonConsole.h"
@@ -58,6 +59,7 @@
using namespace Gui;
using namespace Gui::Dialog;
// clang-format off
/**
* Registers all preference pages or widgets to create them dynamically at any later time.
*/
@@ -74,6 +76,7 @@ WidgetFactorySupplier::WidgetFactorySupplier()
new PrefPageProducer<DlgSettingsNotificationArea> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettingsReportView> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettings3DViewImp> ( QT_TRANSLATE_NOOP("QObject","Display") );
new PrefPageProducer<DlgSettingsLightSources> ( QT_TRANSLATE_NOOP("QObject","Display") );
new PrefPageProducer<DlgSettingsUI> ( QT_TRANSLATE_NOOP("QObject","Display") );
new PrefPageProducer<DlgSettingsNavigation> ( QT_TRANSLATE_NOOP("QObject","Display") );
new PrefPageProducer<DlgSettingsViewColor> ( QT_TRANSLATE_NOOP("QObject","Display") );
@@ -122,3 +125,4 @@ WidgetFactorySupplier::WidgetFactorySupplier()
new WidgetProducer<Gui::DoubleSpinBox>;
new WidgetProducer<Gui::QuantitySpinBox>;
}
// clang-format on
+18 -25
View File
@@ -301,9 +301,10 @@ class CommandBuildingPart:
ss += "]"
FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create BuildingPart"))
FreeCADGui.addModule("Arch")
FreeCADGui.doCommand("obj = Arch.makeBuildingPart("+ss+")")
FreeCADGui.addModule("Draft")
FreeCADGui.doCommand("obj.Placement = FreeCAD.DraftWorkingPlane.getPlacement()")
FreeCADGui.addModule("WorkingPlane")
FreeCADGui.doCommand("obj = Arch.makeBuildingPart("+ss+")")
FreeCADGui.doCommand("obj.Placement = WorkingPlane.get_working_plane().get_placement()")
FreeCADGui.doCommand("Draft.autogroup(obj)")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
@@ -963,30 +964,22 @@ class ViewProviderBuildingPart:
FreeCADGui.Selection.clearSelection()
def setWorkingPlane(self,restore=False):
vobj = self.Object.ViewObject
if hasattr(self,"Object") and hasattr(FreeCAD,"DraftWorkingPlane"):
import FreeCADGui
autoclip = False
if hasattr(self.Object.ViewObject,"AutoCutView"):
autoclip = self.Object.ViewObject.AutoCutView
if restore:
FreeCAD.DraftWorkingPlane.restore()
if autoclip:
self.Object.ViewObject.CutView = False
else:
FreeCAD.DraftWorkingPlane.save()
FreeCADGui.runCommand("Draft_SelectPlane")
if autoclip:
self.Object.ViewObject.CutView = True
if hasattr(FreeCADGui,"Snapper"):
FreeCADGui.Snapper.setGrid()
if hasattr(FreeCADGui,"draftToolBar"):
if restore and hasattr(self,"wptext"):
FreeCADGui.draftToolBar.wplabel.setText(self.wptext)
else:
self.wptext = FreeCADGui.draftToolBar.wplabel.text()
FreeCADGui.draftToolBar.wplabel.setText(self.Object.Label)
FreeCAD.DraftWorkingPlane.lastBuildingPart = self.Object.Name
import WorkingPlane
wp = WorkingPlane.get_working_plane(update=False)
autoclip = False
if hasattr(vobj,"AutoCutView"):
autoclip = vobj.AutoCutView
if restore:
if wp.label.rstrip("*") == self.Object.Label:
wp._previous()
if autoclip:
vobj.CutView = False
else:
wp.align_to_selection()
if autoclip:
vobj.CutView = True
def writeCamera(self):
+2 -2
View File
@@ -124,8 +124,8 @@ class CommandArchCurtainWall:
else:
# interactive line drawing
self.points = []
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import WorkingPlane
WorkingPlane.get_working_plane()
if hasattr(FreeCADGui,"Snapper"):
FreeCADGui.Snapper.getPoint(callback=self.getPoint)
+3 -2
View File
@@ -46,8 +46,9 @@ __url__ = "http://www.freecad.org"
def getPlanWithLine(line):
"""Function to make a plane along Normal plan"""
import Part
plan = FreeCAD.DraftWorkingPlane
w = plan.getNormal()
import WorkingPlane
plan = WorkingPlane.get_working_plane()
w = plan.axis
part = Part.Shape(line)
out = part.extrude(w)
return out
+2 -2
View File
@@ -583,8 +583,8 @@ class Nester:
# flatten the polygon on the XY plane
wp = WorkingPlane.plane()
wp.alignToPointAndAxis(face.CenterOfMass,face.normalAt(0,0))
wp = WorkingPlane.PlaneBase()
wp.align_to_point_and_axis(face.CenterOfMass,face.normalAt(0,0))
pverts = []
for v in verts:
vx = DraftVecUtils.project(v,wp.u)
+3 -5
View File
@@ -165,9 +165,9 @@ class CommandPanel:
return
# interactive mode
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import WorkingPlane
WorkingPlane.get_working_plane()
self.points = []
self.tracker = DraftTrackers.boxTracker()
self.tracker.width(self.Width)
@@ -434,8 +434,6 @@ class _Panel(ArchComponent.Component):
if self.clone(obj):
return
import Part #, DraftGeomUtils
layers = []
length = 0
width = 0
+8 -7
View File
@@ -74,7 +74,8 @@ def makeSectionPlane(objectslist=None,name=None):
for o in Draft.get_group_contents(objectslist):
if hasattr(o,"Shape") and hasattr(o.Shape,"BoundBox"):
bb.add(o.Shape.BoundBox)
obj.Placement = FreeCAD.DraftWorkingPlane.getPlacement()
import WorkingPlane
obj.Placement = WorkingPlane.get_working_plane().get_placement()
obj.Placement.Base = bb.Center
if FreeCAD.GuiUp:
margin = bb.XLength*0.1
@@ -391,13 +392,13 @@ def getSVG(source,
svgcache = ''
# render using the Arch Vector Renderer
import ArchVRM, WorkingPlane
wp = WorkingPlane.plane()
wp = WorkingPlane.PlaneBase()
pl = FreeCAD.Placement(source.Placement)
if source.ViewObject and hasattr(source.ViewObject,"CutMargin"):
mv = pl.multVec(FreeCAD.Vector(0,0,1))
mv.multiply(source.ViewObject.CutMargin)
pl.move(mv)
wp.setFromPlacement(pl)
wp.align_to_placement(pl)
#wp.inverse()
render = ArchVRM.Renderer()
render.setWorkingPlane(wp)
@@ -748,9 +749,9 @@ def getCoinSVG(cutplane,objs,cameradata=None,linewidth=0.2,singleface=False,face
factor = None
trans = None
import WorkingPlane
wp = WorkingPlane.plane()
wp.alignToPointAndAxis_SVG(Vector(0,0,0),cutplane.normalAt(0,0),0)
p = wp.getLocalCoords(markervec)
wp = WorkingPlane.PlaneBase()
wp.align_to_point_and_axis_svg(Vector(0,0,0),cutplane.normalAt(0,0),0)
p = wp.get_local_coords(markervec)
orlength = FreeCAD.Vector(p.x,p.y,0).Length
marker = re.findall("<line x1=.*?stroke=\"\#ffffff\".*?\/>",svg)
if marker:
@@ -763,7 +764,7 @@ def getCoinSVG(cutplane,objs,cameradata=None,linewidth=0.2,singleface=False,face
p2 = FreeCAD.Vector(x2,y2,0)
factor = orlength/p2.sub(p1).Length
if factor:
orig = wp.getLocalCoords(FreeCAD.Vector(boundbox.XMin,boundbox.YMin,boundbox.ZMin))
orig = wp.get_local_coords(FreeCAD.Vector(boundbox.XMin,boundbox.YMin,boundbox.ZMin))
orig = FreeCAD.Vector(orig.x,-orig.y,0)
scaledp1 = FreeCAD.Vector(p1.x*factor,p1.y*factor,0)
trans = orig.sub(scaledp1)
+12 -13
View File
@@ -170,9 +170,8 @@ def placeAlongEdge(p1,p2,horizontal=False):
pl = FreeCAD.Placement()
pl.Base = p1
up = FreeCAD.Vector(0,0,1)
if hasattr(FreeCAD,"DraftWorkingPlane"):
up = FreeCAD.DraftWorkingPlane.axis
import WorkingPlane
up = WorkingPlane.get_working_plane(update=False).axis
zaxis = p2.sub(p1)
yaxis = up.cross(zaxis)
if yaxis.Length > 0:
@@ -290,6 +289,7 @@ class _CommandStructure:
self.bpoint = None
self.bmode = False
self.precastvalues = None
self.wp = None
sel = FreeCADGui.Selection.getSelection()
if sel:
st = Draft.getObjectsOfType(sel,"Structure")
@@ -309,15 +309,15 @@ class _CommandStructure:
return
# interactive mode
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import WorkingPlane
self.wp = WorkingPlane.get_working_plane()
self.points = []
self.tracker = DraftTrackers.boxTracker()
self.tracker.width(self.Width)
self.tracker.height(self.Height)
self.tracker.length(self.Length)
self.tracker.setRotation(FreeCAD.DraftWorkingPlane.getRotation().Rotation)
self.tracker.setRotation(self.wp.get_placement().Rotation)
self.tracker.on()
self.precast = ArchPrecast._PrecastTaskPanel()
self.dents = ArchPrecast._DentsTaskPanel()
@@ -344,6 +344,7 @@ class _CommandStructure:
horiz = True # determines the type of rotation to apply to the final object
FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Structure"))
FreeCADGui.addModule("Arch")
FreeCADGui.addModule("WorkingPlane")
if self.Profile is not None:
try: # try to update latest precast values - fails if dialog has been destroyed already
self.precastvalues = self.precast.getValues()
@@ -361,8 +362,7 @@ class _CommandStructure:
delta = FreeCAD.Vector(0,0-self.Width/2,0)
else:
delta = FreeCAD.Vector(-self.Length/2,-self.Width/2,0)
if hasattr(FreeCAD,"DraftWorkingPlane"):
delta = FreeCAD.DraftWorkingPlane.getRotation().multVec(delta)
delta = self.wp.get_global_coords(delta,as_vector=True)
point = point.add(delta)
if self.bpoint:
self.bpoint = self.bpoint.add(delta)
@@ -396,7 +396,8 @@ class _CommandStructure:
FreeCADGui.doCommand('s.Placement = Arch.placeAlongEdge('+DraftVecUtils.toString(self.bpoint)+","+DraftVecUtils.toString(point)+","+str(horiz)+")")
else:
FreeCADGui.doCommand('s.Placement.Base = '+DraftVecUtils.toString(point))
FreeCADGui.doCommand('s.Placement.Rotation = s.Placement.Rotation.multiply(FreeCAD.DraftWorkingPlane.getRotation().Rotation)')
FreeCADGui.doCommand('wp = WorkingPlane.get_working_plane()')
FreeCADGui.doCommand('s.Placement.Rotation = s.Placement.Rotation.multiply(wp.get_placement().Rotation)')
FreeCADGui.addModule("Draft")
FreeCADGui.doCommand("Draft.autogroup(s)")
@@ -543,16 +544,14 @@ class _CommandStructure:
delta = Vector(0,0,self.Height/2)
else:
delta = Vector(self.Length/2,0,0)
if hasattr(FreeCAD,"DraftWorkingPlane"):
delta = FreeCAD.DraftWorkingPlane.getRotation().multVec(delta)
delta = self.wp.get_global_coords(delta,as_vector=True)
if self.modec.isChecked():
self.tracker.pos(point.add(delta))
self.tracker.on()
else:
if self.bpoint:
delta = Vector(0,0,-self.Height/2)
if hasattr(FreeCAD,"DraftWorkingPlane"):
delta = FreeCAD.DraftWorkingPlane.getRotation().multVec(delta)
delta = self.wp.get_global_coords(delta,as_vector=True)
self.tracker.update([self.bpoint.add(delta),point.add(delta)])
self.tracker.on()
l = (point.sub(self.bpoint)).Length
+2 -2
View File
@@ -105,8 +105,8 @@ class CommandArchTruss:
else:
# interactive line drawing
self.points = []
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import WorkingPlane
WorkingPlane.get_working_plane()
if hasattr(FreeCADGui,"Snapper"):
FreeCADGui.Snapper.getPoint(callback=self.getPoint)
+7 -7
View File
@@ -65,7 +65,7 @@ class Renderer:
self.wp = wp
else:
import WorkingPlane
self.wp = WorkingPlane.plane()
self.wp = WorkingPlane.PlaneBase()
if DEBUG: print("Renderer initialized on " + str(self.wp))
@@ -92,7 +92,7 @@ class Renderer:
def setWorkingPlane(self,wp):
"sets a Draft WorkingPlane or Placement for this renderer"
if isinstance(wp,FreeCAD.Placement):
self.wp.setFromPlacement(wp)
self.wp.align_to_placement(wp)
else:
self.wp = wp
if DEBUG: print("Renderer set on " + str(self.wp))
@@ -198,7 +198,7 @@ class Renderer:
for e in edges:
v = e.Vertexes[0].Point
#print(v)
v = self.wp.getLocalCoords(v)
v = self.wp.get_local_coords(v)
verts.append(v)
verts.append(verts[0])
if len(verts) > 2:
@@ -211,7 +211,7 @@ class Renderer:
return None
else:
# restoring flipped normals
vnorm = self.wp.getLocalCoords(norm)
vnorm = self.wp.get_local_coords(norm)
if vnorm.getAngle(sh.normalAt(0,0)) > 1:
sh.reverse()
#print("VRM: projectFace end: ",len(sh.Vertexes)," verts")
@@ -220,8 +220,8 @@ class Renderer:
def projectEdge(self,edge):
"projects a single edge on the WP"
if len(edge.Vertexes) > 1:
v1 = self.wp.getLocalCoords(edge.Vertexes[0].Point)
v2 = self.wp.getLocalCoords(edge.Vertexes[-1].Point)
v1 = self.wp.get_local_coords(edge.Vertexes[0].Point)
v2 = self.wp.get_local_coords(edge.Vertexes[-1].Point)
return Part.LineSegment(v1,v2).toShape()
return edge
@@ -293,7 +293,7 @@ class Renderer:
# http://paulbourke.net/geometry/insidepoly/
count = 0
p = self.wp.getLocalCoords(vert.Point)
p = self.wp.get_local_coords(vert.Point)
for e in face[0].Edges:
p1 = e.Vertexes[0].Point
p2 = e.Vertexes[-1].Point
+10 -7
View File
@@ -316,6 +316,7 @@ class _CommandWall:
sel = FreeCADGui.Selection.getSelectionEx()
done = False
self.existing = []
self.wp = None
if sel:
# automatic mode
@@ -345,9 +346,9 @@ class _CommandWall:
# interactive mode
self.points = []
import WorkingPlane
self.wp = WorkingPlane.get_working_plane()
self.tracker = DraftTrackers.boxTracker()
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
FreeCADGui.Snapper.getPoint(callback=self.getPoint,
extradlg=self.taskbox(),
title=translate("Arch","First point of wall")+":")
@@ -386,8 +387,8 @@ class _CommandWall:
elif len(self.points) == 2:
import Part
l = Part.LineSegment(FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[0]),
FreeCAD.DraftWorkingPlane.getLocalCoords(self.points[1]))
l = Part.LineSegment(self.wp.get_local_coords(self.points[0]),
self.wp.get_local_coords(self.points[1]))
self.tracker.finalize()
FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Wall"))
FreeCADGui.addModule("Arch")
@@ -431,6 +432,8 @@ class _CommandWall:
"""
FreeCADGui.addModule("Draft")
FreeCADGui.addModule("WorkingPlane")
FreeCADGui.doCommand("wp = WorkingPlane.get_working_plane()")
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("WallSketches",True):
# Use ArchSketch if SketchArch add-on is present
try:
@@ -439,13 +442,13 @@ class _CommandWall:
FreeCADGui.doCommand('base=ArchSketchObject.makeArchSketch()')
except:
FreeCADGui.doCommand('base=FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject","WallTrace")')
FreeCADGui.doCommand('base.Placement = FreeCAD.DraftWorkingPlane.getPlacement()')
FreeCADGui.doCommand('base.Placement = wp.get_placement()')
FreeCADGui.doCommand('base.addGeometry(trace)')
else:
FreeCADGui.doCommand('base=Draft.makeLine(trace)')
FreeCADGui.doCommand('FreeCAD.ActiveDocument.recompute()')
FreeCADGui.doCommand('wall = Arch.makeWall(base,width='+str(self.Width)+',height='+str(self.Height)+',align="'+str(self.Align)+'")')
FreeCADGui.doCommand('wall.Normal = FreeCAD.DraftWorkingPlane.getNormal()')
FreeCADGui.doCommand('wall.Normal = wp.axis')
if self.MultiMat:
FreeCADGui.doCommand("wall.Material = FreeCAD.ActiveDocument."+self.MultiMat.Name)
FreeCADGui.doCommand("Draft.autogroup(wall)")
@@ -467,7 +470,7 @@ class _CommandWall:
if FreeCADGui.Control.activeDialog():
b = self.points[0]
n = FreeCAD.DraftWorkingPlane.axis
n = self.wp.axis
bv = point.sub(b)
dv = bv.cross(n)
dv = DraftVecUtils.scaleTo(dv,self.Width/2)
+7 -7
View File
@@ -186,6 +186,7 @@ class _CommandWindow:
self.Include = True
self.baseFace = None
self.wparams = ["Width","Height","H1","H2","H3","W1","W2","O1","O2"]
self.wp = None
# autobuild mode
if FreeCADGui.Selection.getSelectionEx():
@@ -235,8 +236,8 @@ class _CommandWindow:
return
# interactive mode
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import WorkingPlane
self.wp = WorkingPlane.get_working_plane()
self.tracker = DraftTrackers.boxTracker()
self.tracker.length(self.Width)
@@ -274,8 +275,8 @@ class _CommandWindow:
point = point.add(FreeCAD.Vector(0,0,self.Sill))
FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Window"))
FreeCADGui.doCommand("import math, FreeCAD, Arch, DraftGeomUtils")
FreeCADGui.doCommand("wp = FreeCAD.DraftWorkingPlane")
FreeCADGui.doCommand("import math, FreeCAD, Arch, DraftGeomUtils, WorkingPlane")
FreeCADGui.doCommand("wp = WorkingPlane.get_working_plane()")
if self.baseFace is not None:
FreeCADGui.doCommand("face = FreeCAD.ActiveDocument." + self.baseFace[0].Name + ".Shape.Faces[" + str(self.baseFace[1]) + "]")
@@ -342,9 +343,8 @@ class _CommandWindow:
delta = FreeCAD.Vector(self.Width/2,self.Thickness/2,self.Height/2)
delta = delta.add(FreeCAD.Vector(0,0,self.Sill))
wp = FreeCAD.DraftWorkingPlane
if self.baseFace is None:
rot = FreeCAD.Rotation(wp.u,wp.v,-wp.axis,"XZY")
rot = FreeCAD.Rotation(self.wp.u,self.wp.v,-self.wp.axis,"XZY")
self.tracker.setRotation(rot)
if info:
if "Face" in info['Component']:
@@ -353,7 +353,7 @@ class _CommandWindow:
self.baseFace = [o,int(info['Component'][4:])-1]
#print("switching to ",o.Label," face ",self.baseFace[1])
f = o.Shape.Faces[self.baseFace[1]]
p = DraftGeomUtils.placement_from_face(f,vec_z=wp.axis,rotated=True)
p = DraftGeomUtils.placement_from_face(f,vec_z=self.wp.axis,rotated=True)
rot = p.Rotation
self.tracker.setRotation(rot)
r = self.tracker.trans.rotation.getValue().getValue()
+1 -3
View File
@@ -714,9 +714,7 @@ def getRotation(entity):
w = FreeCAD.Vector(entity.Axis3.DirectionRatios)
except AttributeError:
return FreeCAD.Rotation()
import WorkingPlane
p = WorkingPlane.plane(u=u, v=v, w=w)
return p.getRotation().Rotation
return FreeCAD.Rotation(u, v, w, "ZYX")
def getPlacement(entity,scaling=1000):
@@ -73,6 +73,7 @@ class Draft_SelectPlane:
App.activeDraftCommand.finish()
App.activeDraftCommand = self
self.call = None
# Set variables
self.wp = WorkingPlane.get_working_plane()
@@ -134,6 +135,7 @@ class Draft_SelectPlane:
if Gui.Selection.hasSelection():
if self.wp.align_to_selection(self.offset):
Gui.Selection.clearSelection()
self.finish()
return
# Execute the actual task panel delayed to catch possible active Draft command
+16 -12
View File
@@ -77,6 +77,7 @@ class Facebinder(DraftObject):
if "Face" in sub:
try:
face = Part.getShape(sel[0], sub, needSubElement=True, retType=0)
area += face.Area
if offs_val:
if face.Surface.isPlanar():
norm = face.normalAt(0, 0)
@@ -86,14 +87,14 @@ class Facebinder(DraftObject):
else:
offs = face.makeOffsetShape(offs_val, 1e-7)
faces.extend(offs.Faces)
area += face.Area
else:
faces.append(face)
except Part.OCCError:
print("Draft: error building facebinder")
return
if not faces:
return
try:
sh = None
if extr_val:
extrs = []
for face in faces:
@@ -103,23 +104,26 @@ class Facebinder(DraftObject):
else:
extr = face.makeOffsetShape(extr_val, 1e-7, fill=True)
extrs.extend(extr.Solids)
sh = extrs.pop()
sh = sh.multiFuse(extrs)
shp = Part.Shape() # create empty shape to ensure default Placement
shp = shp.fuse(extrs.pop()) # add 1st shape, multiFuse does not work otherwise
if extrs:
shp = shp.multiFuse(extrs) # multiFuse is more reliable than serial fuse
else:
shp = Part.Shape()
shp = shp.fuse(faces.pop())
if faces:
shp = shp.multiFuse(faces)
if len(faces) > 1:
if not sh:
sh = faces.pop()
sh = sh.multiFuse(faces)
if hasattr(obj, "Sew") and obj.Sew:
sh.sewShape()
shp.sewShape()
if not hasattr(obj, "RemoveSplitter"):
sh = sh.removeSplitter()
shp = shp.removeSplitter()
elif obj.RemoveSplitter:
sh = sh.removeSplitter()
shp = shp.removeSplitter()
except Part.OCCError:
print("Draft: error building facebinder")
return
obj.Shape = sh
obj.Placement = pl
obj.Shape = shp
obj.Area = area
self.props_changed_clear()
@@ -66,24 +66,28 @@ TaskFemConstraintTemperature::TaskFemConstraintTemperature(
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
// Fill data into dialog elements
ui->if_temperature->setMinimum(0);
ui->if_temperature->setMaximum(FLOAT_MAX);
ui->qsb_temperature->setMinimum(0);
ui->qsb_temperature->setMaximum(FLOAT_MAX);
ui->qsb_cflux->setMinimum(-FLOAT_MAX);
ui->qsb_cflux->setMaximum(FLOAT_MAX);
std::string constraint_type = pcConstraint->ConstraintType.getValueAsString();
if (constraint_type == "Temperature") {
ui->rb_temperature->setChecked(true);
ui->if_temperature->setValue(pcConstraint->Temperature.getQuantityValue());
App::PropertyEnumeration* constrType = &pcConstraint->ConstraintType;
QStringList qTypeList;
for (auto item : constrType->getEnumVector()) {
qTypeList << QString::fromUtf8(item.c_str());
}
ui->if_temperature->bind(pcConstraint->Temperature);
ui->if_temperature->setUnit(pcConstraint->Temperature.getUnit());
}
else if (constraint_type == "CFlux") {
ui->rb_cflux->setChecked(true);
std::string str = "Concentrated heat flux";
ui->if_temperature->setValue(pcConstraint->CFlux.getQuantityValue());
ui->if_temperature->bind(pcConstraint->CFlux);
ui->if_temperature->setUnit(pcConstraint->CFlux.getUnit());
}
ui->cb_constr_type->addItems(qTypeList);
ui->cb_constr_type->setCurrentIndex(constrType->getValue());
onConstrTypeChanged(constrType->getValue());
ui->qsb_temperature->setValue(pcConstraint->Temperature.getQuantityValue());
ui->qsb_temperature->bind(pcConstraint->Temperature);
ui->qsb_temperature->setUnit(pcConstraint->Temperature.getUnit());
ui->qsb_cflux->setValue(pcConstraint->CFlux.getQuantityValue());
ui->qsb_cflux->bind(pcConstraint->CFlux);
ui->qsb_cflux->setUnit(pcConstraint->CFlux.getUnit());
ui->lw_references->clear();
for (std::size_t i = 0; i < Objects.size(); i++) {
@@ -108,12 +112,22 @@ TaskFemConstraintTemperature::TaskFemConstraintTemperature(
&QListWidget::itemClicked,
this,
&TaskFemConstraintTemperature::setSelection);
connect(ui->rb_temperature, &QRadioButton::clicked, this, &TaskFemConstraintTemperature::Temp);
connect(ui->rb_cflux, &QRadioButton::clicked, this, &TaskFemConstraintTemperature::Flux);
connect(ui->cb_constr_type,
qOverload<int>(&QComboBox::activated),
this,
&TaskFemConstraintTemperature::onConstrTypeChanged);
connect(ui->qsb_temperature,
qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
this,
&TaskFemConstraintTemperature::onTempChanged);
connect(ui->qsb_cflux,
qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
this,
&TaskFemConstraintTemperature::onCFluxChanged);
// Selection buttons
buttonGroup->addButton(ui->btnAdd, (int)SelectionChangeModes::refAdd);
buttonGroup->addButton(ui->btnRemove, (int)SelectionChangeModes::refRemove);
buttonGroup->addButton(ui->btnAdd, static_cast<int>(SelectionChangeModes::refAdd));
buttonGroup->addButton(ui->btnRemove, static_cast<int>(SelectionChangeModes::refRemove));
updateUI();
}
@@ -129,20 +143,41 @@ void TaskFemConstraintTemperature::updateUI()
}
}
void TaskFemConstraintTemperature::Temp()
void TaskFemConstraintTemperature::onTempChanged(double)
{
Fem::ConstraintTemperature* pcConstraint =
static_cast<Fem::ConstraintTemperature*>(ConstraintView->getObject());
ui->if_temperature->setUnit(pcConstraint->Temperature.getUnit());
ui->if_temperature->setValue(pcConstraint->Temperature.getQuantityValue());
std::string name = ConstraintView->getObject()->getNameInDocument();
Gui::Command::doCommand(Gui::Command::Doc,
"App.ActiveDocument.%s.Temperature = \"%s\"",
name.c_str(),
get_temperature().c_str());
}
void TaskFemConstraintTemperature::Flux()
void TaskFemConstraintTemperature::onCFluxChanged(double)
{
Fem::ConstraintTemperature* pcConstraint =
static_cast<Fem::ConstraintTemperature*>(ConstraintView->getObject());
ui->if_temperature->setUnit(pcConstraint->CFlux.getUnit());
ui->if_temperature->setValue(pcConstraint->CFlux.getQuantityValue());
std::string name = ConstraintView->getObject()->getNameInDocument();
Gui::Command::doCommand(Gui::Command::Doc,
"App.ActiveDocument.%s.CFlux = \"%s\"",
name.c_str(),
get_cflux().c_str());
}
void TaskFemConstraintTemperature::onConstrTypeChanged(int item)
{
auto obj = static_cast<Fem::ConstraintTemperature*>(ConstraintView->getObject());
obj->ConstraintType.setValue(item);
const char* type = obj->ConstraintType.getValueAsString();
if (strcmp(type, "Temperature") == 0) {
ui->qsb_temperature->setVisible(true);
ui->qsb_cflux->setVisible(false);
ui->lbl_temperature->setVisible(true);
ui->lbl_cflux->setVisible(false);
}
else if (strcmp(type, "CFlux") == 0) {
ui->qsb_cflux->setVisible(true);
ui->qsb_temperature->setVisible(false);
ui->lbl_cflux->setVisible(true);
ui->lbl_temperature->setVisible(false);
}
}
void TaskFemConstraintTemperature::addToSelection()
@@ -270,25 +305,17 @@ const std::string TaskFemConstraintTemperature::getReferences() const
std::string TaskFemConstraintTemperature::get_temperature() const
{
return ui->if_temperature->value().getSafeUserString().toStdString();
return ui->qsb_temperature->value().getSafeUserString().toStdString();
}
std::string TaskFemConstraintTemperature::get_cflux() const
{
return ui->if_temperature->value().getSafeUserString().toStdString();
return ui->qsb_cflux->value().getSafeUserString().toStdString();
}
std::string TaskFemConstraintTemperature::get_constraint_type() const
{
std::string type;
if (ui->rb_temperature->isChecked()) {
type = "\"Temperature\"";
}
else if (ui->rb_cflux->isChecked()) {
type = "\"CFlux\"";
}
return type;
return ui->cb_constr_type->currentText().toStdString();
}
bool TaskFemConstraintTemperature::event(QEvent* e)
@@ -357,7 +384,7 @@ bool TaskDlgFemConstraintTemperature::accept()
try {
Gui::Command::doCommand(Gui::Command::Doc,
"App.ActiveDocument.%s.ConstraintType = %s",
"App.ActiveDocument.%s.ConstraintType = \"%s\"",
name.c_str(),
parameterTemperature->get_constraint_type().c_str());
if (type == "Temperature") {
@@ -55,8 +55,9 @@ public:
private Q_SLOTS:
void onReferenceDeleted();
void Temp();
void Flux();
void onConstrTypeChanged(int item);
void onCFluxChanged(double);
void onTempChanged(double);
void addToSelection() override;
void removeFromSelection() override;
+29 -26
View File
@@ -49,42 +49,45 @@
<widget class="QListWidget" name="lw_references"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="rb_temperature">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lbl_constr_type">
<property name="text">
<string>Temperature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
<string>Constraint type</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rb_cflux">
<item row="0" column="1">
<widget class="QComboBox" name="cb_constr_type"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lbl_temperature">
<property name="text">
<string>Temperature</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_temperature">
<property name="unit" stdset="0">
<string notr="true">K</string>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_cflux">
<property name="text">
<string>Concentrated heat flux</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutTemperature">
<item>
<widget class="QLabel" name="lbl_type">
<property name="text">
<string>Temperature</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::QuantitySpinBox" name="if_temperature">
<item row="2" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_cflux">
<property name="unit" stdset="0">
<string notr="true">K</string>
<string notr="true">mW</string>
</property>
<property name="minimum">
<double>0.000000000000000</double>
+26 -8
View File
@@ -6,16 +6,22 @@
<rect>
<x>0</x>
<y>0</y>
<width>264</width>
<height>142</height>
<width>344</width>
<height>160</height>
</rect>
</property>
<property name="windowTitle">
<string>Sprocket parameter</string>
</property>
<layout class="QFormLayout" name="formLayout">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Number of teeth:</string>
</property>
@@ -23,6 +29,12 @@
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_NumberOfTeeth">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>3</number>
</property>
@@ -43,6 +55,12 @@
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBox_SprocketReference">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>ANSI 25</string>
@@ -205,7 +223,7 @@
<item row="2" column="1">
<widget class="Gui::InputField" name="Quantity_Pitch">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -245,14 +263,14 @@
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Roller Diameter:</string>
<string>Chain Roller Diameter:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::InputField" name="Quantity_RollerDiameter">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -289,14 +307,14 @@
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Thickness:</string>
<string>Tooth Width</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Gui::InputField" name="Quantity_Thickness">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
+19 -15
View File
@@ -346,21 +346,25 @@ class ObjectOp(PathOp.ObjectOp):
# Note that emitting preambles between moves breaks some dressups and prevents path optimization on some controllers
pathParams["preamble"] = False
if self.endVector is None:
verts = hWire.Wires[0].Vertexes
idx = 0
if obj.Direction == "CCW":
idx = len(verts) - 1
x = verts[idx].X
y = verts[idx].Y
# Zero start value adjustments for Path.fromShapes() bug
if Path.Geom.isRoughly(x, 0.0):
x = 0.00001
if Path.Geom.isRoughly(y, 0.0):
y = 0.00001
pathParams["start"] = FreeCAD.Vector(x, y, verts[0].Z)
else:
pathParams["start"] = self.endVector
# Always manually setting pathParams["start"] to the first or
# last vertex of the wire (depending on obj.Direction) ensures
# the edge is always milled in the correct direction. Using
# self.endVector would allow Path.fromShapes to reverse the
# direction if that would shorten the travel move and thus cause
# the edges being milled in seemingly random directions.
verts = hWire.Wires[0].Vertexes
idx = 0
if obj.Direction == "CCW":
idx = len(verts) - 1
x = verts[idx].X
y = verts[idx].Y
# Zero start value adjustments for Path.fromShapes() bug
if Path.Geom.isRoughly(x, 0.0):
x = 0.00001
if Path.Geom.isRoughly(y, 0.0):
y = 0.00001
pathParams["start"] = FreeCAD.Vector(x, y, verts[0].Z)
obj.PathParams = str(
{key: value for key, value in pathParams.items() if key != "shapes"}
@@ -394,7 +394,7 @@ void SketcherToolDefaultWidget::setParameterLabel(int parameterindex, const QStr
void SketcherToolDefaultWidget::setParameter(int parameterindex, double val)
{
if (parameterindex < nParameters) {
getParameterSpinBox(parameterindex)->setValue(Base::Quantity(val, Base::Unit::Length));
getParameterSpinBox(parameterindex)->setValue(val);
return;
}
@@ -424,6 +424,45 @@ void SketcherToolDefaultWidget::configureParameterUnit(int parameterindex, const
QT_TRANSLATE_NOOP("Exceptions", "ToolWidget parameter index out of range"));
}
void SketcherToolDefaultWidget::configureParameterDecimals(int parameterindex, int val)
{
Base::StateLocker lock(blockParameterSlots, true);
if (parameterindex < nParameters) {
getParameterSpinBox(parameterindex)->setDecimals(val);
return;
}
THROWM(Base::IndexError,
QT_TRANSLATE_NOOP("Exceptions", "ToolWidget parameter index out of range"));
}
void SketcherToolDefaultWidget::configureParameterMin(int parameterindex, double val)
{
Base::StateLocker lock(blockParameterSlots, true);
if (parameterindex < nParameters) {
getParameterSpinBox(parameterindex)->setMinimum(val);
return;
}
THROWM(Base::IndexError,
QT_TRANSLATE_NOOP("Exceptions", "ToolWidget parameter index out of range"));
}
void SketcherToolDefaultWidget::configureParameterMax(int parameterindex, double val)
{
Base::StateLocker lock(blockParameterSlots, true);
if (parameterindex < nParameters) {
getParameterSpinBox(parameterindex)->setMaximum(val);
return;
}
THROWM(Base::IndexError,
QT_TRANSLATE_NOOP("Exceptions", "ToolWidget parameter index out of range"));
}
void SketcherToolDefaultWidget::setParameterEnabled(int parameterindex, bool active)
{
if (parameterindex < nParameters) {
@@ -714,6 +753,20 @@ void SketcherToolDefaultWidget::restoreCheckBoxPref(int checkboxindex)
}
}
void SketcherToolDefaultWidget::setCheckboxIcon(int checkboxindex, QIcon icon)
{
if (checkboxindex < nCheckbox) {
getCheckBox(checkboxindex)->setIcon(icon);
}
}
void SketcherToolDefaultWidget::setComboboxItemIcon(int comboboxindex, int index, QIcon icon)
{
if (comboboxindex < nCombobox) {
getComboBox(comboboxindex)->setItemIcon(index, icon);
}
}
void SketcherToolDefaultWidget::setComboboxPrefEntry(int comboboxindex,
const std::string& prefEntry)
{
@@ -146,6 +146,9 @@ public:
void setParameter(int parameterindex, double val);
void configureParameterInitialValue(int parameterindex, double value);
void configureParameterUnit(int parameterindex, const Base::Unit& unit);
void configureParameterDecimals(int parameterindex, int val);
void configureParameterMax(int parameterindex, double val);
void configureParameterMin(int parameterindex, double val);
double getParameter(int parameterindex);
bool isParameterSet(int parameterindex);
void
@@ -172,6 +175,7 @@ public:
void setCheckboxToolTip(int checkboxindex, const QString& string);
bool getCheckboxChecked(int checkboxindex);
void setCheckboxPrefEntry(int checkboxindex, const std::string& prefEntry);
void setCheckboxIcon(int checkboxindex, QIcon icon);
void restoreCheckBoxPref(int checkboxindex);
void initNComboboxes(int ncombobox);
@@ -180,6 +184,7 @@ public:
void setComboboxLabel(int comboboxindex, const QString& string);
int getComboboxIndex(int comboboxindex);
void setComboboxElements(int comboboxindex, const QStringList& names);
void setComboboxItemIcon(int comboboxindex, int index, QIcon icon);
void setComboboxPrefEntry(int comboboxindex, const std::string& prefEntry);
void restoreComboboxPref(int comboboxindex);
+7 -3
View File
@@ -1066,11 +1066,12 @@ void execLine2Points(Gui::Command* cmd)
//check if editing existing edge
if (!edgeNames.empty() && (edgeNames.size() == 1)) {
TechDraw::CosmeticEdge* ce = baseFeat->getCosmeticEdgeBySelection(edgeNames.front());
if (!ce) {
if (!ce || ce->m_geometry->getGeomType() != TechDraw::GeomType::GENERIC) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("Selection is not a Cosmetic Line."));
return;
}
Gui::Control().showDialog(new TaskDlgCosmeticLine(baseFeat,
edgeNames.front()));
return;
@@ -1208,11 +1209,14 @@ void execCosmeticCircle(Gui::Command* cmd)
//check if editing existing edge
if (!edgeNames.empty() && (edgeNames.size() == 1)) {
TechDraw::CosmeticEdge* ce = baseFeat->getCosmeticEdgeBySelection(edgeNames.front());
if (!ce) {
if (!ce
|| !(ce->m_geometry->getGeomType() == TechDraw::GeomType::CIRCLE
|| ce->m_geometry->getGeomType() == TechDraw::GeomType::ARCOFCIRCLE)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("Selection is not a Cosmetic edge."));
QObject::tr("Selection is not a Cosmetic Circle or a Cosmetic Arc of Circle."));
return;
}
Gui::Control().showDialog(new TaskDlgCosmeticCircle(baseFeat,
edgeNames.front()));
return;
+2
View File
@@ -289,6 +289,8 @@ void QGIViewPart::drawAllEdges()
item->setNormalColor(PreferencesGui::getAccessibleQColor(PreferencesGui::normalQColor()));
item->setStyle(Qt::SolidLine);
if ((*itGeom)->getCosmetic()) {
item->setCosmetic(true);
// cosmetic edge - format appropriately
int source = (*itGeom)->source();
if (source == COSMETICEDGE) {