Part Design scripting

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Part Design scripting

Post by TheMarkster »

I have added a new section to the scripted objects page in the wiki:

https://wiki.freecadweb.org/Scripted_objects

detailing creating solid features that work well in Part Design. Scroll down to the bottom of the page to see the section and the example, code: a tube primitive for Part Design.

When creating solid feature objects for Part Design there are a number of considerations:

handling placement/attachment
fusing with/cutting from the base feature (object before your object in the tree)
handling an additional 2nd shape if you want your object to be usable in pattern features, such as polar pattern

When it comes to placement/attachment the example code shows how to do it. It's tricky, but seems to work fairly well with the tube object. (Code was borrowed from gears workbench.) Note: even Part Design native primitive objects are a bit wonky when it comes to attachment positioning.

Because of the way Part Design works each solid in the feature tree must build upon the previous solid feature. With additive objects the current object, example a Pad, gets fused to any previous solid feature and so the Pad's shape is actually the extruded sketch *and* the previous shape (BaseFeature property in the code). With subtractive objects (like Pocket) the extruded material is cut from the previous shape rather than fused with it.

Base your feature python object not on Part::FeaturePython, but on PartDesign::FeaturePython. Doing this means it inherits the BaseFeature property and gets treated as a native Part Design object (and not added as a "BaseFeature" into the body). The BaseFeature property automatically points to the previous solid feature. You just need to check that isn't null (your object is first in the feature tree) before fusing/cutting with it.

If you want your object to work with pattern features, base it on either PartDesign::FeatureAdditivePython or PartDesign::FeatureSubtractivePython and manage a new property inherited from these "AddSubShape". AddSubShape is the actual shape of your object (before fusing/cutting with the BaseFeature). Use something like fp.AddSubShape = my_object_shape. The pattern feature tool will manage whether this pattern shape should be cut from existing material or fused to existing material based on which class the object is created with. I know of no way to dynamically change this -- it's either created as an additive or as a subtractive feature.

When using one of the PartDesign::FeaturePython classes your object will be expected to be a solid and to manage for itself fusing/cutting with the BaseFeature. If you want to create a 2D object, such as for using as a profile or path or whatever, Part::Part2DObjectPython, because it can dragged/dropped into the body and treated more or less the way the Body will treat a sketch.

Migrating existing classes from Part::FeaturePython to PartDesign::FeaturePython is not too difficult. You just need to check for the BaseFeature property (hasattr(fp,"BaseFeature")) and fuse your shape with it if it exists and isn't null. Using one of the additive/subtractive classes will also involve the AddSubShape property, which can simply be your existing fp.Shape property. Use body.addObject() to add to the end of the body and make it the new tip or use body.insertObject() to place it after / before some existing solid feature (target).

The multiple solid rule is still in effect, meaning your shape should be a contiguous solid, but it actually works just fine if it has multiple solids so long as it's the tip feature in the body or so long as the next feature tool results in a single contiguous solid. For example, you could have an array tool that generates multiple solids, and the user can then make a sketch and pad it so that it connects all the separate objects in the array.

I learned these things while working on the PDWrapper macro, stumbling across the PartDesign::FeatureAdditivePython and PartDesign::FeatureSubtractivePython classes while looking through the source code.
Post Reply