C# - Get face of extruded hole?

C# - Get face of extruded hole?

ieatacid
Participant Participant
1,124 Views
6 Replies
Message 1 of 7

C# - Get face of extruded hole?

ieatacid
Participant
Participant

I'm trying to get the face plane of an extruded hole (blue in picture below) to start a sketch. I'm using the CustomCommand addin example as a reference and this works to get the extruded hole:

EnableInteraction()
{
...
m_selectEvents.AddSelectionFilter(SelectionFilterEnum.kPartFaceCylindricalFilter);
...
}

And in OnPreSelect , preSelectEntity even evaluates to Face. But if I pass the Face to AddByPlaneAndOffset it throws an exception about the face being a wrong parameter. It works fine if I change the selection filter to kPartFacePlanarFilter and select the actual face (red in picture).

 

Is there a way to use kPartFaceCylindricalFilter as my selection filter and get the face of the cylinder? I spent a good 8 hours looking in the API reference and trying different things.  Picture for reference:

cylinderface.jpg

0 Likes
1,125 Views
6 Replies
Replies (6)
Message 2 of 7

ieatacid
Participant
Participant

Here is some more information. The exception:

exception.jpg

 

 

And the intended result when I use kPartFacePlanarFilter as the selection filter (but I need to use kPartFaceCylindricalFilter so I can select the cylinder (extruded hole)):

success.jpg

 

I would love you forever if you can help!

0 Likes
Message 3 of 7

BrianEkins
Mentor
Mentor

Creating a work plane requires a planar entity as input.  You see the same thing in the UI.  You can't create a work plane by only selecting a cylindrical face.

 

However, it is possible to find the faces that are on the ends of the hole.  If the hole is a through hole then there are two potential faces and you'll have to choose which one.  If it's a blind hole and the bottom is angled then it's fairly easy.  The cylindrical face you've found is represented by the Face object.  The Face object supports an Edges property which returns all of the edges of the face.  In the case of your hole example, there will be two edges returned.  The edges are represented by the Edge object and the Edge object supports a Face property which returns the faces that are connected to the edge.  This will return two faces, the cylindrical face you already have and the connecting face.  For a blind hole with an angled end, this will return a conical face but the face you're looking for will be a plane.  I'm not able to take the time to code up the sample but that's the workflow I would go through.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes
Message 4 of 7

ieatacid
Participant
Participant

Thanks for your reply. That makes sense but here are some debug messages that don't match those numbers 

RackFaceCmd.OnSelect m_extrudeFace.EdgeLoops.Count  4
RackFaceCmd.OnSelect m_extrudeFace.Edges.Count      22
0 Likes
Message 5 of 7

ieatacid
Participant
Participant

Well this works, but it's obviously not the *right* way to do it (I don't think)

    Edge edge = m_extrudeFace.Edges[1];
    Face face = edge.Faces[1];
    WorkPlane workPlane = workPlanes.AddByPlaneAndOffset(face, dOffset);
    workPlane.Visible = true;

There has to be a way to check if the edge is right on the face of the part - or will this always be the case with edge 1?

 

Edit: Another hole that doesn't go all the way through produced the same exception as above, so it's not going to work unless I can figure out how to check if edge->face is at the opening of the hole (open to suggestions >.< )

0 Likes
Message 6 of 7

ieatacid
Participant
Participant

This "just works" and selects the correct face to add the plane to. Still, I'd like to find a way to be absolutely sure it's the same face as the hole's face.

    Face planarFace = null;

    for (int i = m_extrudeFace.Edges.Count; i > 0; i--)
    {
        Edge edge = m_extrudeFace.Edges[i];

        if (edge != null)
        {
            int nFaces = edge.Faces.Count;

            for (int j = 1; j <= nFaces; j++)
            {
                Face face = edge.Faces[j];

                if(face.SurfaceType == SurfaceTypeEnum.kPlaneSurface)
                {
                    Message("Planar surface found!");
                    planarFace = face;
                }
            }
        }

    }

    if(planarFace != null)
    {
        WorkPlane workPlane = workPlanes.AddByPlaneAndOffset(planarFace, 0);
        workPlane.Visible = true;
    }
0 Likes
Message 7 of 7

BrianEkins
Mentor
Mentor

Here's some code that should give the right result every time, assuming that it's a blind hole and there are no other cuts into the hole.  Other cases would be possible to handle too but will need some more logic to identify them.

 

private void button1_Click(object sender, EventArgs e)
{
    Inventor.Application invapp = (Inventor.Application)Marshal.GetActiveObject("Inventor.Application");

    PartDocument partDoc = (Inventor.PartDocument)invapp.ActiveDocument;
    PartComponentDefinition partComp = partDoc.ComponentDefinition;

    // Get the extrude feature named "Extrusion2".
    ExtrudeFeature extrude = (ExtrudeFeature)partComp.Features["Extrusion2"];

    // Get the side face of the extrusion.
    Face sideFace = extrude.SideFaces[1];

    // Iterate over the edges of the face and find the connecting faces.
    Face endFace = null;
    foreach (Edge testEdge in sideFace.Edges)
    {
        // Get the face that connects to the side face using the current edge.
        Face otherFace = GetConnectedFace(sideFace, testEdge);

        // check to see if this face isn't the bottom of the hole by
        // making sure it isn't one of the faces created by the extrude.
        bool badFace = false;
        foreach (Face extrudeFace in extrude.Faces)
        {
            if (extrudeFace == otherFace)
            {
                badFace = true;
                break;
            }
        }

        // It isn't one of the extrude faces so keep it.
        if (!badFace)
        {
            endFace = otherFace;
            break;
        }
    }

    if (endFace != null)
    {
        // A face was found so create a work plane.
        WorkPlane workPlane = partComp.WorkPlanes.AddByPlaneAndOffset(endFace, 0);
    }
}

// Function that given a face and an edge on that face returns
// the connecting face.
private Face GetConnectedFace(Face knownFace, Edge knownEdge)
{
    if (knownEdge.Faces[1] == knownFace)
        return knownEdge.Faces[2];
    else
        return knownEdge.Faces[1];
}
---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
0 Likes