Share

Body Imprinting and matching the results

Description

This sample is intended to demonstrate a technique of finding the matching surfaces between the original input bodies and output imprinted bodies. This relies on transient keys, which is a unique ID associated with each B-Rep entity. A transient key is only good as long as the model is not recomputed.

Code Samples

To use this sample you need to have a part with multiple bodies. Two of the bodies should be coincident and those two bodies can be selected when running the sample.
Public Sub SampleImprintMatching2()
    ' Get the active assembly document and its definition.
    Dim doc As PartDocument
    Set doc = ThisApplication.ActiveDocument
    Dim def As PartComponentDefinition
    Set def = doc.ComponentDefinition
    
    ' Have two parts selected in the assembly.
    Dim part1 As ComponentOccurrence
    Dim part2 As ComponentOccurrence
    Dim origBody1 As SurfaceBody
    Dim origBody2 As SurfaceBody
    Set origBody1 = ThisApplication.CommandManager.Pick(kPartBodyFilter, "Select body 1")
    Set origBody2 = ThisApplication.CommandManager.Pick(kPartBodyFilter, "Select body 2")
    
    ' Create alternate bodies.  Ideally this wouldn't be needed but this adds some special
    ' tags to the bodies that allow transient keys to continue to work after the ImprintBodies method is called.
    ' After this there is the original two bodies and the alternate version of each of the
    ' bodies.  The alternate may have more faces than the original, but the transient keys
    ' between the two should still match.
    Dim body1 As SurfaceBody
    Dim body2 As SurfaceBody
    Set body1 = origBody1.AlternateBody(Inventor.SurfaceGeometryFormEnum.SurfaceGeometryForm_NURBS)
    Set body2 = origBody2.AlternateBody(Inventor.SurfaceGeometryFormEnum.SurfaceGeometryForm_NURBS)

    ' Imprint the bodies.  After this call we now have three sets of bodies; the original, the alternate,
    ' and the imprinted bodies.  There should be additional faces in the imprinted bodies but the
    ' transient keys should still match for all three sets of bodies.
    Dim newBody1 As SurfaceBody
    Dim newBody2 As SurfaceBody
    Dim body1OverlapFaces As Faces
    Dim body2OverlapFaces As Faces
    Dim body1OverlapEdges As Edges
    Dim body2OverlapEdges As Edges
    Call ThisApplication.TransientBRep.ImprintBodies(body1, body2, True, newBody1, newBody2, body1OverlapFaces, body2OverlapFaces, body1OverlapEdges, body2OverlapEdges)
    
    ' The code below creates new non-parametric base features using the new imprinted bodies
    ' so that the results can be visualized.  The new bodies are created offset from the
    ' original so that they don't overlap and are more easily seen.
    '
    ' ** After this operation there will be four sets of bodies; the original, the alternate form,
    ' ** the imprinted bodies, and now the body created as a result of the feature creation.
    ' ** Because a new persisted body is created as part of the operation, new transient keys
    ' ** are assigned to the body, so the transient keys will no longer match this body.
    ' ** However, because they're essentially just copies of the imprinted bodies, the faces
    ' ** are in the same order in the two bodies so the indexes can be used to match between
    ' ** the two bodies.
        
    ' Define a matrix to use in transforming the bodies.
    Dim trans As Matrix
    Set trans = ThisApplication.TransientGeometry.CreateMatrix
    
    ' Move the first imprinted body over based on the range so it doesn't lie on the original.
    ' Moving the body is a modification of the existing body and leaves the transient keys as-is.
    ' However, it does change the face identities so comparing IUnknowns will no longer work.  Because
    ' of this I first save the indices of the overlapping faces while the faces are the same.
        Dim matchingIndexList1() As Integer
    Dim matchingIndexList2() As Integer
    ReDim matchingIndexList1(body1OverlapFaces.Count - 1)
    ReDim matchingIndexList2(body2OverlapFaces.Count - 1)
    Dim i As Integer
    For i = 1 To body1OverlapFaces.Count
        ' Find the indices of the overlapping face in the Faces collection.
        Dim j As Integer
        For j = 1 To newBody1.Faces.Count
            If body1OverlapFaces.Item(i) Is newBody1.Faces.Item(j) Then
                matchingIndexList1(i - 1) = j
                Exit For
            End If
        Next
        
        Dim body2Index As Integer
        For j = 1 To newBody2.Faces.Count
            If body2OverlapFaces.Item(i) Is newBody2.Faces.Item(j) Then
                matchingIndexList2(i - 1) = j
                Exit For
            End If
        Next
    Next

    ' Now do the transformation of the first body.
    trans.Cell(1, 4) = (body1.RangeBox.MaxPoint.X - body1.RangeBox.MinPoint.X) * 1.1
    Call ThisApplication.TransientBRep.Transform(newBody1, trans)
    
    ' Move the second imprinted body over based on the range so it doesn't lie on the original.
    trans.Cell(1, 4) = trans.Cell(1, 4) + (body1.RangeBox.MaxPoint.X - body1.RangeBox.MinPoint.X) * 1.1
    Call ThisApplication.TransientBRep.Transform(newBody2, trans)

    ' Create a new feature from the first imprinted body.
    Dim nonParaDef As NonParametricBaseFeatureDefinition
    Set nonParaDef = def.Features.NonParametricBaseFeatures.CreateDefinition
    Dim bodyColl As ObjectCollection
    Set bodyColl = ThisApplication.TransientObjects.CreateObjectCollection
    Call bodyColl.Add(newBody1)
    nonParaDef.BRepEntities = bodyColl
    nonParaDef.OutputType = kSolidOutputType
    Dim non1 As NonParametricBaseFeature
    Set non1 = def.Features.NonParametricBaseFeatures.AddByDefinition(nonParaDef)
    Dim resultBody1 As SurfaceBody
    Set resultBody1 = non1.SurfaceBodies.Item(1)

    ' Create a new feature from the second imprinted body.
    Set nonParaDef = def.Features.NonParametricBaseFeatures.CreateDefinition
    Set bodyColl = ThisApplication.TransientObjects.CreateObjectCollection
    Call bodyColl.Add(newBody2)
    nonParaDef.BRepEntities = bodyColl
    nonParaDef.OutputType = kSolidOutputType
    Dim non2 As NonParametricBaseFeature
    Set non2 = def.Features.NonParametricBaseFeatures.AddByDefinition(nonParaDef)
    Dim resultBody2 As SurfaceBody
    Set resultBody2 = non2.SurfaceBodies.Item(1)
    
    ' Fit the view to see the result.
    Dim cam As Camera
    Set cam = ThisApplication.ActiveView.Camera
    cam.Fit
    cam.Apply

    ' Create a highlight set used to see the matches.
    Dim hs As HighlightSet
    Set hs = doc.CreateHighlightSet
    
    ' Show the matches between the first imprint body and the original body.
    For i = 1 To newBody1.Faces.Count
        ' The face in the feature has a different transient key so get the
        ' face as the same index and assume it's the same.
        Dim newFace As Face
        Set newFace = resultBody1.Faces.Item(i)
        
        hs.AddItem newFace
        
        ' Get the corresponding face in the original body using the transient key from
        ' the imprinted face at the current index in the face collection.
        Dim otherFace As Face
        Set otherFace = origBody1.BindTransientKeyToObject(newBody1.Faces.Item(i).TransientKey)
        
        hs.AddItem otherFace
        
        MsgBox "Match"
        hs.Clear
    Next

    ' Show the matches between the second imprint body and the original body.
    For i = 1 To newBody2.Faces.Count
        ' The face in the feature has a different transient key so get the
        ' face as the same index and assume it's the same.
        Set newFace = resultBody2.Faces.Item(i)
        
        hs.AddItem newFace
        
        ' Get the corresponding face in the original body using the transient key from
        ' the imprinted face at the current index in the face collection.
        Set otherFace = origBody2.BindTransientKeyToObject(newBody2.Faces.Item(i).TransientKey)
        
        hs.AddItem otherFace
        
        MsgBox "Match"
        hs.Clear
    Next
    
    ' Highlight just the overlapping faces.
    ' The collection of overlapping faces returned by the ImprintBodies method correspond to
    ' the bodies returned by the ImprintBodies function.  This means the transient keys on the
    ' overlapping bodies will match all of the bodies except for the bodies created by the
    ' non-parametric base features.  The face index was save previously and will be used here.
    For i = 1 To body1OverlapFaces.Count
        Dim overlapFace1 As Face
        Dim overlapFace2 As Face
        Set overlapFace1 = resultBody1.Faces.Item(matchingIndexList1(i - 1))
        Set overlapFace2 = resultBody2.Faces.Item(matchingIndexList2(i - 1))
        
        hs.AddItem overlapFace1
        hs.AddItem overlapFace2
        
        MsgBox "Overlap Match"
        hs.Clear
    Next
End Sub


Was this information helpful?