Need a way to get the face of a created feature.

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Need a way to get the face of a created feature.

Post by freedman »

This isn't all that important; I wanted to do an animated demo of my piping macro. After FreeCAD completes an Additive pipe feature I would like (by code) to select an edge and a face from the newly created pipe feature . I have no idea how to get that info, I currently get the user selections by mouse clicks. If I could get that data I was planning to do a random piping like the Windows ScreenSaver from the old days.
Thanks
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Need a way to get the face of a created feature.

Post by edwilliams16 »

Code: Select all

import FreeCAD as App

doc = App.newDocument()
obj = App.ActiveDocument.addObject('PartDesign::Body', 'Body')
obj.Label = "Custom label"

feature = App.ActiveDocument.addObject('PartDesign::AdditiveBox', 'Box')
feature.Width = 200
feature.Length = 300
feature.Height = 500
obj.addObject(feature)
App.ActiveDocument.recompute()

faces = feature.Shape.Faces
for face in faces:
    print(f'COM = {face.CenterOfMass}')
    for edge in face.Edges:
        print(f'edgeVertexes {[v.Point for v in edge.Vertexes]}')
        
or was this not what you are after?
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Need a way to get the face of a created feature.

Post by freedman »

I would need the edge (pic, arrow) of that feature, then the next additive would be added to that section and so-on. There could also be Tees and 4 ways. I think the only way this could be done is if FreeCAD sent out the data as it built features, maybe not such a bad idea.
Attachments
tube1.png
tube1.png (207.31 KiB) Viewed 1280 times
chrisb
Veteran
Posts: 53933
Joined: Tue Mar 17, 2015 9:14 am

Re: Need a way to get the face of a created feature.

Post by chrisb »

freedman wrote: Fri May 06, 2022 6:21 am I would need the edge (pic, arrow) of that feature, then the next additive would be added to that section and so-on. There could also be Tees and 4 ways. I think the only way this could be done is if FreeCAD sent out the data as it built features, maybe not such a bad idea.
Wouldn't it be better and easier to attach something to the end of the sweep path?
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Need a way to get the face of a created feature.

Post by freedman »

To use a sketch for each pipe routing, I found "SectionOfRevolution" for mapmode. To accomplish using that I need an edge and face selection but I think eventually it can be made by just an edge or face.
It's kind of clumsy to create the sketch in code but I got there and I will describe the process later.

I'm doing the basics right now and would expect better selection modes and viewing to come later. Viewing is tough because FreeCAD has many view options but none are easy to use when trying to target a specific view. Routing a pipe is typically an operation you want in 3D and you also want to see thru objects as you route. I will do a demo soon and post how long it takes to route some complex tubing. Hopefully no leaks. :)
Thanks
Last edited by freedman on Fri May 06, 2022 5:51 pm, edited 1 time in total.
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Need a way to get the face of a created feature.

Post by edwilliams16 »

Similar to @chrisb's suggestion - if you can keep track of the vertex on the end of the pipe, you can search the list of faces for the one that is co-planar with it.

Code: Select all

face.Surface.projectPoint(vertex.Point)
is the distance of the Vertex from the plane, ~0 if coplanar.


EDIT forget this It's more complicated.
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Need a way to get the face of a created feature.

Post by edwilliams16 »

Here's some working code for a simple sweep:

Code: Select all

# -*- coding: utf-8 -*-


import FreeCAD
import Part
import Part,PartGui
from FreeCAD import Base

doc = App.ActiveDocument
circle =doc.addObject("Part::Circle","Circle")
circle.Radius=1
circle.Angle1=0
circle.Angle2=360
circle.Placement=App.Placement(App.Vector(1.0000,0.0000,0.0000),App.Rotation(App.Vector(0.0000,0.0000,1.0000),0.0000))
circle.Label='Circle'

# Object Circle created at document root
doc.recompute()

helix = App.ActiveDocument.addObject("Part::Helix","Helix")
helix.Pitch=10
helix.Height=20
helix.Radius=1
helix.Angle=0
helix.LocalCoord=0
helix.Style=1
helix.Placement=App.Placement(App.Vector(0.0000,0.0000,0.0000),App.Rotation(App.Vector(0.0000,0.0000,1.0000),0.0000))
helix.Label='Helix'
helixedges = helix.Shape.Edges

# Object Helix created at document root
doc.recompute()


sweep = doc.addObject('Part::Sweep','Sweep')
sweep.Sections=[doc.Circle, ]
#doc.ActiveObject.Spine=(doc.getObject('Helix'),['Edge1','Edge2',])
edgenames = ['Edge' + str(i+1) for  i in range(len(helixedges))]  #ugh there must be better
sweep.Spine = (helix, edgenames) 
sweep.Solid=True
sweep.Frenet=True
doc.recompute()

def findendface(obj, spine):
    spineendpoint = spine.Shape.Vertexes[-1].Point  #last vertex  - could be first if drawn opposite way? In which case deal with Vertexes[0] instead
    #print(spineendpoint)
    faces = [face for face in obj.Shape.Faces if face.Surface.isPlanar() ] #sweeps always have planar ends, I think. 
    return (spineendpoint, [ face for face in faces if abs(face.normalAt(0,0).dot(spineendpoint - face.valueAt(0,0))) < 1e-8]) #return faces where spineendpoint lies in the plane of the face

endpoint, face = findendface(sweep, helix) #with luck only one
print(f'end of spine at {endpoint}  face_object {face}')
 
The idea is to find any planar faces of the sweep containing the last vertex of the spine.
freedman
Veteran
Posts: 3441
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Need a way to get the face of a created feature.

Post by freedman »

Thanks Ed
I like this:

Code: Select all

faces = [face for face in obj.Shape.Faces if face.Surface.isPlanar() ] #sweeps always have planar ends, I think. 
A round sweep should have two faces (that are planar) in my case, I attach a new sketch to the last feature so if I identify the attachment face there should only be one left over. :)

I have my process working and I really like the sketch based concept, it allows the user to add any path to the basic sketch I create. I am having some problems with sketch flipping so I need to trap that issue. I will post a limited working macro soon. I would like to attach sketch to sketch with external geo but that might be fragile with TNP.
Post Reply