add App::PropertyQuatity per Python

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

add App::PropertyQuatity per Python

Post by bernd »

Code: Select all

from FreeCAD import Units
from femobjects import base_fempythonobject

class MyNewObject(base_fempythonobject.BaseFemPythonObject):

    Type = "Fem::MyNewObject"

    def __init__(self, obj):
        super(MyNewObject, self).__init__(obj)
        obj.addProperty(
            "App::PropertyQuantity",
            "MyNewProperty",
            "MyPropertyGroup",
            "Set my new PropertyQuantity"
        )



newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
MyNewObject(newobj)
newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")
newobj.MyNewProperty = Units.Quantity("1 mm")



Code: Select all

>>> 
>>> from FreeCAD import Units
>>> from femobjects import base_fempythonobject
>>> 
>>> class MyNewObject(base_fempythonobject.BaseFemPythonObject):
... 
...     Type = "Fem::MyNewObject"
... 
...     def __init__(self, obj):
...         super(MyNewObject, self).__init__(obj)
...         obj.addProperty(
...             "App::PropertyQuantity",
...             "MyNewProperty",
...             "MyPropertyGroup",
...             "Set my new PropertyQuantity"
...         )
... 
>>> 
>>> 
>>> newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
>>> MyNewObject(newobj)
<__main__.MyNewObject object at 0x7f6e3d351b70>
>>> newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ArithmeticError: Not matching Unit!
>>> newobj.MyNewProperty = Units.Quantity("1 mm")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ArithmeticError: Not matching Unit!
>>> 
I am not able to assign any value to the App.PropertyQuantity
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: add App::PropertyQuatity per Python

Post by vocx »

bernd wrote: Wed Jun 24, 2020 8:03 pm "App::PropertyQuantity",
Is PropertyQuantity used by itself at all?

Maybe it's just subclassed and used in PropertyLength, PropertyArea, PropertyVolume, etc.

https://github.com/FreeCAD/FreeCAD/blob ... its.h#L121

https://github.com/FreeCAD/FreeCAD/blob ... its.h#L145

https://github.com/FreeCAD/FreeCAD/blob ... its.h#L157

https://github.com/FreeCAD/FreeCAD/blob ... its.h#L169
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: add App::PropertyQuatity per Python

Post by bernd »

Ahh that would mean the correct way to do it would be adding this to FreeCAD App ...

https://github.com/berndhahnebach/FreeC ... 00ca933966 and use it this way ...

Code: Select all

from FreeCAD import Units
from femobjects import base_fempythonobject

class MyNewObject(base_fempythonobject.BaseFemPythonObject):

    Type = "Fem::MyNewObject"

    def __init__(self, obj):
        super(MyNewObject, self).__init__(obj)
        obj.addProperty(
            "App::PropertyVacuumPermittivity",
            "MyNewProperty",
            "MyPropertyGroup",
            "Set my new PropertyQuantity"
        )



newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
MyNewObject(newobj)
newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")  # ok
newobj.MyNewProperty = Units.Quantity("1 mm")  # error

wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: add App::PropertyQuatity per Python

Post by wmayer »

PropertyQuantity is a generic quantity property and it handles arbitrary units. However, you are not allowed to change the unit by assigning a quantity with a different unit. This is to avoid to unintentionally change the unit.

To change it you must do:

Code: Select all

newobj.MyNewProperty = Units.Length
Afterwards you can assign

Code: Select all

newobj.MyNewProperty = Units.Quantity("1 mm")
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: add App::PropertyQuatity per Python

Post by bernd »

wmayer wrote: Thu Jun 25, 2020 6:29 am PropertyQuantity is a generic quantity property and it handles arbitrary units. However, you are not allowed to change the unit by assigning a quantity with a different unit. This is to avoid to unintentionally change the unit.
Aha, thus the following works before a unit is assigned.

Code: Select all

Units.Unit(newobj.MyNewProperty)
newobj.MyNewProperty = Units.Quantity("1")
newobj.MyNewProperty = Units.Quantity(2)
newobj.MyNewProperty = 3
newobj.MyNewProperty = "4"

Code: Select all

>>> 
>>> Units.Unit(newobj.MyNewProperty)
Unit:  (0,0,0,0,0,0,0,0)
>>> newobj.MyNewProperty = Units.Quantity("1")
>>> newobj.MyNewProperty = Units.Quantity(2)
>>> newobj.MyNewProperty = 3
>>> newobj.MyNewProperty = "4"
>>> 
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: add App::PropertyQuatity per Python

Post by bernd »

for the sake of completeness

Code: Select all

from FreeCAD import Units
from femobjects import base_fempythonobject

class MyNewObject(base_fempythonobject.BaseFemPythonObject):
    Type = "Fem::MyNewObject"
    def __init__(self, obj):
        super(MyNewObject, self).__init__(obj)
        obj.addProperty(
            "App::PropertyQuantity",
            "MyNewProperty",
            "MyPropertyGroup",
            "Set my new PropertyQuantity"
        )
        obj.MyNewProperty = Units.VacuumPermittivity



newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
MyNewObject(newobj)
newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")
newobj.MyNewProperty

Code: Select all

>>> 
>>> from FreeCAD import Units
>>> from femobjects import base_fempythonobject
>>> 
>>> class MyNewObject(base_fempythonobject.BaseFemPythonObject):
...     Type = "Fem::MyNewObject"
...     def __init__(self, obj):
...         super(MyNewObject, self).__init__(obj)
...         obj.addProperty(
...             "App::PropertyQuantity",
...             "MyNewProperty",
...             "MyPropertyGroup",
...             "Set my new PropertyQuantity"
...         )
...         obj.MyNewProperty = Units.VacuumPermittivity
... 
>>> 
>>> 
>>> newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
>>> MyNewObject(newobj)
<__main__.MyNewObject object at 0x0000023CC146B6A0>
>>> newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")
>>> 
>>> newobj.MyNewProperty 
1e-09 s^4*A^2/(mm^3*kg)
>>>
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: add App::PropertyQuatity per Python

Post by vocx »

Should every Unit have an App::Property?

I raised this question in the past. It seems every unit should have its own property type. Otherwise, the use of App::PropertyQuantity should be more documented, like Werner explains in this thread.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: add App::PropertyQuatity per Python

Post by bernd »

I was asking myself the same question today.

I will implement the property for vacuum permittivity. IMHO the generic property quantity.should be used if one can not just change source and compile FreeCAD. Might be because one has to stay with stable release version or one is just not able to compile, or whatever.
josegegas
Posts: 241
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: add App::PropertyQuatity per Python

Post by josegegas »

Hello.

When I use the code above to create a scripted object:

Code: Select all

from FreeCAD import Units
from femobjects import base_fempythonobject

class MyNewObject(base_fempythonobject.BaseFemPythonObject):
    Type = "Fem::MyNewObject"
    def __init__(self, obj):
        super(MyNewObject, self).__init__(obj)
        obj.addProperty(
            "App::PropertyQuantity",
            "MyNewProperty",
            "MyPropertyGroup",
            "Set my new PropertyQuantity"
        )
        obj.MyNewProperty = Units.VacuumPermittivity



newobj = App.ActiveDocument.addObject("Fem::ConstraintPython", "FunnyObject")
MyNewObject(newobj)
newobj.MyNewProperty = Units.Quantity("1 s^4*A^2 / (m^3*kg)")
newobj.MyNewProperty
It works fine, it creates the object with a property of the adequate units:

Code: Select all

FreeCAD.getDocument('Cubo').getObject('FunnyObject').MyNewProperty.Unit
returns:

Unit: s^4*A^2/(mm^3*kg) (-3,-1,4,2,0,0,0,0) [VacuumPermittivity]

However when I save the file, close and open it again, the units of "MyNewProperty" are gone. After opening the document again MyNewProperty has no units:

Code: Select all

FreeCAD.getDocument('Cubo').getObject('FunnyObject').MyNewProperty.Unit
returns:

Unit: (0,0,0,0,0,0,0,0)

I am using FreeCAD 0.20 version 26155.

I would appreciate any ideas...

Thanks in advance.
josegegas
Posts: 241
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: add App::PropertyQuatity per Python

Post by josegegas »

Here is the relevant part of my code:

Code: Select all

from FreeCAD import Units
import FreeCAD

class Rigidbody: 
    def __init__(self, obj): 
        obj.addProperty("App::PropertyQuantity",
                        "absolute_angular_velocity_X",
                        "Initial conditions: absolute angular velocity [deg/s]",
                        "X component of the absolute initial angular velocity").absolute_angular_velocity_X = 10.0
        
        obj.absolute_angular_velocity_X = FreeCAD.Units.Unit('deg/s') 
 
    
 
a = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","MyObject")
Rigidbody(a)
This works perfectly, except that when the FreeCAD document is saved, closed and open again, the units of the "absolute_angular_velocity_X" property have disappeared.

Any ideas why?
Post Reply