How to determine if an edge belongs to faces that are inward facing or outward facing?

How to determine if an edge belongs to faces that are inward facing or outward facing?

gerrardhickson
Collaborator Collaborator
1,621 Views
18 Replies
Message 1 of 19

How to determine if an edge belongs to faces that are inward facing or outward facing?

gerrardhickson
Collaborator
Collaborator

In the example below, I have a part with two pairs of faces - one pair inward facing (blue) and one pair outward facing (red). I'm looking for the edge that belongs to the two inward facing pairs (the blue line). Using VBA, I have access to the faces via edge.faces and therefore I can access the normal vector for all faces. However, I'm not sure how to determine which pair correspond to the internal face. If I measure the angle between either pair of normal vectors I get the same result since Inventor always returns the smallest angle between two vectors.

 

gerrardhickson_0-1694675958249.png

 

Any suggestions?

 

0 Likes
Accepted solutions (2)
1,622 Views
18 Replies
Replies (18)
Message 2 of 19

WCrihfield
Mentor
Mentor

Hi @gerrardhickson.  That's a seemingly simple inquiry, but a tough situation.  Have you considered assigning names to the faces, edges, or vertices?  That would make it much simpler for you to find that specific edge by code.  In the Part environment, you can simply select the Face, Edge, or Vertex, then right mouse button click, and choose Assign Name from the right click menu.  It will show a small dialog for you to type in a name.  Then there are a few ways to retrieve the entities that are named that way by code.  The easiest 2 ways are specific to iLogic, not VBA, but there is a way to do it by VBA too, if you decide to go that route.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 19

gerrardhickson
Collaborator
Collaborator

@WCrihfield, the issue isn't how to get the edge, the issue is how do I tell if it belongs to the internal or external surface?

 

 

0 Likes
Message 4 of 19

Andrii_Humeniuk
Advisor
Advisor

Hi @gerrardhickson . I know you asked for VBA code, but I hope this iLogic solution will work for you. It will only work if the thickness of your part does not change between the top and side planes.

 

Dim oInvApp As Inventor.Application = ThisApplication
Dim oDoc As PartDocument = oInvApp.ActiveDocument
Dim oMT As MeasureTools = oInvApp.MeasureTools
Dim oBody As SurfaceBody = oDoc.ComponentDefinition.SurfaceBodies(1)
Dim dArreaList As New List (Of Double)
For i As Integer = 1 To oBody.Faces.Count
	dArreaList.Add(oBody.Faces(i).Evaluator.Area)
Next
dArreaList.Sort()
Dim oFaceOutMax, oFaceInMax As Face
Dim oEdgeOut, oEdgeIn As Edge
For i As Integer = 1 To oBody.Faces.Count
	If oBody.Faces(i).Evaluator.Area = dArreaList(dArreaList.Count - 1) Then
		oFaceOutMax = oBody.Faces(i)
	Else If oBody.Faces(i).Evaluator.Area = dArreaList(dArreaList.Count - 2) Then
		oFaceInMax = oBody.Faces(i)
	End If
Next
Dim dThick As Double = oMT.GetMinimumDistance(oFaceOutMax, oFaceInMax)
For iE1 As Integer = 1 To oFaceOutMax.Edges.Count
	For iE2 As Integer = 1 To oFaceInMax.Edges.Count
		For iF1 As Integer = 1 To oFaceOutMax.Edges(iE1).Faces.Count
			If oFaceOutMax.Edges(iE1).Faces(iF1) Is oFaceOutMax Then Continue For
			For iF2 As Integer = 1 To oFaceInMax.Edges(iE2).Faces.Count
				If oFaceInMax.Edges(iE2).Faces(iF2) Is oFaceInMax Then Continue For
				If oFaceOutMax.Edges(iE1).Faces(iF1) Is oFaceInMax.Edges(iE2).Faces(iF2) Then Continue For
				If EqualWithinTolerance(oMT.GetMinimumDistance(oFaceOutMax.Edges(iE1).Faces(iF1),
										oFaceInMax.Edges(iE2).Faces(iF2)), dThick, 0.001) Then
					oEdgeOut = oFaceOutMax.Edges(iE1) : oEdgeIn = oFaceInMax.Edges(iE2)
					GoTo SkipSearch
				End If				
			Next iF2
		Next iF1
	Next iE2	
Next iE1
SkipSearch :
oDoc.SelectSet.Select(oEdgeOut) 'Outer edge
oDoc.SelectSet.Select(oEdgeIn) 'Inner edge

 

 

 

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

Message 5 of 19

WCrihfield
Mentor
Mentor

If the two Faces that the Edge is associated with had been assigned names, you could check those names to see if they are the correct ones or not.  The 'internal' vs 'external' seems to not be the correct terminology here, because it is also possible for those Face objects to actually be 'pointing' inwards, towards the inside of the solid body, instead of outward away from the solid body.  So technically speaking, all the faces shown in the image could be 'external', depending on if their Normal is 'reversed' (Face.IsParamReversed).  That condition sometimes happens when mirroring bodies, but can be a bit unpredictable.  Otherwise, you may have to use the end point of the edge geometry, then get the position of a point away from that point, along each face, then fire a ray in the direction of each face's Normal, and see if they intersect.  That idea may work for rectangular geometry and flat faces, but may not work in other scenarios.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 19

gerrardhickson
Collaborator
Collaborator

I like the suggestion of finding intersection points, but I think I could use the normal vector. If the intersection point is in the direction of the vectors, then it's inwards facing, otherwise it's outwards facing.

0 Likes
Message 7 of 19

gerrardhickson
Collaborator
Collaborator

Could you explain the logic here? It's not clear to me from reading the code.

0 Likes
Message 8 of 19

Andrii_Humeniuk
Advisor
Advisor

The steps are marked in the code below:

  • Step 1: Getting areas and sorting all faces;
  • Step 2: Finding the face with the largest area and the face with the second largest area. Getting the minimum distance between them.
  • Step 3: Reading all edges of the outer face;
  • Step 4: Reading all edges of the inner face;
  • Step 5: Reading all faces of the current edge (Edges(iE1));
  • Step 6: Reading all faces of the current edge (Edges(iE2));
  • Step 7: Distance comparison between current faces and dThick;
Dim oInvApp As Inventor.Application = ThisApplication
Dim oDoc As PartDocument = oInvApp.ActiveDocument
Dim oMT As MeasureTools = oInvApp.MeasureTools
Dim oBody As SurfaceBody = oDoc.ComponentDefinition.SurfaceBodies(1)
'[ Step 1
Dim dArreaList As New List(Of Double)
For i As Integer = 1 To oBody.Faces.Count
	dArreaList.Add(oBody.Faces(i).Evaluator.Area)
Next
dArreaList.Sort()']
Dim oFaceOutMax, oFaceInMax As Face
Dim oEdgeOut, oEdgeIn As Edge
'[ Step 2
For i As Integer = 1 To oBody.Faces.Count
	If oBody.Faces(i).Evaluator.Area = dArreaList(dArreaList.Count - 1) Then
		oFaceOutMax = oBody.Faces(i)
	Else If oBody.Faces(i).Evaluator.Area = dArreaList(dArreaList.Count - 2) Then
		oFaceInMax = oBody.Faces(i)
	End If
Next
Dim dThick As Double = oMT.GetMinimumDistance(oFaceOutMax, oFaceInMax)']
'[ Step 3
For iE1 As Integer = 1 To oFaceOutMax.Edges.Count
	'[ Step 4
	For iE2 As Integer = 1 To oFaceInMax.Edges.Count
		'[ Step 5
		For iF1 As Integer = 1 To oFaceOutMax.Edges(iE1).Faces.Count
			If oFaceOutMax.Edges(iE1).Faces(iF1) Is oFaceOutMax Then Continue For 'A face from the edge is not an outside face
			'[ Step 6
			For iF2 As Integer = 1 To oFaceInMax.Edges(iE2).Faces.Count
				If oFaceInMax.Edges(iE2).Faces(iF2) Is oFaceInMax Then Continue For 'A face from the edge is not an inside face
				If oFaceOutMax.Edges(iE1).Faces(iF1) Is oFaceInMax.Edges(iE2).Faces(iF2) Then Continue For 'Shared face
				'[ Step 7
				If EqualWithinTolerance(oMT.GetMinimumDistance(oFaceOutMax.Edges(iE1).Faces(iF1),
										oFaceInMax.Edges(iE2).Faces(iF2)), dThick, 0.001) Then
					oEdgeOut = oFaceOutMax.Edges(iE1) : oEdgeIn = oFaceInMax.Edges(iE2)
					GoTo SkipSearch
				End If']			
			Next iF2']
		Next iF1']
	Next iE2']
Next iE1']
SkipSearch :
oDoc.SelectSet.Select(oEdgeOut) 'Outer edge
oDoc.SelectSet.Select(oEdgeIn) 'Inner edge

If you have a Г-profile of the part, you do not need to measure the distances, but if you have a C-profile, you definitely need to measure the distances.

In any case, it is very difficult to write code that will understand all possible variations of a part.

Г profile.png

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 9 of 19

gerrardhickson
Collaborator
Collaborator

Ok, so it's assuming that the inner faces will have a smaller area than the outer faces - is that right?

In this case, it would not successfully detect the edges for a case like the image below.

gerrardhickson_0-1694755560136.png

 

0 Likes
Message 10 of 19

Andrii_Humeniuk
Advisor
Advisor

That's right, the code I wrote is situational, I relied on the screenshot in the title of the topic. In order to describe all possible variations, you need to anticipate them and describe them first in text and then in code.

For example, the solution to the problem can be the determination of all parallel faces relative to the XZ Plane and the minimum distance to the XZ Plane. Select the two planes that are on top and use the similar code that I described to find the required edges.

Andrii Humeniuk - CAD Coordinator, Autodesk Certified Instructor

LinkedIn | My free Inventor Addin | My Repositories

Did you find this reply helpful ? If so please use the Accept as Solution/Like.

EESignature

0 Likes
Message 11 of 19

gerrardhickson
Collaborator
Collaborator

The original example is simplified. The solution will need to be robust - that is, consider all possible cases, regardless of the rest of the geometry, regardless of the orientation of that geometry. Consider it a 'general solution' one that works in all cases.

 

 

Interestingly - I just thought of a crude solution. Apply a fillet to the edge. If the part volume increases, it's an internal edge. If it decreases it's an outer edge.

0 Likes
Message 12 of 19

gerrardhickson
Collaborator
Collaborator

The Fillet test has worked for now, but still hoping for an analytic method.

0 Likes
Message 13 of 19

J-Camper
Advisor
Advisor

@gerrardhickson,

 

Can you answer a few questions:

  1. How are your profiles created?
    1. Extrusion of actual profile?
    2. Extrusion of overall and cut extrusions for profile?
    3. Other?
  2. How are your "Outside" faces orientated?
    1. All Normal with X Axis? [or other Axis]
    2. Random/No consistency?
  3. In the Z profile shown, which side is "Outside"?[may be answered with above question]
    1. How is "Outside" determined in general?

 

Depending on some of these answers there may be options for finding the desired face.  Alternatively if these are parts copied and reused, then you could name your outside face and retrieve it that way.

 

More information about the parts will be helpful to think of solutions.

0 Likes
Message 14 of 19

gerrardhickson
Collaborator
Collaborator

It might be tempting to consider the part history, it's orientation or other factors in your solution, but that isn't robust. Consider only that you have 1 edge and 2 faces (with normals).

 

For what its worth, the whole model is created programmatically, it is a series of surfaces that are later thickened to form a solid. The purpose of detecting the inner edge is to apply a sheet metal feature. Initially I took a brute force approach and tried to apply a bend feature to sand edge that met a few basic criteria (longer than the 2x thickness, aligned in directions that I'm interested in etc), but that fails in some edge cases. 

 

As an interim, I'm using the fillet test which works well but it's quite slow (unsurprisingly). This one test takes about as long as all my other code.

0 Likes
Message 15 of 19

J-Camper
Advisor
Advisor

@gerrardhickson,

 

So these are sheet metal parts?  I don't use the Sheet metal side of Inventor very much in my line of work so excuse my ignorance, but can't you unfold the part, which would give bend lines around the "Inside" edges in the flat pattern representation?  That approach might lead you to a solution.

 

0 Likes
Message 16 of 19

gerrardhickson
Collaborator
Collaborator

You can only unfold a part that has uniform thickness, which means it has constant radius bends. And that's the purpose of the code - to determine where to place bend features.

 

I did some more research and found some tests that looks promising. Both use "findusingray". The first says that if the origin point is outside a solid, the number of faces it passed through will be an even number. The other uses the door product if the face normal vector and ray direction vector to determine whether the ray passes through the face from the front or back.

0 Likes
Message 17 of 19

nmunro
Collaborator
Collaborator
Accepted solution

An interesting problem. Attached is a part file with a VBA solution embedded (IV2023). The part is pretty simple in that there is just the one change in direction that is of any interest. The faces are also joined without bends to simplify the solution. The macro requires either the two "inner" or two "outer" faces be preselected before running the GetInnerOrOuterFaces macro. The common edge between the two is found, and the part is reviewed for the opposite faces and the common edge between these two faces.

 

If all are found, the two selected faces are checked to see if they are the inner or outer faces. Transient geometry is used to generate boxes that simulate an extrusion normal to each of the two selected faces (each slightly inside the boundary of the face). If the boxes intersect, the two faces must be the "inner" faces. Likewise the two boxes will not intersect if the faces are on the "outside". A message box relates the findings.

 

Although not tested, the solution should work for almost all angles and for cases where the common edge is not perpendicular to the side faces of the part. There is some checking for bad selections and geometry but no real error checking was included. I hope you might be able to use something from this as a pointer to a possible direction for your project.

 

Cheers,

Neil

 

https://c3mcad.com

        


https://c3mcad.com

Message 18 of 19

gerrardhickson
Collaborator
Collaborator

Thanks @nmunro, That's a pretty decent solution. I have only taken a cursory look over your code, but your approach makes sense. In many ways it's similar to my fillet solution except that it takes place in TransientGeometry space, so should be much faster.

EDIT: I have implemented your code in place of my fillet test, and it seemed to be working well for simple examples, but it fails with a false negative for others. I decided to adapt your code, by creating a 'unitbox' (my term) based on the midpoint of an edge - that is, take the midpoint and move it one unit in each direction to make a box. I think it was failing with face shapes that were a little more complex. I also found that I needed to move my 'boxes' away from the edge by a small distance - the 'box.isdisjointed' method seems to returns false (they are connected) if they share an edge.

0 Likes
Message 19 of 19

gerrardhickson
Collaborator
Collaborator
Accepted solution

Well, this feels silly - I just discovered the "SurfaceBodies.ConcaveEdges" edge collection. In my case, this is exactly what I want.