Hi everyone, I wanted to share an iLogic rule that I use in my daily workflow.
I hope you'll find it useful! It’s designed to be very user-friendly, fast, and dynamic.
Option Explicit On
Public Class ThisRule
Private Const kMarkStyleName As String = "Mark Surface"
Private Const kTextStyleName As String = "Grawer_5mm"
'Atrybuty do oznaczania “naszego” tekstu (opcjonalne, ale przydatne)
Private Const kAttrSetName As String = "ML_GRAWER"
Private Const kAttrKey As String = "TYPE"
Private Const kAttrValue As String = "PARTNUMBER"
Sub Main()
Dim doc As PartDocument = TryCast(ThisDoc.Document, PartDocument)
If doc Is Nothing Then
MsgBox("Ta reguła działa tylko w pliku .ipt (Part).", MsgBoxStyle.Exclamation)
Return
End If
'Wysokość tekstu = 5 mm, przeliczona na jednostki bazy (cm)
Dim uom As UnitsOfMeasure = doc.UnitsOfMeasure
Dim textHeightDb As Double = uom.GetValueFromExpression("5 mm", UnitsTypeEnum.kDatabaseLengthUnits)
'Wybór punktu na płaskiej ścianie
Dim selector As New Selector(ThisApplication)
selector.Pick()
If selector.SelectedObject Is Nothing OrElse selector.ModelPosition Is Nothing Then Return
Dim face As Face = selector.SelectedObject
Dim pointOnFace As Point = selector.ModelPosition
CreateMarkFeature(doc, face, pointOnFace, kMarkStyleName, kTextStyleName, textHeightDb)
End Sub
Private Sub CreateMarkFeature(doc As PartDocument,
face As Face,
pointOnFace As Point,
markStyleName As String,
textStyleName As String,
textHeightDb As Double)
Dim def As PartComponentDefinition = doc.ComponentDefinition
'Styl tekstu (wysokość 5 mm)
Dim customTextStyle As TextStyle = GetOrCreateTextStyle(doc, textStyleName, textHeightDb)
If customTextStyle Is Nothing Then Return
'Szkic na wskazanej ścianie
Dim sketch As PlanarSketch = def.Sketches.Add(face)
Dim skPoint As Point2d = sketch.ModelToSketchSpace(pointOnFace)
'===== KLUCZOWY FRAGMENT =====
'Zamiast “suchego” Part Number wstawiamy POLE iProperty jako FormattedText.
'To pole jest dynamiczne – po zmianie iProperty Part Number tekst się aktualizuje.
Dim formattedPN As String = BuildIPropertyField_PartNumber()
Dim tb As Inventor.TextBox = sketch.TextBoxes.AddFitted(skPoint, formattedPN, customTextStyle)
'Wyrównanie
tb.HorizontalJustification = HorizontalTextAlignmentEnum.kAlignTextCenter
tb.VerticalJustification = VerticalTextAlignmentEnum.kAlignTextMiddle
'Oznacz tekst atrybutem (opcjonalne, ale pomaga w serwisie/odświeżaniu)
Try
TagTextBox(tb)
Catch
End Try
'Geometria do Mark Feature
Dim markGeometry As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection()
markGeometry.Add(tb)
Dim markFeatures As MarkFeatures = def.Features.MarkFeatures
'Mark Style
Dim markStyle As MarkStyle = Nothing
Try
markStyle = doc.MarkStyles.Item(markStyleName)
Catch
MsgBox("Brak stylu grawerowania (Mark Style): " & markStyleName, MsgBoxStyle.Critical)
Try : sketch.Delete() : Catch : End Try
Return
End Try
Dim markDef As MarkDefinition = markFeatures.CreateMarkDefinition(markGeometry, markStyle)
If (ThisApplication.SoftwareVersion.Major >= 28) Then
markDef.Direction = PartFeatureExtentDirectionEnum.kNegativeExtentDirection
End If
Try
Dim mk = markFeatures.Add(markDef)
'opcjonalnie: mk.Name = "Grawer_PN"
Catch ex As Exception
MsgBox("Nie udało się utworzyć graweru. Sprawdź czy tekst mieści się na ścianie." & vbCrLf & ex.Message,
MsgBoxStyle.Exclamation)
End Try
End Sub
'Pole iProperty = Part Number (Design Tracking Properties).
'To jest ten sam mechanizm, który Inventor wstawia przez Format Text.
Private Function BuildIPropertyField_PartNumber() As String
Return "<Property Document='model' PropertySet='Design Tracking Properties' Property='Part Number' FormatID='{32853F0F-3444-11D1-9E93-0060B03C1CA6}' PropertyID='5'>PART NUMBER</Property>"
End Function
Private Sub TagTextBox(tb As Inventor.TextBox)
Dim sets As AttributeSets = tb.AttributeSets
Dim setObj As AttributeSet
If sets.NameIsUsed(kAttrSetName) Then
setObj = sets.Item(kAttrSetName)
Else
setObj = sets.Add(kAttrSetName)
End If
If setObj.NameIsUsed(kAttrKey) Then
setObj.Item(kAttrKey).Value = kAttrValue
Else
setObj.Add(kAttrKey, ValueTypeEnum.kStringType, kAttrValue)
End If
End Sub
Private Function GetOrCreateTextStyle(doc As PartDocument, styleName As String, heightDb As Double) As TextStyle
Dim textStyles As TextStylesEnumerator = doc.TextStyles
'1) istnieje?
Try
Dim existingStyle As TextStyle = textStyles.Item(styleName)
If Math.Abs(existingStyle.FontSize - heightDb) > 0.0001 Then
existingStyle.FontSize = heightDb
End If
Return existingStyle
Catch
End Try
'2) utwórz kopię bazowego
If textStyles.Count < 1 Then
MsgBox("Błąd: w pliku brak stylów tekstu!", MsgBoxStyle.Critical)
Return Nothing
End If
Dim baseStyle As TextStyle = textStyles.Item(1)
Try
Dim newStyle As TextStyle = baseStyle.Copy(styleName)
newStyle.FontSize = heightDb
Return newStyle
Catch
Return baseStyle
End Try
End Function
End Class
'--- Selector (prawie jak u Ciebie) ---
Public Class Selector
Private WithEvents _interactEvents As InteractionEvents
Private WithEvents _selectEvents As SelectEvents
Private _stillSelecting As Boolean
Private _inventor As Inventor.Application
Public Sub New(ThisApplication As Inventor.Application)
_inventor = ThisApplication
End Sub
Public Sub Pick()
_stillSelecting = True
_interactEvents = _inventor.CommandManager.CreateInteractionEvents
_interactEvents.InteractionDisabled = False
_interactEvents.StatusBarText = "Wskaż punkt na płaskiej powierzchni."
_selectEvents = _interactEvents.SelectEvents
_selectEvents.WindowSelectEnabled = False
_interactEvents.Start()
Do While _stillSelecting
_inventor.UserInterfaceManager.DoEvents()
Loop
_interactEvents.Stop()
_inventor.CommandManager.StopActiveCommand()
End Sub
Public Property SelectedObject As Face = Nothing
Public Property ModelPosition As Point = Nothing
Private Sub oSelectEvents_OnPreSelect(ByRef PreSelectEntity As Object,
ByRef DoHighlight As Boolean,
ByRef MorePreSelectEntities As ObjectCollection,
SelectionDevice As SelectionDeviceEnum,
ModelPosition As Point,
ViewPosition As Point2d,
View As Inventor.View) Handles _selectEvents.OnPreSelect
DoHighlight = False
If TypeOf PreSelectEntity Is Face Then
Dim f As Face = CType(PreSelectEntity, Face)
If TypeOf f.Geometry Is Plane Then DoHighlight = True
End If
End Sub
Private Sub oInteractEvents_OnTerminate() Handles _interactEvents.OnTerminate
_stillSelecting = False
End Sub
Private Sub oSelectEvents_OnSelect(ByVal JustSelectedEntities As ObjectsEnumerator,
ByVal SelectionDevice As SelectionDeviceEnum,
ByVal ModelPosition As Point,
ByVal ViewPosition As Point2d,
ByVal View As Inventor.View) Handles _selectEvents.OnSelect
Dim obj As Object = JustSelectedEntities.Item(1)
Dim f As Face = TryCast(obj, Face)
If f IsNot Nothing AndAlso TypeOf f.Geometry Is Plane Then
SelectedObject = f
Me.ModelPosition = ModelPosition
End If
_stillSelecting = False
End Sub
End Class