How to extend an part class inside python?

Need help, or want to share a macro? Post here!
User avatar
microelly2
Posts: 4354
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

How to extend an part class inside python?

Postby microelly2 » Wed Oct 14, 2015 9:51 pm

I want to enrich a standard FreeCAD object example Box by a string list.

Code: Select all

b=App.ActiveDocument.addObject("Part::Box","Box")
b.addProperty("App::PropertyStringList","script","main","script")
It doesnt work because Part::Box has no method to add props.
When I use FeaturePython, then I can add my property but have to reimplement all the Box functionality.

Code: Select all

b1=App.ActiveDocument.addObject("Part::FeaturePython","My")
b1.addProperty("App::PropertyStringList","script","main","script")
I'm looking for something like this (common Qt syntax):

Code: Select all

class MyBox(PartBox):

	def __init__(self,**args):
		super(PartBox, self).__init__(**args)
		self.script=["Hello", "it's so simple to add a property"]
or some other incantation in python to be able for this

Code: Select all

b2=App.ActiveDocument.addObject("Part::Box::MyBox","MyBox")
b2.addProperty("App::PropertyStringList","script","main","script")
b2.script=["Hello", "it's so simple to add a property"]
I'm sure this can be done in C++, but is there a open door for pythoneers too?
wmayer
Site Admin
Posts: 14778
Joined: Thu Feb 19, 2009 10:32 am

Re: How to extend an part class inside python?

Postby wmayer » Thu Oct 15, 2015 9:09 pm

It doesnt work because Part::Box has no method to add props.
For none of the C++ feature classes this is possible. It's as you said only possible for custom feature classes.
When I use FeaturePython, then I can add my property but have to reimplement all the Box functionality.
Yes, but it's not that much code. You just have to add properties for length, width and height and then use Part.makeBox to create the shape.

Code: Select all


class Box:
    def __init__(self, obj):
        PartFeature.__init__(self, obj)
        obj.addProperty("App::PropertyLength","Length","Box","Length of the box").Length=1.0
        obj.addProperty("App::PropertyLength","Width","Box","Width of the box").Width=1.0
        obj.addProperty("App::PropertyLength","Height","Box", "Height of the box").Height=1.0
        obj.Proxy = self

    def onChanged(self, fp, prop):
        if prop == "Length" or prop == "Width" or prop == "Height":
            fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)

    def execute(self, fp):
        fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)
I'm sure this can be done in C++, but is there a open door for pythoneers too?
In C++ it's possible to add a property as class member (i.e. at compile time) which means that this member is bound to the class. But the addProperty method adds a property to a single instance at runtime and this is not possible either in C++. As you can see that addProperty is called inside the __init__ method which means that the properties are added for all created instances separately.
User avatar
microelly2
Posts: 4354
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: How to extend an part class inside python?

Postby microelly2 » Sat Oct 17, 2015 3:14 pm

Thank you,
with your answer I have found the complete example

https://raw.githubusercontent.com/FreeC ... ePython.py

Works fine with other primitives too.
For bool ops I use Part.makeCompound
but what are the Shape constructors for fuse, common and cut?
Part.makeFuse does not exist in pythonland :roll:
wmayer
Site Admin
Posts: 14778
Joined: Thu Feb 19, 2009 10:32 am

Re: How to extend an part class inside python?

Postby wmayer » Sat Oct 17, 2015 3:31 pm

but what are the Shape constructors for fuse, common and cut?
Part.makeFuse does not exist in pythonland
The boolean ops are not part of the module but of the shape class

Code: Select all

import Part
c=Part.makeCylinder(2,10)
b=Part.makeBox(10,10,10)
c.fuse(b)
c.cut(b)
c.common(b)
User avatar
microelly2
Posts: 4354
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: How to extend an part class inside python?

Postby microelly2 » Tue Oct 20, 2015 11:08 am

Thank you Werner once more.
my wrapper is growing - parts and bool ops are okay.
https://www.youtube.com/watch?v=VK8LF1ApNuA
the draft objects are already python featured.

So I want to add the part design objects
Is there a way to get the pad/pockets and sketches too?
wmayer
Site Admin
Posts: 14778
Joined: Thu Feb 19, 2009 10:32 am

Re: How to extend an part class inside python?

Postby wmayer » Tue Oct 20, 2015 7:24 pm

Is there a way to get the pad/pockets
No.
sketches too?
For sketches there is indeed a custom feature version available but the problem is that it's not usable.

Code: Select all

class SketchFeature:
  def __init__(self, obj):
    obj.Proxy = self
  def execute(self, obj):
    pass

SketchFeature(App.ActiveDocument.addObject("Sketcher::SketchObjectPython"))
App.ActiveDocument.ActiveObject.ViewObject.Proxy=1
Now edit it and try to add some geometry...
User avatar
microelly2
Posts: 4354
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: How to extend an part class inside python?

Postby microelly2 » Tue Oct 20, 2015 7:43 pm

thank you, its not the best answer
but so I will use a draft clone and check the idea to have moveable pads ;)
wmayer
Site Admin
Posts: 14778
Joined: Thu Feb 19, 2009 10:32 am

Re: How to extend an part class inside python?

Postby wmayer » Tue Oct 20, 2015 7:59 pm

I have an idea how to overcome the limitations with sketcher. This idea then can be applied to any other high-level feature class, too.
wmayer
Site Admin
Posts: 14778
Joined: Thu Feb 19, 2009 10:32 am

Re: How to extend an part class inside python?

Postby wmayer » Tue Oct 20, 2015 10:47 pm

With git commit e7a3dc48e834591e5553 sketcher can now be used in Python as custom feature.

So, from now on a Python feature doesn't need to have an execute() method any more. If it's not there then the execute() method of the related C++ class is called instead.

If your Python feature must have an execute() method but you also want to call the execute() of the C++ class you must return "False".

Examples:

Code: Select all

class SketchFeature:
  def __init__(self, obj):
    obj.Proxy = self
  def execute(self, obj):
    return False

SketchFeature(App.ActiveDocument.addObject("Sketcher::SketchObjectPython"))
App.ActiveDocument.ActiveObject.ViewObject.Proxy=1

Code: Select all

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

SketchFeature(App.ActiveDocument.addObject("Sketcher::SketchObjectPython"))
App.ActiveDocument.ActiveObject.ViewObject.Proxy=1
User avatar
microelly2
Posts: 4354
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: How to extend an part class inside python?

Postby microelly2 » Wed Oct 21, 2015 4:34 am

Thank you.
So I hope for a rainy weekend to test and use it all.