Python Features / Concept and Reference
Forum rules
and Helpful information
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!
Also, be nice to others! Read the FreeCAD code of conduct!
Re: Python Features / Concept and Reference
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.
Re: Python Features / Concept and Reference
Here are some answers to some of your questions:
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.
Hidden means that the property doesn't appear in the property editor but can still be accessed via Python.
It would be good to tell us for which properties you get a crash.
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.But it is not so easy to work with it. The concept is not clear to me.
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.
Certain properties have some special attributes. Read-only means that they cannot be changed via property editor or Python.Some properties can be edit, some are read-only, some are hidden
Hidden means that the property doesn't appear in the property editor but can still be accessed via Python.
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.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.
It would be good to tell us for which properties you get a crash.
Yes, make sense to fix this.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?
Until now this wasn't possible. Now you can add it by assigning a list of strings. The assertion failure is also fixed.How can i set the value of a App::PropertyEnumeration property with python? Which python type is used?
Code: Select all
App.newDocument()
s=App.ActiveDocument.addObject("App::FeaturePython","feature")
s.addProperty("App::PropertyEnumeration","Enums")
s.Enums=["One","Two","Three"]
Yes, makes sense.I would prefer to also remove it from the supportedProperties() list.
-
- Posts: 75
- Joined: Mon Dec 14, 2009 9:49 am
Re: Python Features / Concept and Reference
Hi werner,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.
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")
Code: Select all
obj.addProperty("Part::PropertyPartShape","P_Shape8")
Cheers, Jack - not really
-
- Posts: 75
- Joined: Mon Dec 14, 2009 9:49 am
removeObject() / crash
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
Cheers, Jack - not really
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
Re: Python Features / Concept and Reference
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
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!
-
- Posts: 75
- Joined: Mon Dec 14, 2009 9:49 am
Re: Python Features / Concept and Reference
But this only happens in this special name case! This might suggest something else.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
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().
Re: Python Features / Concept and Reference
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
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
-
- Posts: 75
- Joined: Mon Dec 14, 2009 9:49 am
removeObjects()
Hi werner,
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
I agree, removing objects during recompute may not be "state of the art".wmayer wrote: .... So, removing objects inside a execute method is still possible although this is not the recommended way.
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