-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add spacenavd motion event support to Placement dialog that allows for object rotation and translation #18098
base: main
Are you sure you want to change the base?
Conversation
#include <Gui/View3DInventor.h> | ||
#include <Inventor/SbVec3f.h> | ||
#include <Gui/SpaceballEvent.h> | ||
#include <Base/DualQuaternion.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This header seems to be superfluous
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, every thing except
#include <Gui/SpaceballEvent.h>
seems superfluous and are left from old experiments.
} | ||
|
||
Placement::~Placement() | ||
{ | ||
if (qApp!=NULL) qApp->removeEventFilter(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is not needed. I have never seen qApp being null in a GUI application. Btw, NULL is C and in modern C++ nullptr must be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check removed.
Assumed that it mitigated a segmentation fault that I have seen.
Unfortunately triggering it was not very repeatable and this check does not help with that segfault.
I can also trigger that segfault on current unmodified Freecad:main branch.
Could you check if you can trigger it by something like this:
- open any document (lets say "test.FCStd")
- open placement dialog on any Body in that document
- move object by spacenavd or mouse scroll wheel on angle spinbox
- open any other document without closing placement dialog
- close test.FCStd
- move object by spacenavd or mouse scroll wheel on angle spinbox (trigger is hard to predict, sometimes value needs to be changed many times per second or enough times to trigger, sometimes a single value change can trigger a segmentation fault, I have seen a higher probability with spacenavd)
After that procedure i can get different segmentation faults.
For example like this:
No object selected. Program received signal SIGSEGV, Segmentation fault. #0 /lib/x86_64-linux-gnu/libc.so.6(+0x3c050) [0x7fdd3e369050] #1 0x7fdd3e67e014 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const from /lib/x86_64-linux-gnu/libstdc++.so.6+0x4 #2 0x7fdd4139019c in App::Document::getName() const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x1e #3 0x7fdd41605a1e in App::ObjectIdentifier::resolve(App::ObjectIdentifier::ResolveResults&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x114 #4 0x7fdd4160c60c in App::ObjectIdentifier::ResolveResults::ResolveResults(App::ObjectIdentifier const&) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x1ec #5 0x7fdd41608105 in App::ObjectIdentifier::getDocumentName() const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x33 #6 0x7fdd416066cc in App::ObjectIdentifier::getDocument(App::ObjectIdentifier::String, bool*) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x52 #7 0x7fdd41606970 in App::ObjectIdentifier::getDocumentObject() const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x6e #8 0x7fdd4359baba in Gui::QuantitySpinBoxPrivate::parseString(QString const&, Base::Quantity&, double&, App::ObjectIdentifier const&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0xbe #9 0x7fdd4359ccdc in Gui::QuantitySpinBoxPrivate::validateAndInterpret(QString&, QValidator::State&, App::ObjectIdentifier const&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x1012 #10 0x7fdd4359a27b in Gui::QuantitySpinBox::validate(QString&, int&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x57 #11 0x7fdd3f660868 in QWidgetLineControl::finishChange(int, bool, bool) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0xf8 #12 0x7fdd3f660c2e in QWidgetLineControl::internalSetText(QString const&, int, bool) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1ae #13 0x7fdd43598031 in Gui::QuantitySpinBox::updateEdit(QString const&) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0xaf #14 0x7fdd43597f43 in Gui::QuantitySpinBox::updateText(Base::Quantity const&) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x7f #15 0x7fdd43599271 in Gui::QuantitySpinBox::stepBy(int) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0xdf #16 0x7fdd3f6b46e1 in QAbstractSpinBox::wheelEvent(QWheelEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x81 #17 0x7fdd3f551db8 in QWidget::event(QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1a8 #18 0x7fdd4359983d in Gui::QuantitySpinBox::event(QEvent*) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x23 #19 0x7fdd3f50ffae in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x7e #20 0x7fdd3f518e06 in QApplication::notify(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1c76 #21 0x7fdd42eef000 in Gui::GUIApplication::notify(QObject*, QEvent*) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x134 #22 0x7fdd3ea3b738 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x118 #23 /lib/x86_64-linux-gnu/libQt5Widgets.so.5(+0x1bf7ab) [0x7fdd3f56c7ab] #24 /lib/x86_64-linux-gnu/libQt5Widgets.so.5(+0x1c1095) [0x7fdd3f56e095] #25 0x7fdd3f50ffae in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x7e #26 0x7fdd42eef000 in Gui::GUIApplication::notify(QObject*, QEvent*) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x134 #27 0x7fdd3ea3b738 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x118 #28 0x7fdd3ee16e72 in QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent*) from /lib/x86_64-linux-gnu/libQt5Gui.so.5+0xe2 #29 0x7fdd3edefcec in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt5Gui.so.5+0xac #30 /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5(+0x6deca) [0x7fdd38327eca] #31 /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x299) [0x7fdd3c8767a9] #32 /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x54a38) [0x7fdd3c876a38] #33 /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x2c) [0x7fdd3c876acc] #34 0x7fdd3ea93876 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x66 #35 0x7fdd3ea3a1bb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x12b #36 0x7fdd3ea42316 in QCoreApplication::exec() from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x96 #37 /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so(+0x129ad91) [0x7fdd42dabd91] #38 /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so(+0x129b055) [0x7fdd42dac055] #39 0x7fdd42dac323 in Gui::Application::runApplication() from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x1d3 #40 ./bin/FreeCAD(+0x2d683) [0x559ae0063683] #41 /lib/x86_64-linux-gnu/libc.so.6(+0x2724a) [0x7fdd3e35424a] #42 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85) [0x7fdd3e354305] #43 ./bin/FreeCAD(+0x2c801) [0x559ae0062801]
or
Program received signal SIGSEGV, Segmentation fault. #0 /lib/x86_64-linux-gnu/libc.so.6(+0x3c050) [0x7f67c8eee050] #1 0x7f67c9203014 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const from /lib/x86_64-linux-gnu/libstdc++.so.6+0x4 #2 0x7f67cbf1519c in App::Document::getName() const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x1e #3 0x7f67cc18aa1e in App::ObjectIdentifier::resolve(App::ObjectIdentifier::ResolveResults&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x114 #4 0x7f67cc19160c in App::ObjectIdentifier::ResolveResults::ResolveResults(App::ObjectIdentifier const&) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x1ec #5 0x7f67cc18d105 in App::ObjectIdentifier::getDocumentName() const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x33 #6 0x7f67cc18b6cc in App::ObjectIdentifier::getDocument(App::ObjectIdentifier::String, bool*) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x52 #7 0x7f67cc18b970 in App::ObjectIdentifier::getDocumentObject() const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADApp.so+0x6e #8 0x7f67ce120aba in Gui::QuantitySpinBoxPrivate::parseString(QString const&, Base::Quantity&, double&, App::ObjectIdentifier const&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0xbe #9 0x7f67ce121cdc in Gui::QuantitySpinBoxPrivate::validateAndInterpret(QString&, QValidator::State&, App::ObjectIdentifier const&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x1012 #10 0x7f67ce11f27b in Gui::QuantitySpinBox::validate(QString&, int&) const from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x57 #11 0x7f67ca1e5868 in QWidgetLineControl::finishChange(int, bool, bool) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0xf8 #12 0x7f67ca1e5c2e in QWidgetLineControl::internalSetText(QString const&, int, bool) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1ae #13 0x7f67ce11d031 in Gui::QuantitySpinBox::updateEdit(QString const&) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0xaf #14 0x7f67ce11cf43 in Gui::QuantitySpinBox::updateText(Base::Quantity const&) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x7f #15 0x7f67ce11e271 in Gui::QuantitySpinBox::stepBy(int) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0xdf #16 0x7f67ca2396e1 in QAbstractSpinBox::wheelEvent(QWheelEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x81 #17 0x7f67ca0d6db8 in QWidget::event(QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1a8 #18 0x7f67ce11e83d in Gui::QuantitySpinBox::event(QEvent*) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x23 #19 0x7f67ca094fae in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x7e #20 0x7f67ca09de06 in QApplication::notify(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x1c76 #21 0x7f67cda74000 in Gui::GUIApplication::notify(QObject*, QEvent*) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x134 #22 0x7f67c95c0738 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x118 #23 /lib/x86_64-linux-gnu/libQt5Widgets.so.5(+0x1bf7ab) [0x7f67ca0f17ab] #24 /lib/x86_64-linux-gnu/libQt5Widgets.so.5(+0x1c1095) [0x7f67ca0f3095] #25 0x7f67ca094fae in QApplicationPrivate::notify_helper(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Widgets.so.5+0x7e #26 0x7f67cda74000 in Gui::GUIApplication::notify(QObject*, QEvent*) from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x134 #27 0x7f67c95c0738 in QCoreApplication::notifyInternal2(QObject*, QEvent*) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x118 #28 0x7f67c999be72 in QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent*) from /lib/x86_64-linux-gnu/libQt5Gui.so.5+0xe2 #29 0x7f67c9974cec in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt5Gui.so.5+0xac #30 /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5(+0x6deca) [0x7f67c2eaceca] #31 /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x299) [0x7f67c73fb7a9] #32 /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x54a38) [0x7f67c73fba38] #33 /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x2c) [0x7f67c73fbacc] #34 0x7f67c9618876 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x66 #35 0x7f67c95bf1bb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x12b #36 0x7f67c95c7316 in QCoreApplication::exec() from /lib/x86_64-linux-gnu/libQt5Core.so.5+0x96 #37 /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so(+0x129ad91) [0x7f67cd930d91] #38 /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so(+0x129b055) [0x7f67cd931055] #39 0x7f67cd931323 in Gui::Application::runApplication() from /freecad_build/github2/FreeCAD/_build/lib/libFreeCADGui.so+0x1d3 #40 ./bin/FreeCAD(+0x2d683) [0x5601139e0683] #41 /lib/x86_64-linux-gnu/libc.so.6(+0x2724a) [0x7f67c8ed924a] #42 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85) [0x7f67c8ed9305] #43 ./bin/FreeCAD(+0x2c801) [0x5601139df801]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but I don't have a space mouse device.
From the callstack it looks like a null string is assigned to a std::string. This is not allowed and may cause a segmentation fault or throws an exception.
|
||
void Placement::setupEventFilter() | ||
{ | ||
if (qApp!=NULL) qApp->installEventFilter(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
@@ -559,6 +572,83 @@ void Placement::showDefaultButtons(bool ok) | |||
} | |||
} | |||
|
|||
bool Placement::eventFilter(QObject*, QEvent* ev) { | |||
//handle spacenav daemon motion events in placement window | |||
if (//event->type() == Spaceball::ButtonEvent::ButtonEventType || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commented code should be removed.
double dP=static_cast<double>(motionEvent->rotationY()) * rotationConstant; | ||
double dR=static_cast<double>(motionEvent->rotationX()) * rotationConstant; | ||
|
||
if(xTrans == 0 && yTrans == 0 && zTrans == 0 && dY ==0 && dP ==0 && dR ==0 ) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To improve readability you should write:
if (xTrans == 0 && yTrans == 0 && zTrans == 0 && dY ==0 && dP ==0 && dR ==0) {
return false;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or simply
return xTrans != 0 || yTrans != 0 || zTrans != 0 || dY !=0 || dP !=0 || dR !=0;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bofdahof doing that would return from the function too early, as there are more lines after this if
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! My bad!!! You are quite correct!
if (!motionEvent) { | ||
Base::Console().Log("invalid spaceball motion event in bool Placement::eventFilter(QObject*, QEvent* ev)\n"); | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation error.
|
||
if(xTrans == 0 && yTrans == 0 && zTrans == 0 && dY ==0 && dP ==0 && dR ==0 ) return false; | ||
signalMapper->blockSignals(true); | ||
// printf("\nSpaceball Placement Event\t(x,y,z)=(%f,%f,%f)\t(Rx,Ry,Rz)=(%f,%f,%f);\n",xTrans,yTrans,zTrans,dR,dP,dY ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am developing a 6dof controller and this snippet is useful for debugging purposes.
I am not very familiar how debugging code is usually included in Freecad.
Could you recommend an acceptable way to include it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disclaimer, I don't know what's preferred in freecad. This is just my personal opinion.
The issue I have with including debug code in a non-personal project, is that the debug code is essentially dead code for everyone except the author. Debug code usually make code more difficult to read and makes it more difficult to maintain and refactor.
When coding, I try to prioritize others time above my own. I'm only one person, but there might be hundreds of people who my laziness affects.
Personally, I do the following:
- don't stage debug code when creating commits
- stash and test without debug code before push
- If I want to keep the debug code, I create a new branch and a a commit the debug code and call it
DEBUG, DONT PUSH
to avoid accidentally create a pull request with that code.
Later when/if I want to continue with the debugging, I can simply checkout and rebase the debug code on latest main. There might be conflicts this way, but that just shows that it was a good idea to avoid commit that code in the first place.
Base::Vector3d dTrans(xTrans,yTrans,zTrans); | ||
Base::Vector3d rotationCenter=this->getCenterData(); | ||
Base::Placement old_placement(getPositionData(),getRotationData()); | ||
// Code below allows for seamles rotation around axes without blocking on roll, pitch, yaw range ends. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: seamless
Base::Matrix4D new_placement_mat; | ||
new_placement_mat = old_placement.toMatrix(); | ||
new_placement_mat.move(-rotationCenter); | ||
if(dY!=0) new_placement_mat.rotZ(Base::toRadians(dY)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Readability as mentioned above
new_placement_mat.move(dTrans); | ||
Base::Placement new_placement(new_placement_mat); | ||
new_placement.setPosition(old_placement.getPosition()+dTrans); | ||
//setPlacementData(new_placement);//Does not work properly because of problems with euler angles. Angle values need to be adjusted below to fit into proper range. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What to do with this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first I was trying to minimize count of UI updates but the first approach did not work properly.
It was supposed to be a note explaining why the rest of the algorithm was needed.
Can be removed or maybe rewritten in hopefully more clear way.
Which way would be preferred?
ui->zPos->setValue(new_placement.getPosition().z); | ||
|
||
Base::Vector3d new_dir_vect; | ||
double angle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A minor thing but our clang-tidy rules want initialized variables: double angle {};
double angle; | ||
new_placement.getRotation().getValue(new_dir_vect,angle); | ||
|
||
// bug seen in freecad-0.21.2+dfsg1 (from debian source package) and in github master 20240708 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment must be reformatted because the maximum chars per line is 100.
ui->yAxis->setValue(new_dir_vect.y); | ||
ui->zAxis->setValue(new_dir_vect.z); | ||
ui->angle->setValue(Base::toDegrees<double>(angle)); | ||
//printf("eventFilter-D\t(x,y,z)=(%f,%f,%f)\t(RotXYZ)=(%f,%f,%f)\t(RotAngle)=(%f)\n\n",ui->xPos->value().getValue(),ui->yPos->value().getValue(),ui->zPos->value().getValue(),ui->xAxis->value().getValue(),ui->yAxis->value().getValue(),ui->zAxis->value().getValue(),ui->angle->value().getValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
//printf("eventFilter-D\t(x,y,z)=(%f,%f,%f)\t(RotXYZ)=(%f,%f,%f)\t(RotAngle)=(%f)\n\n",ui->xPos->value().getValue(),ui->yPos->value().getValue(),ui->zPos->value().getValue(),ui->xAxis->value().getValue(),ui->yAxis->value().getValue(),ui->zAxis->value().getValue(),ui->angle->value().getValue()); | ||
|
||
// Euler angles (XY'Z'') | ||
double Y,P,R; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialize
// Euler angles (XY'Z'') | ||
double Y,P,R; | ||
new_placement.getRotation().getYawPitchRoll(Y,P,R); | ||
if(R>180) R-=360; else if(R<-180) R+=360; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Readability
signalMapper->blockSignals(false); | ||
onPlacementChanged(0); | ||
return true; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
double dR=static_cast<double>(motionEvent->rotationX()) * rotationConstant; | ||
|
||
if(xTrans == 0 && yTrans == 0 && zTrans == 0 && dY ==0 && dP ==0 && dR ==0 ) return false; | ||
signalMapper->blockSignals(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend to use: QSignalBlocker blocker(signalMapper);
because this is exception-safe and you don't have to worry about unblocking it when leaving the method (RAII).
ui->pitchAngle->setValue(P); | ||
ui->rollAngle->setValue(R); | ||
|
||
signalMapper->blockSignals(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using QSignalBlocker this line can be removed
@@ -131,6 +131,8 @@ class GuiExport Placement : public QDialog | |||
Base::Placement getPlacement() const; | |||
void showDefaultButtons(bool); | |||
|
|||
bool eventFilter(QObject *, QEvent *ev); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should declare it as: bool eventFilter(QObject* , QEvent* ev) override;
This commit adds spacemouse/spacenavd support to Placement dialog that allows for moving of objects (rotation and translation with 6-axis controller) instead of rotating the view.
It allows for smooth changing of object`s pitch/yaw/roll despite the range limits set in ui spinboxes (object rotation does not stop when reaching the spinbox limit).
When one of the angles exceeds limits set in spinbox all angles are corrected in such a way that the actual direction is still accurate.
Rotation and translation is relative to the main coordinate system (not the current camera view position).
Because this commit is using the Gui::QuantitySpinBox as data storage for object Placement it is susceptible to errors introduced by rounding (inherent to Gui::QuantitySpinBox and configured by decimal places setting).
Rounding errors accumulation is especially visible when using "Rotation axis with angle" in Placement dialog during consecutive calls to "Placement::eventFilter(QObject*, QEvent* ev)". This issue can be circumvented by increasing the decimal places setting in Edit->Preferences->General->Units->Number of decimals.
This can be tested by orienting object in such a way that x/y/z part of direction vector is non zero and then rotating it by 360degrees around any axis - the object does not return to the same, starting orientation when the rounding issue is present.
Code was tested and was working in dev version of freecad:
OS: Debian GNU/Linux 12 (bookworm) (X-Cinnamon/lightdm-xsession/xcb)
Architecture: x86_64
Version: 1.1.0dev.39290 (Git)
Build type: Unknown
Branch: main
Hash: 0a2e78b
Python 3.11.2, Qt 5.15.8, Coin 4.0.0, Vtk 9.1.0, OCC 7.6.3
Locale: English/United States (en_US)
Stylesheet/Theme/QtStyle: unset/unset/Qt default
Installed mods:
This is a copy of #15375 that was unintentionally closed.