FeaturePython restoring on document load

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

FeaturePython restoring on document load

Post by Joel_graff »

So I thought I had this figured out, but it appears, I don't. That is, is there a good example of how to re-instance a FeaturePython object when a file reloads?
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: FeaturePython restoring on document load

Post by DeepSOIC »

What problem do you have exactly? There are tons of addon workbenches, and probably 80% of them use FeaturePython, which of course is restored on file load. Not to mention FPs in FC itself.
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: FeaturePython restoring on document load

Post by Joel_graff »

DeepSOIC wrote: Wed Jun 06, 2018 8:26 pm What problem do you have exactly?
Well, I create a FP object with some custom functions and properties. If I save the doc and reload, the properties are accessible since they get serialized, but if I try to call a custom function defined in the original class, Python tells me that the FP object doesn't have that attribute. Of course, I could call those functions after I created the object for the first time, before I saved and reloaded.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FeaturePython restoring on document load

Post by microelly2 »

You have to create the object from a stored script file.
If you create it from the python console and store the model then FreeCAd cannot remember the inner structure of the FP class.
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: FeaturePython restoring on document load

Post by Joel_graff »

microelly2 wrote: Thu Jun 07, 2018 7:05 am You have to create the object from a stored script file.
If you create it from the python console and store the model then FreeCAd cannot remember the inner structure of the FP class.
DeepSOIC wrote: Wed Jun 06, 2018 8:26 pm What problem do you have exactly? There are tons of addon workbenches, and probably 80% of them use FeaturePython, which of course is restored on file load. Not to mention FPs in FC itself.
See code snippet from the python file.

The function add_parameters is conspicuously absent when I try to access the Parameters object after reloading the file.

Code: Select all

"""
Parameters Feature Python object which provides general parameters for a group of objects
"""
__title__ = "parameters.py"
__author__ = "Joel Graff"
__url__ = "https://www.freecadweb.org"

import FreeCAD as App

if App.Gui:
    import FreeCADGui as Gui
    from DraftTools import translate
    from PySide.QtCore import QT_TRANSLATE_NOOP

class Parameters():

    def __init__(self, obj):
        """
        Default constructor
        """

        obj.Proxy = self
        self.Type = "Parameters"
        self.Object = obj

        if App.GuiUp:
            _ViewProviderParameters(obj.ViewObject)

    def __getstate__(self):
        return self.Type

    def __setstate__(self, state):
        if state:
            self.Type = state

    def add_parameter(self, kind, name, description):

        return self.Object.addProperty(kind, name, "Parameters", QT_TRANSLATE_NOOP("App::Property", description))
The Parameters object is instanced from the BoxCulvert class as a child object:

Code: Select all

class BoxCulvert():

    def __init__(self, obj):
        """
        Default constructor
        """

        obj.Proxy = self
        self.Type = "BoxCulvert"
        self.Object = obj

        if App.GuiUp:
            _ViewProviderBoxCulvert(obj.ViewObject)

        obj = App.ActiveDocument.addObject("App::DocumentObjectGroupPython", "Parameters")
        
        parameters = Parameters.Parameters(obj)

        parameters.add_parameter("App::PropertyFloat", "Skew", "Skew of box culvert from roadway centerline").Skew = 15.0

        self.addObject(parameters.Object)
The actual files are linked below:
https://github.com/joelgraff/freecad-tr ... ameters.py
https://github.com/joelgraff/freecad-tr ... Culvert.py
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
microelly2
Veteran
Posts: 4688
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: FeaturePython restoring on document load

Post by microelly2 »

I have changed the code a bit
main thing is the onDocumentRestored method to assign Object again

Code: Select all

"""
Parameters Feature Python object which provides general parameters for a group of objects
"""
__title__ = "parameters.py"
__author__ = "Joel Graff"
__url__ = "https://www.freecadweb.org"

import FreeCAD as App

class _ViewProviderParameters:
	''' basic defs '''

	def __init__(self, obj):
		obj.Proxy = self
		self.Object = obj

	def __getstate__(self):
		return None

	def __setstate__(self, state):
		return None

class _ViewProviderBoxCulvert:
	''' basic defs '''

	def __init__(self, obj):
		obj.Proxy = self
		self.Object = obj

	def __getstate__(self):
		return None

	def __setstate__(self, state):
		return None


if App.Gui:
	import FreeCADGui as Gui
	from DraftTools import translate
	from PySide.QtCore import QT_TRANSLATE_NOOP

class Parameters():

	def __init__(self, obj):
		"""
		Default constructor
		"""

		obj.Proxy = self
		self.Type = "Parameters"
		self.Object = obj

		if App.GuiUp:
			_ViewProviderParameters(obj.ViewObject)

	def __getstate__(self):
		return self.Type

	def __setstate__(self, state):
		if state:
			self.Type = state

	def add_parameter(self, kind, name, description):

		return self.Object.addProperty(kind, name, "Parameters", QT_TRANSLATE_NOOP("App::Property", description))

	def onDocumentRestored(self, fp):
		print "restored"
		self.Object=fp


class BoxCulvert():

	def __init__(self, obj):
		"""
		Default constructor
		"""

		obj.Proxy = self
		self.Type = "BoxCulvert"
		self.Object = obj

		if App.GuiUp:
			_ViewProviderBoxCulvert(obj.ViewObject)

		#obj = App.ActiveDocument.addObject("App::DocumentObjectGroupPython", "Parameters")

		parameters = Parameters(obj)

		parameters.add_parameter("App::PropertyFloat", "Skew", "Skew of box culvert from roadway centerline").Skew = 15.0

		#self.addObject(parameters.Object)



def run():
	obj = App.ActiveDocument.addObject("App::DocumentObjectGroupPython", "Parameters")
	BoxCulvert(obj)



works now for me
Python 2.7.6 (default, Nov 23 2017, 15:53:45)
[GCC 4.8.4] on linux2
Type 'help', 'copyright', 'credits' or 'license' for more information.
>>> import FreeCAD
>>> FreeCAD.open(u"/home/thomas/Schreibtisch/tta.fcstd")
>>> App.setActiveDocument("tta")
>>> App.ActiveDocument=App.getDocument("tta")
>>> Gui.ActiveDocument=Gui.getDocument("tta")
>>> App.ActiveDocument.Parameters.Proxy.add_parameter("App::PropertyFloat", "Skew", "Skew of box culvert from roadway centerline")
<group object>
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: FeaturePython restoring on document load

Post by Joel_graff »

microelly2 wrote: Thu Jun 07, 2018 2:12 pm works now for me
Cool. I also missed the fact that you have to access it through the Proxy object. Should have occurred to me...
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
JLienard
Posts: 3
Joined: Mon Jun 11, 2018 8:32 am

Re: FeaturePython restoring on document load

Post by JLienard »

Hello, I am new user of FreeCAD.
I appreciated being able to create parametric object in Python. I had many difficulties so that they work after saving and reload after restart of FreeCAD. The documentation is not rather precise. Now, it is good. Here am how I made (tested with FreeCAD 0.17).

I takes the basic example of the documentation: https://www.freecadweb.org/wiki/Scripte ... ple_shapes

The code of definition of the class is in a file "pline.py". He is saved in the directory of the macro users. He can be created by the menu "macro of FreeCAD":

Code: Select all

import FreeCAD as App
import FreeCADGui
import FreeCAD
import Part
class Pline:
    def __init__(self, obj):
        '''"App two point properties" '''
        obj.addProperty("App::PropertyVector","p1","Line","Start point")
        obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(1,0,0)
        obj.addProperty("App::PropertyLink","link")
        obj.addProperty("App::PropertyLinkList","links")
        obj.Proxy = self
    def execute(self, fp):
        FreeCAD.Console.PrintMessage("Execute!\n")
        fp.Shape = Part.makeLine(fp.p1,fp.p2)
The code of creation of the object is in another file "pline. FCMacro":

Code: Select all

from pline import Pline
a=App.ActiveDocument.addObject("Part::FeaturePython","Line")
Pline(a)
a.ViewObject.Proxy=0
FreeCAD.ActiveDocument.recompute() 
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: FeaturePython restoring on document load

Post by Joel_graff »

JLienard wrote: Mon Jun 11, 2018 9:20 am The code of definition of the class is in a file "pline.py". He is saved in the directory of the macro users. He can be created by the menu "macro of FreeCAD":
The code you cited is incomplete and, for some reason, the link you provided comes up with an empty page for me.

Here's a link to a clear example (I used it to get started with my code):

https://www.freecadweb.org/wiki/index.p ... ed_objects

You might want to look at that example for some help. The code you posted looks incomplete to me - you didn't define the ViewProvider for the PLine class, for example.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
Post Reply