View Issue Details

IDProjectCategoryView StatusLast Update
0001441FreeCADBugpublic2017-03-27 08:18
Reportershoogen Assigned Towmayer  
PrioritylowSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Versiontrunk 
Fixed in Version0.14 
Summary0001441: entering Transform mode degrades the Placemens rotation to single precision
Descriptionentering Transform mode an Part::Feature degrades the Placements rotation to single precision.
>>> App.ActiveDocument.prism.Placement.Rotation.toEuler()
(30.000006837567817, 0.0, 0.0)
TagsNo tags attached.
FreeCAD Information

Activities

wmayer

2014-02-26 15:32

administrator   ~0004311

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.

shoogen

2014-02-26 18:31

developer   ~0004313

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.

shoogen

2014-02-26 21:51

developer   ~0004314

the commit form today afternoon did not chage anything.
BTW: is there a guide that explains how setPropertyValue(data); for the PropertyItems work?

shoogen

2014-02-27 12:13

developer   ~0004318

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

wmayer

2014-02-27 13:41

administrator   ~0004319

> 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.

wmayer

2014-02-27 14:04

administrator   ~0004320

> 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?

shoogen

2014-02-27 17:04

developer   ~0004324

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?

wmayer

2014-02-27 18:13

administrator   ~0004325

> 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.

shoogen

2014-02-27 18:36

developer   ~0004326

Last edited: 2014-02-28 08:06

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.

wmayer

2014-02-28 10:23

administrator   ~0004332

git show 19619c0 fixes the issue when using Coin's draggers.

shoogen

2014-02-28 11:45

developer   ~0004333

Thanks Werner
I will close this one as resolved and open a feature request for the property issue.

Related Changesets

FreeCAD: master a48ec3ce

2014-02-27 14:43:07

wmayer

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

wmayer

Details Diff
0001441: entering Transform mode degrades the Placemens rotation to single precision Affected Issues
0001441
mod - src/Gui/ViewProviderGeometryObject.cpp Diff File

Issue History

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