Place a Mark on a planar face where clicked - iLogic

Place a Mark on a planar face where clicked - iLogic

Rich-T
Advocate Advocate
1,589 Views
5 Replies
Message 1 of 6

Place a Mark on a planar face where clicked - iLogic

Rich-T
Advocate
Advocate

Hi,

I would like to place a mark on a planar face which contains the part number iprop for laser etching.

Text height to be  5mm.

 

The workflow I'd like is - run the rule, select a face, and place the mark where clicked on the selected face.

 

I've got a bit of code from this post by Xiaodong Liang

and this enhancement of the code

but I can't seem to make the leap to get the workflow I'm after. 

 

Any help would be appreciated.

0 Likes
1,590 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @Rich-T.  That is a relatively complex task to achieve by one iLogic rule.

 

The task of obtaining the location where you click your mouse, by itself, requires a whole additional large block of code that starts a very specific user interactions mode be started by the code at a certain point, then makes it wait while it monitors for specific actions to happen in the user interface area, then automatically reacts to a very specific action in a way that can capture that location.  And even then, model space is 3D, while the mouse actions are relatively 2D, so there may be some projection involved.

 

I did create a rather large iLogic rule for this task, but it just attempts to center the TextBox at the center of the planar face you select.  There are a lot of things that can be changed or personalized about this code routine, so you would have to review it carefully before trying it out, to see if changes may be needed to suit your specific situation.  For instance:

  • parts come in all shapes and sizes
  • part faces can be pointing in any direction (may not necessarily be aligned with the UCS axes)
  • TextBox can potentially be oriented in different directions
  • Font, FontSize, Bold, Italic, UnderLine, Strikethrough options are available for edit by the custom Function
  • There is a whole scrolling list of possible 'SHXfont' choices for the initial 'convert text to geometry' step
    • It is using one simply named "txt" right now
  • There is also an optional secondary step to the 'convert geometry to text' step, where you can specify if it should use a 'big font', and specify which one of those available ones to use for it.
    • I did not include this second step in this code example, but it would be added into Line 49 as additional inputs.
  • There are 2 MarkStyle objects that come installed with Inventor.  Each one is for a different functionality (surface or through), and each one has its own settings other than that.
    • If this is not set to the one you want, or you have a custom one, then you will have to edit that part of the code to find that other MarkStyle object, then, if it is a different type, you may have to change the other related options within the MarkDefinition below.  (I left a couple lines commented out in that area.)

Anyways, the code is in the attached text file, because it is pretty long.  As mentioned earlier, getting the location of your mouse click would mean getting rid of the 'Pick' method used in Line 2, then including a whole other custom block of code that you can call to run there, which will handle your face selection and/or the text location specification.  There is an example or few here on this forum for that task by itself.  Those types of large, special functionality blocks of code are usually stored as a separate rule, referenced from an external resource, or something like that, instead of all included in the same rule, for efficiency and reuse by other tasks later.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 6

Rich-T
Advocate
Advocate

Thanks Wesley, given your comments about mouse click events I've changed tack and have the code below, which asks for an offset position instead

Ideally I'd like it to offer 3 options for text height (3.5/5/10mm) and to rename the mark feature in the browser and wrap it up nicely in a transaction so it can be undone easily.

 

        Dim oAssDoc As Document
        Dim oAssDef As PartComponentDefinition
        Dim oFace As Face
        Dim oSketch As Sketch
        Dim oEdgeLoop As EdgeLoop
        Dim oMinPt As Point
        Dim oMaxPt As Point
        Dim insPoint As Point
        Dim oTextPt As Point2d
        Dim oSketchText As Inventor.TextBox
        Dim oPartNum As String
        Dim myX As Double
        Dim myY As Double
        Dim newX As Double
        Dim newY As Double

        oAssDoc = ThisApplication.ActiveDocument
        oAssDef = oAssDoc.ComponentDefinition


        ' Pick a planar face
        oFace = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllPlanarEntities, "Select the face for a part number mark")



        ' Make sure it is a planar face
        If oFace.SurfaceType = SurfaceTypeEnum.kPlaneSurface Then
            ' Add a sketch
            oSketch = oAssDef.Sketches.Add(oFace)

            ' Trying to choose an appropriate point
            ' Assume this planar face has one edge loop only
            oEdgeLoop = oFace.EdgeLoops(1)
            oMinPt = oEdgeLoop.RangeBox.MinPoint
            oMaxPt = oEdgeLoop.RangeBox.MaxPoint

            ' Ask for offset values
            myX = CDbl(InputBox("Enter X offset", "X Offset", "0"))
            myY = CDbl(InputBox("Enter Y offset", "Y Offset", "0"))

            ' Calculate new coordinates
            newX = oMinPt.X + (myX / 10)
            newY = oMinPt.Y + (myY / 10)

            ' Create insertion point
            insPoint = ThisApplication.TransientGeometry.CreatePoint(newX, newY + 0.375, oMinPt.Z)
			'0.375mm text offset - so that the text doesnt fall off the lower edge of the selected face

            ' Convert insertion point to sketch space
            oTextPt = oSketch.ModelToSketchSpace(insPoint)

            ' Add the textbox
            oPartNum = iProperties.Value("Project", "Part Number")
			'MessageBox.Show(oPartNum)

            oSketchText = oSketch.TextBoxes.AddFitted(oTextPt, oPartNum)

            ' Create a mark feature on the textbox
            Dim oSObjs As ObjectCollection
            oSObjs = ThisApplication.TransientObjects.CreateObjectCollection
            oSObjs.Add(oSketchText)

            ' Convert text to geometry
            Dim oTextSketchEntities As SketchEntitiesEnumerator
            oTextSketchEntities = oSketchText.ConvertToGeometry("txt")

            Dim oMarkGeometry As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
            For Each oSE As SketchEntity In oTextSketchEntities
                oMarkGeometry.Add(oSE)
            Next 'oSE

            Dim oMarkFeatures As MarkFeatures
            oMarkFeatures = oAssDef.Features.MarkFeatures

            Dim oMarkStyle As MarkStyle
			oMarkStyle = oAssDoc.MarkStyles.Item("Mark Surface")

            Dim oMarkDef As MarkDefinition
            oMarkDef = oMarkFeatures.CreateMarkDefinition(oMarkGeometry, oMarkStyle)

            Dim oMark As MarkFeature
            oMark = oMarkFeatures.Add(oMarkDef)

        Else
            MsgBox("Please select a planar face!")
        End If

 

 
0 Likes
Message 4 of 6

JelteDeJong
Mentor
Mentor

Maybe you want to have a look at this rule. It is a bit complex when it comes to selecting the plane/point. (Line 31 to line 109).  But the important part (and easiest part) is in the first part of the rule.

Public Class ThisRule
	Sub Main()
		Dim doc As PartDocument = ThisDoc.Document
        Dim def As PartComponentDefinition = doc.ComponentDefinition

        Dim selector As New Selector(ThisApplication)
        selector.Pick()

        Dim sketch = def.Sketches.Add(selector.SelectedObject)
        Dim modelPoint As Point2d = sketch.ModelToSketchSpace(selector.ModelPosition)


        Dim partNumber = iProperties.Value("Project", "Part Number")
        Dim sketchText = sketch.TextBoxes.AddFitted(modelPoint, partNumber)

        Dim textSketchEntities As SketchEntitiesEnumerator = sketchText.ConvertToGeometry("txt")

        Dim markGeometry As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
        For Each oSE As SketchEntity In textSketchEntities
            markGeometry.Add(oSE)
        Next

        Dim markFeatures As MarkFeatures = def.Features.MarkFeatures
        Dim markStyle As MarkStyle = doc.MarkStyles.Item("Mark Surface")
        Dim markDef As MarkDefinition = markFeatures.CreateMarkDefinition(markGeometry, markStyle)
        markDef.Direction = PartFeatureExtentDirectionEnum.kNegativeExtentDirection
        markFeatures.Add(markDef)

    End Sub
End Class
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 = "Select a LinearGeneralDimension."
        _interactEvents.SetCursor(CursorTypeEnum.kCursorBuiltInLineCursor)

        _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
            If TypeOf PreSelectEntity.Geometry Is Plane Then
                DoHighlight = True
            End If
        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

        SelectedObject = JustSelectedEntities.Item(1)

        If TypeOf SelectedObject Is Face Then
            If TypeOf SelectedObject.Geometry Is Plane Then
                Me.SelectedObject = SelectedObject
                Me.ModelPosition = ModelPosition
            End If
        End If

        _stillSelecting = False
    End Sub

End Class

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

0 Likes
Message 5 of 6

Rich-T
Advocate
Advocate

Thanks Jelte that works a treat. I've made a few edits as seen below.

It works but there's some weirdness in the model browser with phantom-like features if you repeat a few times.

I'm not sure about how i've renamed the mark feature - i want it work so that if you run the rule again on a different face it still does the business but haven't tested it yet.

 

I'd be grateful if you spot any other improvements. 

 

 

Public Class ThisRule
Sub Main()
Dim doc As PartDocument = ThisDoc.Document
        Dim def As PartComponentDefinition = doc.ComponentDefinition
 
Dim m_inventorApplication As Inventor.Application = ThisApplication
 
Dim oTransMgr As TransactionManager
oTransMgr = m_inventorApplication.TransactionManager
Dim oTrans As Transaction = oTransMgr.StartTransaction(doc,"Part Number Mark Feature")
 
 
        Dim selector As New Selector(ThisApplication)
        selector.Pick()
 
        Dim sketch = def.Sketches.Add(selector.SelectedObject)
        Dim modelPoint As Point2d = sketch.ModelToSketchSpace(selector.ModelPosition)
 
Dim oTextSize As String
 
'ask for text height
Dim oTS As String
oTS = InputBox("Select from 3.5 / 5.0 / 10.0", "Select Text Height - iLogic", "10.00")
 
'massage user input to suit text styles 
Select Case oTS
Case Is <5.00
oTextSize = "Arial 3.50mm"
Case Is =5.00
oTextSize = "Arial 5.00mm"
Case Is >5.00
oTextSize = "Arial 10.00mm"
End Select
 
Dim partNumber = iProperties.Value("Project", "Part Number")
        Dim sketchText = sketch.TextBoxes.AddFitted(modelPoint, partNumber, oTextSize)
 
        Dim textSketchEntities As SketchEntitiesEnumerator = sketchText.ConvertToGeometry("txt")
 
        Dim markGeometry As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
        For Each oSE As SketchEntity In textSketchEntities
            markGeometry.Add(oSE)
        Next
 
        Dim markFeatures As MarkFeatures = def.Features.MarkFeatures
        Dim markStyle As MarkStyle = doc.MarkStyles.Item("Mark Surface")
        Dim markDef As MarkDefinition = markFeatures.CreateMarkDefinition(markGeometry, markStyle)
        markDef.Direction = PartFeatureExtentDirectionEnum.kNegativeExtentDirection
        markFeatures.Add(markDef)
 
'Rename the mark feature
Try
Dim oMark As MarkFeature
oMark = def.Features.MarkFeatures.Item(1)
oMark.Name = "Mark: Part Number"
Catch
MessageBox.Show("Feature not found, or new name is already in use.", "iLogic")
End Try
 
oTrans.End()
 
    End Sub
End Class
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 = "Select a LinearGeneralDimension."
        _interactEvents.SetCursor(CursorTypeEnum.kCursorBuiltInLineCursor)
 
        _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
            If TypeOf PreSelectEntity.Geometry Is Plane Then
                DoHighlight = True
            End If
        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
 
        SelectedObject = JustSelectedEntities.Item(1)
 
        If TypeOf SelectedObject Is Face Then
            If TypeOf SelectedObject.Geometry Is Plane Then
                Me.SelectedObject = SelectedObject
                Me.ModelPosition = ModelPosition
            End If
        End If
 
        _stillSelecting = False
    End Sub
 
End Class
0 Likes
Message 6 of 6

Rich-T
Advocate
Advocate

Is there a way to catch if the placed textbox overhangs the edge(s) of the selected face with an appropriate error message and restart the rule ?

0 Likes