Mapping objects on faces

Need help, or want to share a macro? Post here!
User avatar
dimitar
Posts: 125
Joined: Thu Jun 13, 2019 6:10 am
Location: UK
Contact:

Mapping objects on faces

Postby dimitar » Mon Aug 12, 2019 5:15 pm

New to pyhon in Freecad, but not so new to Python in general.

I am trying to place clones of an object along each face of a compound object. It seems I am doing something wrong with assigning support but I am not sure what since none of the clones are mapped the the faces that I wish for them to be mapped.

Code: Select all

import FreeCAD, Draft, Part

# get main object
mainObj = App.ActiveDocument.diagrid_panels

# get panel object
panelObj = App.ActiveDocument.Sketch020

for i in mainObj.Shape.Faces:
    clone = Draft.clone(panelObj)
    clone.Support=[(mainObj,i)] #is this the correct syntax?
    clone.MapMode='InertialCS'
TheMarkster
Posts: 995
Joined: Thu Apr 05, 2018 1:53 am

Re: Mapping objects on faces

Postby TheMarkster » Mon Aug 12, 2019 7:12 pm

I get this in the python console when mapping a sketch to a face of an object named Draft.

Code: Select all

App.ActiveDocument.Sketch001.Support = [(App.getDocument('Unnamed').Draft,'Face2')]
I don't think the Face object contains its own name or even the index value, so you have to create the string:

(Code is untested, might contain errors.)

Code: Select all

face_names = ['Face0'] #Face0 not actually used, just there as placeholder
for int i in range(1, len(obj.Faces)+1):
    face_names.append('Face'+str(i))

App.ActiveDocument.Sketch001.Support = [(App.ActiveDocument.Draft, face_names[2])]
User avatar
dimitar
Posts: 125
Joined: Thu Jun 13, 2019 6:10 am
Location: UK
Contact:

Re: Mapping objects on faces

Postby dimitar » Mon Aug 12, 2019 8:09 pm

TheMarkster wrote:
Mon Aug 12, 2019 7:12 pm

I don't think the Face object contains its own name or even the index value, so you have to create the string:
Thanks for your suggestion. I've modified my code in the way you suggested and now it works

Code: Select all

mainObj = App.ActiveDocument.diagrid_panels
panelObj = App.ActiveDocument.Sketch020

for i in range(0,len(mainObj.Shape.Faces)):
    clone = Draft.clone(panelObj)
    clone.Support=[(mainObj,'Face'+str(i))]
    clone.MapMode='InertialCS'
There surely must be another way to query faces. since when hovering over a face, I am getting this the face index number. Just not sure how.
FreeCAD_TwhRiBAAa9.png
FreeCAD_TwhRiBAAa9.png (2.81 KiB) Viewed 304 times
kisolre
Posts: 1115
Joined: Wed Nov 21, 2018 1:13 pm

Re: Mapping objects on faces

Postby kisolre » Tue Aug 13, 2019 8:11 am

I think that is the whole toponaming problem. That sub elements dont have actual names but are just created in a list and names are created and translated to indices on the fly.
User avatar
yorik
Site Admin
Posts: 11398
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Mapping objects on faces

Postby yorik » Tue Aug 13, 2019 3:41 pm

IIRC the Support property, which is a PropertySubLink, requires a tuple that contains an object and a subelement name (ie. a string, not the subelement itself). In your code above you pass it the object and the subelement (the face itself).

The subelement names are simple automatically built lists of strings: ["Face1", "Face2",...] or ["Edge1", "Edge2",...]. Beware, they begin with 1. So actually getattr(myObject.Shape,"Face1") == myObject.Shape.Faces[0]

in your case I guess you must just do something like this:

Code: Select all

for i in range(len(shape.Faces)):
    subname = "Face" + str(i+1)
    clone.Support=[(mainObj,subname)]
vocx
Posts: 736
Joined: Thu Oct 18, 2018 9:18 pm

Re: Mapping objects on faces

Postby vocx » Fri Aug 16, 2019 12:48 am

yorik wrote:
Tue Aug 13, 2019 3:41 pm
IIRC the Support property, which is a PropertySubLink, requires a tuple that contains an object and a subelement name (ie. a string, not the subelement itself). ...
Since I am looking into Draft documentation, I always wonder about the Support property that many objects have. I don't quite understand what this is. It seems to be App::PropertyLinkSubList.

Do Draft objects really need this? Or is this something more applicable to PartDesign objects? It seems to me that this is something that Sketches would use to attach themselves to planes or things like that, and helps determine their Base::Placement.
DeepSOIC wrote: ping
Sorry, DeepSOIC, your name is in the sources for Part::App::Attacher, so I was wondering if you could clarify what a Support is, and why it would be present in Draft objects.
User avatar
DeepSOIC
Posts: 6689
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: Mapping objects on faces

Postby DeepSOIC » Fri Aug 16, 2019 1:12 am

vocx wrote:
Fri Aug 16, 2019 12:48 am
I was wondering if you could clarify what a Support is, and why it would be present in Draft objects.
Support property is a part of the attachment mechanism. It represents the references you see in the attachment dialog. Many Draft objects are attachable (most of those base on (attachable) Part2DObject, the parent class for Sketch objects), hence the Support property. For the same reason (inheritance on Part2DObject), many Draft objects can be dragged into PartDesign bodies, and be interpreted as sketches there.
vocx
Posts: 736
Joined: Thu Oct 18, 2018 9:18 pm

Re: Mapping objects on faces

Postby vocx » Fri Aug 16, 2019 2:21 am

DeepSOIC wrote:
Fri Aug 16, 2019 1:12 am
For the same reason (inheritance on Part2DObject), many Draft objects can be dragged into PartDesign bodies, and be interpreted as sketches there.
In my personal use of Draft, I never attach Draft objects to anything. They are just, say, floating. They are built on top of the active working plane. If you change the working plane, the Draft object just stays where it was. Does this mean that the Support property is empty? Or how can we tell when it's really in use?

As you say, maybe Draft objects have this property by inheritance, being derived from Part2DObject, but I'm trying to determine the common use case for it. Maybe that is mostly applicable for Sketches (inside or outside a PartDesign Body), and not with Draft objects?

What about syntax? It seems that Yorik says that it must be a tuple (DocumentObject, "string"). Is this right?
User avatar
DeepSOIC
Posts: 6689
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: Mapping objects on faces

Postby DeepSOIC » Fri Aug 16, 2019 11:13 am

vocx wrote:
Fri Aug 16, 2019 2:21 am
What about syntax?
Like any PropertyLinkSubList:
[(an_object, ["Face1", "Face3"]), (another_object, ["Vertex6", "Edge2"]), ...]
, that is, a list of tuples, each tuple has the reference to document object and a list of strings naming the subelements.

And also supports this legacy syntax for set-value:
[(an_object, "Face1"), (an_object, "Face3"), (another_object, "Vertex6"), ...]
, that is, a list of pairs (object, subelement_name).
vocx
Posts: 736
Joined: Thu Oct 18, 2018 9:18 pm

Re: Mapping objects on faces

Postby vocx » Fri Aug 16, 2019 3:35 pm

DeepSOIC wrote:
Fri Aug 16, 2019 11:13 am
Like any PropertyLinkSubList:
Thanks for the info. I did see in the sources a reference to the "old style" but wasn't sure.