You're welcome! 🙂 I hope we can all get some clarity on this topic. As I mentioned before, I tried figuring out how to use Reference Keys for this purpose but nothing I tried worked.
Good point about the ZIP-file, I only put it there due to the 3 file limit of the forum. If you wanna give the code a try I included it below:
Sub Main()
'Set references to this assembly
Dim asmDoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim asmDef As ComponentDefinition = asmDoc.ComponentDefinition
'Set references to the "blank" component
Dim blankComponent As ComponentOccurrence = asmDef.Occurrences.Item(1)
Dim blankCompDef As ComponentDefinition = blankComponent.Definition
Dim blankCompDoc As PartDocument = blankCompDef.Document
Dim SMCD As SheetMetalComponentDefinition = blankCompDoc.ComponentDefinition
Dim thkParam As Parameter = SMCD.Thickness
Dim toolCollection As New Collection
toolCollection.Add(asmDef.Occurrences.Item(2))
toolCollection.Add(asmDef.Occurrences.Item(3))
toolCollection.Add(asmDef.Occurrences.Item(4))
'Print out all the AssociativeIDs of all the faces
Call GetAssocIDs(blankCompDef.SurfaceBodies.Item(1), "blankComponent")
'Proxy needed to resolve some bug mentioned somewhere...
Dim proxy As Object = Nothing
Call blankComponent.CreateGeometryProxy(blankCompDef.SurfaceBodies.Item(1), proxy)
Dim bodyProxy As SurfaceBodyProxy = TryCast(proxy, SurfaceBodyProxy)
'Create a Transient BRep copy of the "blank" component
Dim blankBody As SurfaceBody = ThisApplication.TransientBRep.Copy(bodyProxy)
'Marking Face: Find the face index where named attribute exists
Dim markingFaceIndex As Integer = GetAttributeFaceIndex(blankCompDef.SurfaceBodies.Item(1), "MarkingFace")
'Set associativeID
Dim markingFaceID As Integer = -1
blankBody.Faces.Item(markingFaceIndex).AssociativeID = markingFaceID
'A-side Face: Find the face index defined by the A-side feature
Dim ASideFaceIndex As Integer = GetASideFaceIndex(blankCompDef.SurfaceBodies.Item(1), blankCompDoc)
'Set associativeID
Dim ASideFaceID As Integer = -2
blankBody.Faces.Item(ASideFaceIndex).AssociativeID = ASideFaceID
'Open and highlight the face(s) found in the blankComponent
ThisApplication.Documents.Open(blankCompDoc.FullDocumentName, True)
Dim HS As HighlightSet = blankCompDoc.CreateHighlightSet
HS.AddItem(blankCompDef.SurfaceBodies.Item(1).Faces.Item(markingFaceIndex))
HS.AddItem(blankCompDef.SurfaceBodies.Item(1).Faces.Item(ASideFaceIndex))
'Print out all the AssociateIDs of all the faces
Call GetAssocIDs(blankBody, "blankBody")
'Create matrix to hold the coordinates of the "blank" component relative to its position in the assembly
Dim trans As Matrix = blankComponent.Transformation
trans.Invert()
'Process all "tool" occurrences and perform boolean operations
For Each toolOcc As ComponentOccurrence In toolCollection
Dim toolDef As ComponentDefinition = toolOcc.Definition
'Proxy needed to resolve bug...
proxy = Nothing
Call toolOcc.CreateGeometryProxy(toolDef.SurfaceBodies.Item(1), proxy)
Dim toolBodyProxy As SurfaceBodyProxy = TryCast(proxy, SurfaceBodyProxy)
Dim toolBody As SurfaceBody = ThisApplication.TransientBRep.Copy(toolBodyProxy)
'Transform the bodies relative to the "blank" component
Call ThisApplication.TransientBRep.Transform(toolBody, toolBodyProxy.ContainingOccurrence.Transformation)
Call ThisApplication.TransientBRep.Transform(toolBody, trans)
'Subtract the geometry of the "tool" bodies from the "blank" body
ThisApplication.TransientBRep.DoBoolean(blankBody, toolBody, BooleanTypeEnum.kBooleanTypeDifference)
Next
'Print out all the AssociateIDs of all the faces
Call GetAssocIDs(blankBody, "blankBody after processing")
Dim partDoc As PartDocument = ThisApplication.Documents.Add(
DocumentTypeEnum.kPartDocumentObject, ThisApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kPartDocumentObject), CreateVisible:=True) 'Bugs out when set to False running outside of iLogic
Dim partDef As PartComponentDefinition = partDoc.ComponentDefinition
'Create a base feature definition using the inputs below
Dim nonPrmFeatures As NonParametricBaseFeatures
nonPrmFeatures = partDef.Features.NonParametricBaseFeatures
Dim featureDef As NonParametricBaseFeatureDefinition
featureDef = nonPrmFeatures.CreateDefinition
Dim transObjs As TransientObjects = ThisApplication.TransientObjects
Dim col As ObjectCollection = transObjs.CreateObjectCollection
col.Add(blankBody)
'Create an non-associative surface body
featureDef.BRepEntities = col
featureDef.OutputType = BaseFeatureOutputTypeEnum.kSolidOutputType
featureDef.IsAssociative = False
'Add the resulting body
Dim baseFeature As NonParametricBaseFeature
'baseFeature = partDef.Features.NonParametricBaseFeatures.Add(blankBody)
baseFeature = nonPrmFeatures.AddByDefinition(featureDef)
Dim partBody As SurfaceBody = partDef.SurfaceBodies.Item(1)
'Print out all the AssociateIDs of all the faces
Call GetAssocIDs(partBody, "New Part")
'Set camera to home view
ThisApplication.CommandManager.ControlDefinitions.Item("AppViewCubeHomeCmd").Execute()
'Set face color to show the correct face was located
Call SetFaceColor(partDoc, partDef.SurfaceBodies.Item(1), markingFaceID)
Call SetFaceColor(partDoc, partDef.SurfaceBodies.Item(1), ASideFaceID)
'Convert to sheetmetal: Set thickness value, A-side definition and create Flat Pattern
Call ProcessSheetMetal(partDoc, thkParam, partBody, ASideFaceID)
'Copy sketch from blank component, paste to new document and add marking feature
Call AddMarkingSketch(blankCompDef, partDoc, partDef, partBody, markingFaceID)
End Sub
Sub AddMarkingSketch(blankCompDef As ComponentDefinition, partDoc As PartDocument, partDef As PartComponentDefinition, body As SurfaceBody, i As Integer)
'Find the sketch to copy
Dim oSketch As PlanarSketch = Nothing
For Each oSketch In blankCompDef.Sketches
If oSketch.Name = "MarkingSketch" Then
Exit For
End If
oSketch = Nothing
Next
If oSketch Is Nothing Then
MsgBox("Sketch not found. Exiting rule")
Return
End If
'Find the "anchor point" for the TextBox
Dim WP As WorkPoint = Nothing
For Each WP In blankCompDef.WorkPoints
If WP.Name = "TextBoxAnchor" Then
Dim TG As TransientGeometry = ThisApplication.TransientGeometry
Dim TGpoint As Point = TG.CreatePoint(WP.Point.X, WP.Point.Y, WP.Point.Z)
'Add the "anchor point" to the new part as a fixed Work Point feature
WP = partDef.WorkPoints.AddFixed(TGpoint)
Exit For
End If
WP = Nothing
Next
If WP Is Nothing Then
MsgBox("Work Point not found. Exiting rule")
Return
End If
'Find the face to copy the sketch to
For Each oFace As Face In body.Faces
If oFace.AssociativeID = i Then
'Add sketch to face
Dim newSketch As PlanarSketch = partDef.Sketches.Add(oFace)
'Copy contents from source sketch
oSketch.CopyContentsTo(newSketch)
'Replace text in TextBox
newSketch.TextBoxes.Item(1).Text = "some other text"
Dim SP As SketchPoint
For Each SP In newSketch.SketchPoints
'Find the "Center Point" attached to the TextBox frame
If SP.HoleCenter = True Then
'Constrain the TextBox to the "anchor point"
Dim anchorPoint As SketchPoint = newSketch.AddByProjectingEntity(WP)
newSketch.GeometricConstraints.AddCoincident(SP, anchorPoint)
Exit For
End If
Next
Dim sketchObjects As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
'Get all entities in the sketch
For Each sketchText As Inventor.TextBox In newSketch.TextBoxes
sketchObjects.Add(sketchText)
Next
Dim oMarkFeatures As MarkFeatures = partDef.Features.MarkFeatures
'Get mark style
Dim oMarkStyle As MarkStyle = partDoc.MarkStyles.Item(1)
'Create mark definition
Dim oMarkDef As MarkDefinition = oMarkFeatures.CreateMarkDefinition(sketchObjects, oMarkStyle)
'Create a mark feature
Dim oMarkFeature As MarkFeature = oMarkFeatures.Add(oMarkDef)
Exit For
End If
Next
End Sub
Sub ProcessSheetMetal(partDoc As PartDocument, thkParam As Parameter, partBody As SurfaceBody, ASideFaceID As Integer)
'Make sure the new file is sheetmetal
If Not TypeOf partDoc.ComponentDefinition Is SheetMetalComponentDefinition Then
'Convert to sheetmetal
Try
partDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}"
Catch ex As Exception
MsgBox("Failed converting new file to Sheet Metal")
Return
End Try
End If
Dim SMCD As SheetMetalComponentDefinition = partDoc.ComponentDefinition
'Unlock SheetMetalStyle (untick checkbox "Use Thickness from Rule" to allow editing Thickness parameter)
SMCD.UseSheetMetalStyleThickness = False
'Set Thickness from "blank" component
SMCD.Thickness.Value = thkParam.Value
'Loop thru faces in the new part document looking for a match
For Each oFace As Face In partBody.Faces
If oFace.AssociativeID = ASideFaceID Then
'Add the A-side definition to the new part document
SMCD.ASideDefinitions.Add(oFace)
Exit For
End If
Next
'Create flat pattern
SMCD.Unfold()
SMCD.FlatPattern.ExitEdit()
End Sub
Sub GetAssocIDs(body As SurfaceBody, component As String)
Dim i As Integer = 1
For Each face As Face In body.Faces
Logger.Info(component & ": Index = " & i & " -> ID = " & Face.AssociativeID)
i += 1
Next
End Sub
Sub SetFaceColor(doc As PartDocument, body As SurfaceBody, i As Integer)
doc.Activate()
Dim style As RenderStyle = doc.RenderStyles("Green")
For Each face As Face In body.Faces
If Face.AssociativeID = i Then
Call Face.SetRenderStyle(StyleSourceTypeEnum.kOverrideRenderStyle, style)
End If
Next
End Sub
Function GetASideFaceIndex(body As SurfaceBody, doc As PartDocument) As Integer
Dim SMCD As SheetMetalComponentDefinition = doc.ComponentDefinition
Dim i As Integer = 1
For Each face As Face In body.Faces
If Face.TransientKey = SMCD.ASideFace.TransientKey Then
GetASideFaceIndex = i
Return GetASideFaceIndex
End If
i += 1
Next
Return Nothing
End Function
Function GetAttributeFaceIndex(body As SurfaceBody, name As String) As Integer
Dim i As Integer = 1
For Each face As Face In body.Faces
Dim AttSets As AttributeSets = Face.AttributeSets
If AttSets.NameIsUsed("iLogicEntityNameSet") Then
Dim AttSet As AttributeSet = AttSets.Item("iLogicEntityNameSet")
For Each Att As Inventor.Attribute In AttSet
If Att.Value() = name Then
GetAttributeFaceIndex = i
Return GetAttributeFaceIndex
End If
Next
End If
i += 1
Next
Return Nothing
End Function
Best,
Fredrik