Get all faces from a component occurence

Get all faces from a component occurence

Majjek
Advocate Advocate
2,893 Views
7 Replies
Message 1 of 8

Get all faces from a component occurence

Majjek
Advocate
Advocate

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

0 Likes
Accepted solutions (1)
2,894 Views
7 Replies
Replies (7)
Message 2 of 8

Sergio.D.Suárez
Mentor
Mentor

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

0 Likes
Message 3 of 8

Majjek
Advocate
Advocate

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.

0 Likes
Message 4 of 8

JhoelForshav
Mentor
Mentor
Accepted solution

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
Advocate
Advocate

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
Not applicable

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

0 Likes
Message 7 of 8

Anonymous
Not applicable

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

0 Likes
Message 8 of 8

Majjek
Advocate
Advocate

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

 

 

0 Likes