View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001441 | FreeCAD | Bug | public | 2014-02-25 12:12 | 2017-03-27 08:18 |
Reporter | shoogen | Assigned To | wmayer | ||
Priority | low | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | trunk | ||||
Fixed in Version | 0.14 | ||||
Summary | 0001441: entering Transform mode degrades the Placemens rotation to single precision | ||||
Description | entering Transform mode an Part::Feature degrades the Placements rotation to single precision. >>> App.ActiveDocument.prism.Placement.Rotation.toEuler() (30.000006837567817, 0.0, 0.0) | ||||
Tags | No tags attached. | ||||
FreeCAD Information | |||||
|
How do you come to the conclusion that it's caused by using floats? When checking the source code of RotationPy::toEuler and Rotation::getYawPitchRoll we only use double. I guess these are round-off errors because the formula to compute these angles are quite complex using sqrt, arctan and arcsin. Script: import math m=App.Matrix() m.rotateZ(math.radians(30)) # maybe we have some round-off errors here? p=App.Placement(m) # both gives the same angle but not exactly '30' p.Rotation.toEuler() math.degrees(p.Rotation.Angle) # exact angles r=App.Rotation(App.Vector(0,0,1),30) r.toEuler() P.S: Inside Rotation we had some floats like 0.0f, 1.0f, 2.0f which cannot cause a loss of accuracy. Anyway I have changed them to be double now. |
|
I blame the edit mode in the GUI, not the rotation or matrix classes. i set the placement i save the current angle >>> a1=App.ActiveDocument.Box.Placement.Rotation.Angle i enter the edit mode from the context menu in the tree view (transform) i leave the edit mode form the context menu in the tree view (Finish editing) i save the current angle >>> a2=App.ActiveDocument.Box.Placement.Rotation.Angle >>> a1-a2 -6.176440625615953e-08 jürgen recently mentioned that you are a mathematician ;) a rough estimation what my machine epsilon could be tells me: >>> math.log(abs((a1-a2)/((a1+a2)/2)))/math.log(2) -23.01518279518693 or without the devision assuming that the cutoff happens about the magnitude of 1. according to IEEE 754 the result should be slightly above -23-1 for single and -52-1 for double either there was a cast to float at some point or we lost all the 29 bits of margin in the mantissa between double and float in the computation. Second example: i enter 30° in the property editor. >>> a3=App.ActiveDocument.Box.Placement.Rotation.Angle >>> a3-math.pi/6.0 -1.770507451759329e-07 >>> math.log(abs((_/a3))/math.log(2)) -21.495866889331555 this is even far worse than float. But floating point is not the problem here. I would guess that the design of the FreeCAD macro system is the culprit. ">>> FreeCAD.getDocument("Unnamed").getObject("Box").Placement = App.Placement(App.Vector(0,0,0),App.Rotation(0,0,0.258819,0.965926))" And now an example what it should look like. >>> FreeCAD.ActiveDocument.Box.Placement=FreeCAD.Placement(FreeCAD.Vector(),FreeCAD.Rotation(30,0,0)) >>> 1-App.ActiveDocument.Box.Placement.Rotation.Axis[2] -2.220446049250313e-16 >>> OpenSCADUtils.shorthexfloat(_) '-0x1.p-52' and after changing the angle in the GUI >>> 1-App.ActiveDocument.Box.Placement.Rotation.Axis[2] 2.3314683517128287e-15 >>> OpenSCADUtils.shorthexfloat(_) '0x1.5p-49' that is what i would expect of a double after some computation. |
|
the commit form today afternoon did not chage anything. BTW: is there a guide that explains how setPropertyValue(data); for the PropertyItems work? |
|
I see two problems in the GUI: 1. in void Gui::ViewProviderGeometryObject::sensorCallback(void * data, SoSensor * s) src/Gui/ViewProviderGeometryObject.cpp, line 340 "float q0, q1, q2, q3;" 2. it think it's not wise to set the rotation using Gui::Application::Instance->runPythonCode((const char*)cmd.toUtf8()); at src/Gui/propertyeditor/PropertyItem.cpp:244 |
|
> the commit form today afternoon did not chage anything. Of course and that's what I said in the PS. > is there a guide that explains how setPropertyValue(data) The argument 'value' is created by the calling instance, e.g. PropertyFloatItem::setValue which there is a double represented as string. Then we go through the properties and according to the parent type (subclasses of PropertyContainer) we create a string to which we can assign the value. So, we get e.g. a like like: FreeCAD.getDocument("Test").getObject("Part").Width = 3.0000 Then we pass this string to the Python interpreter to run it. > I blame the edit mode in the GUI, not the rotation or matrix classes. Ah, now I see. Yes I can confirm this too. Unfortunately the problem is with OpenInventor which only works with floating point values of single precision. The problem, however, also depends on how we handle the motion of the dragger because it gets called already before the user moves. The fix is to use SoDragger's addMotionCallback instead of using a SoNodeSensor. |
|
> 1. "float q0, q1, q2, q3;" OpenInventor uses floats but nowhere double, so no chance to have double precision. But using addMotionCallback the callback function gets only called when the user starts to move. > 2. it think it's not wise to set the rotation using... How is this related to the issue? |
|
In the past i abused the transform mode to touch objects. So that should be working by now. But this is not the case if i actually want to manipulate my object. I would like to split translation and rotation. If i only rotate the object, the translation should not be messed up. If i only translate the object, the rotation should not be messed up. In the long run, quantizing the movements might make sense. But that would surely be a feature. > > 2. it think it's not wise to set the rotation using... > How is this related to the issue? It as well seems to degrade the precision of the rotation, due to the limited amount of decimal places used to create the QVariant. Should i open a separate ticket? |
|
> It as well seems to degrade the precision of the rotation, due to the limited amount of decimal places used to create the QVariant. One could make a fix precision of 16 when creating the string from a double but this doesn't solve anything because the problem is that the spin box already looses accuracy. |
|
it won't help for an arbitrary rotation. But it would help for common rotations. if i enter 90.00 degree, or 22.5 degree, i can live with the rounding of the spinbox. But rounding the radians or the quaternion will degrade the precision. To me it is counter-intuitive to edit the placement in the property view using an axis and an angle, but getting presented with a quaternion. however specifying axis and angle will impose the same rounding problem, as soon as the (normalized) axis gets rational. |
|
git show 19619c0 fixes the issue when using Coin's draggers. |
|
Thanks Werner I will close this one as resolved and open a feature request for the property issue. |
FreeCAD: master a48ec3ce 2014-02-27 14:43:07 Details Diff |
+ fixes 0001441: entering Transform mode degrades the Placemens rotation to single precision |
Affected Issues 0001441 |
|
mod - src/Gui/ViewProviderGeometryObject.cpp | Diff File | ||
mod - src/Gui/ViewProviderGeometryObject.h | Diff File | ||
FreeCAD: master 19619c03 2014-02-28 11:22:09 Details Diff |
0001441: entering Transform mode degrades the Placemens rotation to single precision |
Affected Issues 0001441 |
|
mod - src/Gui/ViewProviderGeometryObject.cpp | Diff File |
Date Modified | Username | Field | Change |
---|---|---|---|
2014-02-25 12:12 | shoogen | New Issue | |
2014-02-26 15:32 | wmayer | Note Added: 0004311 | |
2014-02-26 18:31 | shoogen | Note Added: 0004313 | |
2014-02-26 21:51 | shoogen | Note Added: 0004314 | |
2014-02-27 12:13 | shoogen | Note Added: 0004318 | |
2014-02-27 13:41 | wmayer | Note Added: 0004319 | |
2014-02-27 14:04 | wmayer | Note Added: 0004320 | |
2014-02-27 14:09 | wmayer | Changeset attached | => FreeCAD Master master a48ec3ce |
2014-02-27 14:09 | wmayer | Assigned To | => wmayer |
2014-02-27 14:09 | wmayer | Status | new => closed |
2014-02-27 14:09 | wmayer | Resolution | open => fixed |
2014-02-27 17:04 | shoogen | Note Added: 0004324 | |
2014-02-27 17:04 | shoogen | Status | closed => feedback |
2014-02-27 17:04 | shoogen | Resolution | fixed => reopened |
2014-02-27 18:13 | wmayer | Note Added: 0004325 | |
2014-02-27 18:36 | shoogen | Note Added: 0004326 | |
2014-02-27 18:36 | shoogen | Status | feedback => assigned |
2014-02-28 08:06 | shoogen | Note Edited: 0004326 | |
2014-02-28 10:23 | wmayer | Note Added: 0004332 | |
2014-02-28 11:45 | shoogen | Note Added: 0004333 | |
2014-02-28 11:45 | shoogen | Status | assigned => closed |
2014-02-28 11:45 | shoogen | Resolution | reopened => fixed |
2014-02-28 11:45 | shoogen | Fixed in Version | => 0.14 |
2017-03-27 08:18 | Kunda1 | Changeset attached | => FreeCAD master 19619c03 |