Scripted objects

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!
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted objects

Postby shoogen » Mon Mar 19, 2012 6:39 pm

wmayer wrote:About how to write pickable classes checkout the Python documentation for this.
But there is still some odd behavoir, like the 'Object' attribute of a ViewProvider Proxy gets magicly restored even if i override __setstate__(self,state).
helo10
Posts: 81
Joined: Tue Feb 21, 2012 7:32 am

Re: Scripted objects

Postby helo10 » Thu Mar 29, 2012 6:56 pm

shoogen wrote: the 'Object' attribute of a ViewProvider Proxy gets magicly restored even if i override __setstate__(self,state).
The Object-attribute gets restored if you do not override get/setstate?
And you initialzid you Object attribute like that?

Code: Select all

    def __init__(self,vobj):
        ...
        self.Object = vobj.Object
        ...
User avatar
yorik
Site Admin
Posts: 11567
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Scripted objects

Postby yorik » Thu Mar 29, 2012 8:01 pm

helo10 wrote:The Object-attribute gets restored if you do not override get/setstate?
No... According to Werner the best way is to setup your Object attribute in the attach() method. Since that method is run on object creation and on file load, you are sure you will always have it present. Another solution is of course to save it with get/setstate, but this is much simpler IMHO

Code: Select all

def attach(self,vobj):
    ...
   self.Object = vobj.Object
helo10
Posts: 81
Joined: Tue Feb 21, 2012 7:32 am

Re: Scripted objects

Postby helo10 » Fri Mar 30, 2012 6:35 am

thanks yorik,
that was the information I was searching for ;)
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted objects

Postby shoogen » Mon May 07, 2012 3:08 pm

Can anyone explain what the relation between the Object Placement and the Shape.Placement is, why Placements get lost when copying Shapes and assigning them in an execute function and whow to safely do transformations on a shape in a parametric object?
If the base object is a boolean, the shape is fine. If the base object is a primitive i need to manualy do a transformGeometry(baseobj.Placement). This doesn't make any sense to me.
User avatar
yorik
Site Admin
Posts: 11567
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Scripted objects

Postby yorik » Mon May 07, 2012 3:38 pm

As far as I know things work like this:
- if a shape is bound to an object, their placements are kept in sync automatically.
- if you create a new shape, it always starts with a null placement. adding pieces to it doesn't modify that placement.

I think, if I understand your problem correctly, that the boolean takes 2 shapes, which have each a specific placement, and creates a new shape, with null placement, but constructed with pieces of the 2 objects, which are at correct positions. When you create a primitive from scratch, it always starts at position 0,0...

Usually in parametric objects, I do like this:

Code: Select all

def execute(self,obj):
    pl = obj.Placement
    # construct shape here
    obj.Shape = shape # this has the effect of resetting the object placement to adopt the shape placement (usually null)
    obj.Placement = pl # to restore the initial placement
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted objects

Postby shoogen » Mon May 07, 2012 3:50 pm

Thanks, it seems that removeSpliter loses the Shape.Placement for the Result of booleans.

EDIT: Filed as https://sourceforge.net/apps/mantisbt/f ... php?id=699
Last edited by shoogen on Mon May 07, 2012 4:08 pm, edited 1 time in total.
User avatar
yorik
Site Admin
Posts: 11567
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Scripted objects

Postby yorik » Mon May 07, 2012 3:59 pm

hm that's possible indeed. The algorithm probably reconstructs the shape from scratch...
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: Scripted objects

Postby shoogen » Thu May 10, 2012 7:39 am

Is there a safe way to apply a placement to a Shape?
transformShape seems to only modify the Shapes Placement.
transformGeometry expects affine transformations which is not needed in this case.
It takes the current Placement into account but istead of returning the null placement. It modifies the geometry to be relative to the Placement of the old Shape. I had once problems with transformGeometry with the unity matrix. But I can't repruce it right now.
On the other hand implicit dropping the Shape after assignment, like i do with the MatrixTransformation and RefineShape Features in the OpenSCAD module is probalbly bad. And an 'applyPlacement' feature would nullify the Placement.
wmayer
Site Admin
Posts: 14899
Joined: Thu Feb 19, 2009 10:32 am

Re: Scripted objects

Postby wmayer » Thu May 10, 2012 9:22 am

Never use transformGeometry() unless you really want to apply an affine transformation other than translations or or rotations (e.g. shearing, scaling, ...) because this always changes the underlying geometry to b-splines. And since boolean operations with splines in OCC are very weak you'll run into a lot of trouble later.

If you have a part feature instance then the "transformShape" of its Shape attribute cannot be used because it's marked as immutable and will throw an exception. So, the fastest way is to apply the placement to the Placement attribute of the part feature. We don't have a method for the feature classes to apply incremental changes on the placement so you have to do that on your own.

Code: Select all

part = App.ActiveDocument.addObject("Part::Feature")
part.Shape = ...
part.Placement = ...
# apply transformation
placement = ...
part.Placement = placement * part.Placement