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
Solved! Go to Solution.
Solved by JhoelForshav. Go to Solution.
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
Sergio Daniel Suarez
Mechanical Designer
| Upwork Profile | LinkedIn
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.
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
Jhoel Forshav
Download my free Inventor Addin - Hole Projector
LinkedIn | Ideas | Contributions | Blog posts | Website
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 😁
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.