Python Features / Concept and Reference

Post here for help on using FreeCAD's graphical user interface (GUI).
Forum rules
and Helpful information
IMPORTANT: Please click here and read this first, before asking for help

Also, be nice to others! Read the FreeCAD code of conduct!
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python Features / Concept and Reference

Post by wmayer »

I have debugged your example but couldn't locate the problem that is causing the failure. Under http://free-cad.svn.sourceforge.net/vie ... y?view=log you'll find a fully working example.
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python Features / Concept and Reference

Post by wmayer »

Here are some answers to some of your questions:
But it is not so easy to work with it. The concept is not clear to me.
The idea is quite simple. In C++ we have the class App::Document which has a list of App::DocumentObject objects it manages. The App::DocumentObject has some important methods like execute() to recompute itself, onChanged() to check if one of its properties has changed and some more which are not of much interest in this context.
Then we have the class App::FeaturePython which is the bridge between C++ and Python. The FeaturePython has the property Proxy which needs a reference to your Python class. FeaturePython reimplements the methods execute() and onChanged() and just calls the same methods of your Python proxy object. That's basically the whole idea.

On the GUI side we have Gui::Document which manages a list of Gui::ViewProviderDocumentObject objects and also have a special view provider implemented for Python. It follows exactly the same principles as in App.
Some properties can be edit, some are read-only, some are hidden
Certain properties have some special attributes. Read-only means that they cannot be changed via property editor or Python.
Hidden means that the property doesn't appear in the property editor but can still be accessed via Python.
Some are listed, but seems to be missing.
Some are doing a lot by itself (for example App::PropertyFileIncluded). Some using (may be wrong kind) crashes FreeCAD.
For a property which should appear in the property editor a special editor class must be implemented to allow the user to see/change it. There are still a few property classes left for which no editor is implemented and thus don't appear in the property editor view.

It would be good to tell us for which properties you get a crash.

If i add a integer Property and DO NOT set them, they will be init by FreeCAD with the Value -842150451. Shouldn't this be 0?
Yes, make sense to fix this.
How can i set the value of a App::PropertyEnumeration property with python? Which python type is used?
Until now this wasn't possible. Now you can add it by assigning a list of strings. The assertion failure is also fixed.

Code: Select all

App.newDocument()
s=App.ActiveDocument.addObject("App::FeaturePython","feature")
s.addProperty("App::PropertyEnumeration","Enums")
s.Enums=["One","Two","Three"]
I would prefer to also remove it from the supportedProperties() list.
Yes, makes sense.
jacknotreally
Posts: 75
Joined: Mon Dec 14, 2009 9:49 am

Re: Python Features / Concept and Reference

Post by jacknotreally »

wmayer wrote:I have debugged your example but couldn't locate the problem that is causing the failure. Under http://free-cad.svn.sourceforge.net/vie ... y?view=log you'll find a fully working example.
Hi werner,

after testing a while i think i have found the problem. It seems to be the _ character (ascii 95 / 0x5F) in the var-Name.

this will work

Code: Select all

obj.addProperty("Part::PropertyPartShape","PxShape8")
and this wont

Code: Select all

obj.addProperty("Part::PropertyPartShape","P_Shape8")
I hope it will help.

Cheers, Jack - not really
jacknotreally
Posts: 75
Joined: Mon Dec 14, 2009 9:49 am

removeObject() / crash

Post by jacknotreally »

Hi,

when i am using the following python feature, FreeCAD crashes.

This happens, the second time the feature is recomputed. At this time removeObject() should remove my shape named "QSShape".
It seems, that the combination of the shape-NAME and the python-feature-Name create the problem.
In each example where the NAME of the python-feature (QS) is the beginning of the Shape name, this happens.

Examples:
Feature name = 'QS' + Shape name ='QSShape' => crash
Feature name = 'aQS' + Shape name ='aQSShape' => crash
Feature name = 'aQSx' + Shape name ='aQSxShape' => crash
Feature name = 'bQSx' + Shape name ='aQSxShape' => OK

Code: Select all

import FreeCAD
import FreeCAD as App
from FreeCAD import Base
import Part


class pfViewProvider_Base:
    def __init__(self, obj):
        obj.Proxy = self

    def attach(self, obj):
        pass

    def updateData(self,fp, prop):
        pass



class pfTest2:
    def __init__(self, obj):
        obj.addProperty('App::PropertyFloat',"Width",'Group').Width=200
        obj.Proxy = self
        pfViewProvider_Base(obj.ViewObject)

    def onChanged(self, fp, prop):
        pass

    def execute(self,fp):
        ShapeName='QSShape'
        o=App.ActiveDocument.getObject(ShapeName)
        if o:
            App.ActiveDocument.removeObject(ShapeName)
        Shape=Part.makeBox(fp.Width,100,100)
        f=App.ActiveDocument.addObject("Part::Feature", ShapeName)
        f.Shape = Shape


def makeTest2Feature():
    pf=App.ActiveDocument.addObject("App::FeaturePython",'QS')
    pfTest2(pf)
    return pf
Cheers, Jack - not really
User avatar
jriegel
Founder
Posts: 3369
Joined: Sun Feb 15, 2009 5:29 pm
Location: Ulm, Germany
Contact:

Re: Python Features / Concept and Reference

Post by jriegel »

Mhhh,
I think the problem is change the document while recomputation....
The document build up a boost graph to do the recomputation.
When a object is removed while recomputing its most likely you have invalid pointer.
I think I have to prohibit the deletion of objects while recomputing :(
Stop whining - start coding!
jacknotreally
Posts: 75
Joined: Mon Dec 14, 2009 9:49 am

Re: Python Features / Concept and Reference

Post by jacknotreally »

jriegel wrote:Mhhh,
I think the problem is change the document while recomputation....
The document build up a boost graph to do the recomputation.
When a object is removed while recomputing its most likely you have invalid pointer.
I think I have to prohibit the deletion of objects while recomputing :(
But this only happens in this special name case! This might suggest something else.
Maybe FreeCAD tries to remove the feature (not the shape) itself while recompute it?
FreeCAD 0.8 is running this example without any error!

Execute() is the central point to redesign the feature. I do not believe that we can give up removeObject().
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python Features / Concept and Reference

Post by wmayer »

Hi,

the problem is really that the object gets removed during the recompute of the document. The crash, however, is not a dangling pointer but the access to its internal document name which is reset to 0. Passing 0 to a std::string causes the crash then.

Note: If undo/redo is disabled in the user preferences then a removed object gets deleted immediately and the above reference would even become to a dangling pointer.

Indeed, the examples work where the shape name is lower than the feature name (lexical comparison). This is working because the object that gets removed is processed _before_ the other object and thus doesn't cause the crash.

I have now fixed this problem by nullifying the pointer of removed objects in an internal list that gets setup at a document recompute. So, removing objects inside a execute method is still possible although this is not the recommended way.

Werner
jacknotreally
Posts: 75
Joined: Mon Dec 14, 2009 9:49 am

removeObjects()

Post by jacknotreally »

Hi werner,
wmayer wrote: .... So, removing objects inside a execute method is still possible although this is not the recommended way.
I agree, removing objects during recompute may not be "state of the art".

I have used it, because i have not enough practical knowledge. What i tried, was to change the contents of a shape (Part::Feature).
But why removing and recreate the feature? I just have to assign a new contents to (Part::Feature).Shape. This works fine.
Is it right that creating new features inside a execute() will not affect the actual recompute because the actual Document.recompute() don´t know them (yet)?

Cheers, Jack - not really
Post Reply