Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Get all faces from a component occurence

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
Majjek
2035 Views, 7 Replies

Get all faces from a component occurence

Hi,

 

I'm busy with a script (VBA) that returns overlapping faces in an assembly.

I feel like I'm at 90%, but need the last details.

 

I pick a face using the Pick command. Then I select a component (also via Pick) and want to check all the faces from that componentoccurrence to the selected face if it has a match.

If I do this between parts, then I create a proxy body from the surface body via CreateGeometryProxy.

Then I can loop through all the faces in that proxy and compare them, this works.

 

But when I want to compare an assembly, I don't have immediate access to all the faces (at least I don't know how, that's the problem).

Should I run down to all components in that assembly and their bodies as well?

Or is there a way, to maybe create a transient body of the entire componentoccurence and then look at all those faces?

 

Thanks in advance

7 REPLIES 7
Message 2 of 8
Sergio.D.Suárez
in reply to: Majjek

Hi, Here I show you an ilogic code, from an assembly you select a face. Then you will access the original document of that face. Then you should try to perform some action on the faces of this document by comparing it with your initial chosen face.
I hope this can give you some idea so you can solve your problem. Regards

 

Dim oFaceA As Face = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Select face") 

Dim oSolid As SurfaceBody= oFaceA.nativeobject.Parent

Dim oDoc As Document =oSolid.Parent.Document

MessageBox.Show(oDoc.displayname)


For Each oSurf As SurfaceBody In oDoc.componentdefinition.surfacebodies
	For Each oFaceB In oSurf.Faces
		ThisApplication.CommandManager.DoSelect(oFaceB)
	Next
Next

 


Please accept as solution and give likes if applicable.

I am attaching my Upwork profile for specific queries.

Sergio Daniel Suarez
Mechanical Designer

| Upwork Profile | LinkedIn

Message 3 of 8
Majjek
in reply to: Sergio.D.Suárez

Hi Sergio,

 

Thanks for your response.

What I want is to compare a face from one component to all faces from another assembly.

In your example, you go through the faces of the parent object itself.

 

The surfacebody collection is also empty for a normal assembly, because it only consists of other components.

Message 4 of 8
JhoelForshav
in reply to: Majjek

Hi @Majjek

Try this code to get all the faceproxies from a sub-assembly:

Sub Main()
Dim oAsm As AssemblyDocument = ThisDoc.Document
Dim oComponent As ComponentOccurrence = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "select subassembly")
If oComponent.Definition.Type = ObjectTypeEnum.kAssemblyComponentDefinitionObject
	Dim oDef As AssemblyComponentDefinition = oComponent.Definition
	For Each oFaceProx In GetProxies(oComponent)
		ThisApplication.CommandManager.DoSelect(oFaceProx)
	Next
End If
End Sub

Function GetProxies(oComponent As ComponentOccurrence) As ObjectCollection
	Dim oProxCol As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oDef As AssemblyComponentDefinition = oComponent.Definition
	For Each oComp As ComponentOccurrence In oDef.Occurrences
		If oComp.Definition.Type = ObjectTypeEnum.kAssemblyComponentDefinitionObject
			For Each oProx1 As FaceProxy In GetProxies(oComp)
				Dim oProx2 As FaceProxy
				Call oComponent.CreateGeometryProxy(oProx1, oProx2)
				oProxCol.Add(oProx2)
			Next
		Else
			Dim oCompDef As PartComponentDefinition = oComp.Definition
			For Each oBod As SurfaceBody In oCompDef.SurfaceBodies
				For Each oFace As Face In oBod.Faces
				Dim oProx1 As FaceProxy
				Dim oProx2 As FaceProxy
				Call oComp.CreateGeometryProxy(oFace, oProx1)
				Call oComponent.CreateGeometryProxy(oProx1, oProx2)
				oProxCol.Add(oProx2)
				Next
			Next
		End If
	Next
	Return oProxCol
End Function

 

Message 5 of 8
Majjek
in reply to: JhoelForshav

Hi Jhoel,

 

Thanks for your answer!

 

I was already working on something similar, but I got stuck when having another assembly in the selected assembly.

The solution was in the recursive part of your function, where you first create a proxy in that reference, and then create a proxy of that proxy in the upper assembly.

 

My function only grabbed all surfacebodies recursively. And in my main sub, I would then first filter out the surfacebody that I needed.

Then I would create a proxy, but if that body is in a deeper sub, it's not possible to create the proxy.

This solves it!

 

Case closed 😁

Message 6 of 8
Anonymous
in reply to: Majjek

Can you share the code where you are checking face overlap. I am looking for the solution for this long…

Message 7 of 8
Anonymous
in reply to: Majjek

@Majjek  please share the final code where you check faces and also are you checking for overlapping faces too?

Message 8 of 8
Majjek
in reply to: Anonymous

Hi,

 

The solution I have consists of 2 functions:

- Try to match the surface area

- Try to match the face bounding box

Of course this is not a 100% match, for example if you have a square face with 1 hole in it, if the outer shape of the square is the same, but the hole is in a different location, it will still match it.

But for my case, this is not an issue.

    Function MatchFace(oFace1 As Face, oFace2 As Face) As Boolean

        Dim bAreaMatch As Boolean
        Dim bRangeBoxMatch As Boolean

        If Math.Round(oFace1.Evaluator.Area, 3) = Math.Round(oFace2.Evaluator.Area, 3) Then
            bAreaMatch = True
        Else
            bAreaMatch = False
        End If

        bRangeBoxMatch = MatchRangeBox(oFace1.Evaluator.RangeBox, oFace2.Evaluator.RangeBox)

        If bAreaMatch = True And bRangeBoxMatch = True Then
            MatchFace = True
        Else
            MatchFace = False
        End If

    End Function
    Function MatchRangeBox(oBox1 As Box, oBox2 As Box) As Boolean

        Dim oMax1 As Point = InvApp.TransientGeometry.CreatePoint
        oMax1 = oBox1.MaxPoint

        Dim oMax2 As Point = InvApp.TransientGeometry.CreatePoint
        oMax2 = oBox2.MaxPoint

        Dim oMin1 As Point = InvApp.TransientGeometry.CreatePoint
        oMin1 = oBox1.MinPoint

        Dim oMin2 As Point = InvApp.TransientGeometry.CreatePoint
        oMin2 = oBox2.MinPoint

        If Math.Round(oMax1.X, 3) = Math.Round(oMax2.X, 3) And Math.Round(oMax1.Y, 3) = Math.Round(oMax2.Y, 3) And Math.Round(oMax1.Z, 3) = Math.Round(oMax2.Z, 3) And Math.Round(oMin1.X, 3) = Math.Round(oMin2.X, 3) And Math.Round(oMin1.Y, 3) = Math.Round(oMin2.Y, 3) And Math.Round(oMin1.Z, 3) = Math.Round(oMin2.Z, 3) Then
            MatchRangeBox = True
        Else
            MatchRangeBox = False
        End If

    End Function

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report