Is there any way through iLogic to select a part face and trim/delete all lines/geometry found outside of the selected face?

Is there any way through iLogic to select a part face and trim/delete all lines/geometry found outside of the selected face?

chewy_robot
Contributor Contributor
2,949 Views
6 Replies
Message 1 of 7

Is there any way through iLogic to select a part face and trim/delete all lines/geometry found outside of the selected face?

chewy_robot
Contributor
Contributor

I am looking for ilogic that would ideally be ran from the assembly edit environment and allow me to choose a face (maybe in the active sketch?) and then delete and/or trim all lines or geometry found outside of that face. I am looking for a quick way to do scribed lines. I have ilogic code that already projects cut edges on to the face of the part I select (it runs in the assembly part edit environment) but I would like to take it a step further and trim down the excess lines. I feel like this is possible. Any ideas? Here is my ilogic code that runs in an assembly while editing a part for reference:

 

Dim oApp As Inventor.Application = ThisApplication
Dim oDoc As Inventor.Document = oApp.ActiveDocument
Dim oAssDoc As Inventor.AssemblyDocument = oApp.ActiveDocument
Dim oAssDocDef As Inventor.AssemblyComponentDefinition = oAssDoc.ComponentDefinition

' Prompt user to select a face
Dim oFaceProxy As FaceProxy = oApp.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Pick a face")

' Check if a face was selected
If oFaceProxy Is Nothing Then
	MessageBox.Show("No face was selected.")
	Return
End If

' Create a new sketch on the selected face, in the context of the part
Dim oSketch As PlanarSketch = Nothing
Try
	' Access the occurrence containing the face
	Dim oOcc As ComponentOccurrence = oFaceProxy.ContainingOccurrence
	' Access the part document's component definition
	Dim oPartCompDef As PartComponentDefinition = oOcc.Definition
	oSketch = oPartCompDef.Sketches.Add(oFaceProxy.NativeObject)
	oSketch.Edit()  ' This will start the sketch editing mode
Catch ex As Exception
	MessageBox.Show("Failed to create a sketch. Error: " & ex.Message)
	Return
End Try

' Check if there is an active sketch
If oSketch Is Nothing Then
	MessageBox.Show("There is no active sketch.")
	Return
End If

' Iterate through the occurrences in the assembly to find which parts are touching the selected face
Dim oOccurrenceList As New List(Of ComponentOccurrence)
For Each oOccurrence As ComponentOccurrence In oAssDocDef.Occurrences
	Dim oOccCompDef As ComponentDefinition = oOccurrence.Definition

	' Check if the occurrence is touching the selected face by checking for interference
	If oApp.MeasureTools.GetMinimumDistance(oOccurrence, oFaceProxy) = 0 Then
		' Add the occurrence to our list
		oOccurrenceList.Add(oOccurrence)
	End If
Next

' Start a transaction to project cut edges
Dim oTrans As Transaction = oApp.TransactionManager.StartTransaction(oDoc, "Project Cut Edges")

Try
	' Attempt to project the touching parts' cut edges onto the sketch
	Dim oControlDef As ControlDefinition = oApp.CommandManager.ControlDefinitions.Item("SketchProjectCutEdgesCmd")

	' Clear current selection
	oApp.ActiveDocument.SelectSet.Clear()

	' Select the occurrences that are touching
	For Each oOcc In oOccurrenceList
		oApp.ActiveDocument.SelectSet.Select(oOcc)
	Next

	' Execute the command to project cut edges
	oControlDef.Execute()

	' Commit the transaction if we were successful
	oTrans.End()
	MessageBox.Show("Cut edges projected!")
Catch ex As Exception
	' Abort the transaction if there was an error
	oTrans.Abort()
	MessageBox.Show("An error occurred while trying to project cut edges: " & ex.Message)
End Try

 

0 Likes
Accepted solutions (1)
2,950 Views
6 Replies
Replies (6)
Message 2 of 7

A.Acheson
Mentor
Mentor

Hi @chewy_robot 

Can you provide images of what your doing manually? We will need to understand you manual method before attempting to help automate. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 3 of 7

chewy_robot
Contributor
Contributor

Thanks for the reply. I've attached 2 images to this reply and to my original post. Basically, my iLogic script does what it shows in the first image. It allows me to select a face on a part in an assembly edit, then it automatically projects cut edges for only the parts in the assembly that touch the face I selected. You can see those in blue (yellow lines are the projected geometry of the face I selected). I manually delete the blue lines that are outside of the yellow lines (which is the face boundary/perimeter). This one is not too bad, but I have some instances where it's pretty tedious. With the lines all cleaned up outside of the yellow perimeter of the face, it looks like what I want in image 2. I then delete the yellow projected lines loop. I'm looking for a way to automatically detect lines that are outside of the face I initially selected and either trim the lines then delete (so that way lines that are partly on the face and partly off the face keeps the lines that are on the face but not off the face). Only thing I can think of is the yellow lines (projected geometry loop) is always an entity under the sketch name and is always called "Projected GeometryXX" where the "XX" is whatever iteration number of the loop. I hope this makes sense!

0 Likes
Message 4 of 7

A.Acheson
Mentor
Mentor

Hi @chewy_robot 

Thanks for the extra info I know now what you want to achieve. I am concerned this will be rather complex to automate. Here are a few of those criteria you will need to determine before continuing. I have yet to automate such complexity so others input here will be a valuable asset. 

1. Firstly sketchlines have no trim method. As far as I can gather the trim function is made up of a number of commands such as adding a sketch point and perhaps deleting the newly formed sketchline in the boundary you choose. Only my theory hopefully more expierienced members can clarify how it works.

2. You will need to create the boundary of the face and figure out which sketch line you want to trim at. Very easy when you select boundary line manually.

3. Determining if a sketch line crosses the boundary line set.  

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 5 of 7

lmc.engineering
Advocate
Advocate
Accepted solution

As @A.Acheson has said, there are no API methods for trimming, however,  there are some options to take, depending on how your initial sketchlines are created.

My preferred method in to use FindUsingRay, as rays can be cast using vectors; where we can get the intersections of the ray with any face/edge/point, however this method is a little involved to give a watertight solution here.

Second option is to use your (blue) sketchlines to create new sketchlines inside the boundary of the projected face. Again, it comes with some caveats around arcs, circles, and splines; however i'm happy to point you in the right direction based on your blue lines always being Sketchlines:

First function gets a dictionary of intersection points for each sketchline:

    Public Shared Function CreateIntersectPoints(sk As PlanarSketch, f As Face) As Dictionary(Of SketchLine, List(Of Point2d))
        Dim boundaryList As New List(Of SketchEntity)
        For Each ege As Edge In f.Edges
            Dim se As SketchEntity = sk.AddByProjectingEntity(ege)
            se.Construction = True
            boundaryList.Add(se)
        Next

        'create dictionary to hold lines and intersect points, respectively
        Dim pointsOnLine As New Dictionary(Of SketchLine, List(Of Point2d))
        'loop over sketchlines in sketch we want to trim
        For Each layoutEnt As SketchEntity In sk.SketchEntities
            If boundaryList.Contains(layoutEnt) Then Continue For 'skip boundary ents

            If TypeOf layoutEnt Is SketchLine Then
                Dim intersections As ObjectsEnumerator = Nothing
                Dim lineA As SketchLine = CType(layoutEnt, SketchLine)

                Dim listOfPoints As New List(Of Point2d)


                'test if this line intersects any boundary entities
                For Each boundaryEnt As SketchEntity In boundaryList
                    Select Case boundaryEnt.Type
                        Case ObjectTypeEnum.kSketchLineObject
                            Dim lineB As SketchLine = CType(boundaryEnt, SketchLine)
                            intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                        Case ObjectTypeEnum.kSketchSplineObject
                            Dim lineB As SketchSpline = CType(boundaryEnt, SketchSpline)
                            intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                        Case ObjectTypeEnum.kSketchCircleObject
                            Dim lineB As SketchCircle = CType(boundaryEnt, SketchCircle)
                            intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                        Case ObjectTypeEnum.kSketchArcObject
                            Dim lineB As SketchArc = CType(boundaryEnt, SketchArc)
                            intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                    End Select

                    If intersections Is Nothing Then Continue For

                    'collect intersects
                    If intersections.Count > 0 Then
                        For Each intPoint As Point2d In intersections
                            listOfPoints.Add(intPoint)
                        Next
                    End If
                Next

                'collect line and intersects
                If Not listOfPoints Is Nothing Then
                    If Not pointsOnLine.ContainsKey(lineA) Then
                        pointsOnLine.Add(lineA, listOfPoints)
                    End If
                End If
            End If
        Next

        Return pointsOnLine
    End Function

 
Next we create the new lines:

    Private Shared Sub CreateNewLines(def As PartComponentDefinition, f As Face, sk As PlanarSketch, linedata As Dictionary(Of SketchLine, List(Of Point2d)))

        For Each kvp As KeyValuePair(Of SketchLine, List(Of Point2d)) In linedata
            Dim listOfPoints As List(Of Point2d) = kvp.Value
            For i = 0 To listOfPoints.Count - 1
                If i = listOfPoints.Count - 1 Then Exit For
                Dim point1 As Point2d = listOfPoints(i)
                Dim point2 As Point2d = listOfPoints(i + 1)

                Dim oTrans As Matrix
                oTrans = sk.SketchToModelTransform

                Dim midpoint As Point2d = CalculateMidpoint(point1.X, point1.Y, point2.X, point2.Y)
                Dim oMidPoint3D As Point = g_invApp.TransientGeometry.CreatePoint(midpoint.X, midpoint.Y, 0)
                oMidPoint3D.TransformBy(oTrans)

                'test if the midpoint is on the face
                If PointIsOnBoundary(f, oMidPoint3D) Then
                    Dim sl As SketchLine = sk.SketchLines.AddByTwoPoints(listOfPoints(i), listOfPoints(i + 1))
                End If
            Next
            kvp.Key.Delete()
        Next
    End Sub

    Public Shared Function CalculateMidpoint(x1 As Double, y1 As Double, x2 As Double, y2 As Double) As Point2d
        Dim midX As Double = (x1 + x2) / 2
        Dim midY As Double = (y1 + y2) / 2
        Return g_invApp.TransientGeometry.CreatePoint2d(midX, midY)
    End Function

    Public Shared Function PointIsOnBoundary(f As Face, oPoint As Point) As Boolean
        If f.GetClosestPointTo(oPoint).IsEqualTo(oPoint, 0.0001) Then
            'Point is on face
            Return True
        Else
            'Point is not on face
            Return False
        End If
    End Function

 
Lastly we use it like this:

Dim d As PartDocument = g_invApp.ActiveDocument
        Dim def As PartComponentDefinition = d.ComponentDefinition
        Dim f As Face = g_invApp.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Pick a face")
        Dim sk As Sketch = def.Sketches.Item("Test")
        Dim trans As Transaction = g_invApp.TransactionManager.StartTransaction(d, "Create lines")
        CreateNewLines(def, f, sk, CreateIntersectPoints(sk, f))
        trans.End()


It goes without saying; these tasks can get very complex, and often will need adapting to specific needs. The above is provided to help you along, and you may well need to adapt it.

Regards

Message 6 of 7

chewy_robot
Contributor
Contributor

Thank you so much for this info! I believe I am getting so close. With this above info, I now am able to successfully trim/split lines that are touching the face border and have them deleted. However, now, it seems like it's a 50/50 chance that it deletes the correct segment of the line. Sometimes it deletes the part of the line outside of the face border leaving the rest of the line inside the border (correct), and other times it keeps the line outside of the face border but deletes the part of the line on the inside of the face border (incorrect). Here is my updated code for reference. It indeed is quite complex but highly valuable so I appreciate your help! Also attached are 2 images, scribes 3.png shows the excess lines that need to be trimmed as well as lines past the face edge that need to be deleted. Scribes 4.png shows what the code below does, just needs to be tweaked I think to work correctly although it is close!

 

Public Sub Main()
    ' Declare the application object and get the current application
    Dim oApp As Inventor.Application = ThisApplication
    Dim oDoc As Inventor.Document = oApp.ActiveDocument
    Dim oAssDoc As Inventor.AssemblyDocument = oApp.ActiveDocument
    Dim oAssDocDef As Inventor.AssemblyComponentDefinition = oAssDoc.ComponentDefinition

    ' Prompt user to select a face
    Dim oFaceProxy As FaceProxy = oApp.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Pick a face")

    ' Check if a face was selected
    If oFaceProxy Is Nothing Then
        MessageBox.Show("No face was selected.")
        Return
    End If

    ' Prompt the user to name the sketch
    Dim sketchName As String = InputBox("Please enter a name for the new sketch:", "Name Sketch", "SCRIBE LINES")
    If sketchName = "" Then
        MessageBox.Show("No name was entered for the sketch.")
        Return
    End If

    ' Access the occurrence containing the face
    Dim oOcc As ComponentOccurrence = oFaceProxy.ContainingOccurrence
    ' Access the part document's component definition
    Dim oPartCompDef As PartComponentDefinition = oOcc.Definition

    ' Initialize the sketch variable
    Dim oSketch As PlanarSketch = Nothing

    Try
        oSketch = oPartCompDef.Sketches.Add(oFaceProxy.NativeObject)
        oSketch.Name = sketchName
        oSketch.Edit()  ' Start the sketch editing mode
    Catch ex As Exception
        MessageBox.Show("Failed to create a sketch. Error: " & ex.Message)
        Return
    End Try

    ' Check for an active sketch
    If oSketch Is Nothing Then
        MessageBox.Show("There is no active sketch.")
        Return
    End If

    ' Iterate through the occurrences in the assembly to find parts touching the selected face
    Dim oOccurrenceList As New List(Of ComponentOccurrence)
    For Each oOccurrence As ComponentOccurrence In oAssDocDef.Occurrences
        Dim oOccCompDef As ComponentDefinition = oOccurrence.Definition

        ' Check for interference with the selected face
        If oApp.MeasureTools.GetMinimumDistance(oOccurrence, oFaceProxy) = 0 AndAlso Not oOccurrence Is oFaceProxy.ContainingOccurrence Then
            oOccurrenceList.Add(oOccurrence)
        End If
    Next

    ' Start a transaction to project cut edges
    Dim oTrans As Transaction = oApp.TransactionManager.StartTransaction(oDoc, "Project Cut Edges")

    Try
        ' Project the touching parts' cut edges onto the sketch
        Dim oControlDef As ControlDefinition = oApp.CommandManager.ControlDefinitions.Item("SketchProjectCutEdgesCmd")
        oApp.ActiveDocument.SelectSet.Clear() ' Clear current selection

        ' Select occurrences that are touching
        For Each oOcc In oOccurrenceList
            oApp.ActiveDocument.SelectSet.Select(oOcc)
        Next

        oControlDef.Execute() ' Execute the command
        oTrans.End() ' Commit the transaction
    Catch ex As Exception
        oTrans.Abort() ' Abort transaction on error
        MessageBox.Show("An error occurred while projecting cut edges: " & ex.Message)
        Return
    Finally
        oApp.CommandManager.StopActiveCommand() ' Ensure no command is left active
    End Try

    ' After projecting the edges, create intersection data and new lines
    Dim faceSelected As Face = oFaceProxy.NativeObject
    Dim intersectionData As Dictionary(Of SketchLine, List(Of Point2d)) = CreateIntersectPoints(oSketch, faceSelected)  ' Ensure CreateIntersectPoints doesn't need oApp

    ' Begin a new transaction to create trimmed lines
    Dim trimTrans As Transaction = oApp.TransactionManager.StartTransaction(oDoc, "Create Trimmed Lines")
    Try
        CreateNewLines(oApp, oPartCompDef, faceSelected, oSketch, intersectionData)
        trimTrans.End() ' End the transaction to apply the changes
    Catch ex As Exception
        MessageBox.Show("An error occurred while trimming the lines: " & ex.Message)
        trimTrans.Abort() ' Abort transaction on error
    Finally
        ' Optionally, clean up any unneeded resources or reset states here
    End Try
End Sub

' Function to create intersection points
Public Shared Function CreateIntersectPoints(sk As PlanarSketch, f As Face) As Dictionary(Of SketchLine, List(Of Point2d))
    Dim boundaryList As New List(Of SketchEntity)
    For Each ege As Edge In f.Edges
        Dim se As SketchEntity = sk.AddByProjectingEntity(ege)
        se.Construction = True
        boundaryList.Add(se)
    Next

    Dim pointsOnLine As New Dictionary(Of SketchLine, List(Of Point2d))
    For Each layoutEnt As SketchEntity In sk.SketchEntities
        If boundaryList.Contains(layoutEnt) Then Continue For ' Skip boundary entities

        If TypeOf layoutEnt Is SketchLine Then
            Dim lineA As SketchLine = CType(layoutEnt, SketchLine)
            Dim listOfPoints As New List(Of Point2d)

            For Each boundaryEnt As SketchEntity In boundaryList
                Dim intersections As ObjectsEnumerator = Nothing
                Select Case boundaryEnt.Type
                    Case ObjectTypeEnum.kSketchLineObject
                        Dim lineB As SketchLine = CType(boundaryEnt, SketchLine)
                        intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                    Case ObjectTypeEnum.kSketchSplineObject
                        Dim lineB As SketchSpline = CType(boundaryEnt, SketchSpline)
                        intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                    Case ObjectTypeEnum.kSketchCircleObject
                        Dim lineB As SketchCircle = CType(boundaryEnt, SketchCircle)
                        intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                    Case ObjectTypeEnum.kSketchArcObject
                        Dim lineB As SketchArc = CType(boundaryEnt, SketchArc)
                        intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                End Select

                If intersections IsNot Nothing AndAlso intersections.Count > 0 Then
                    For Each intPoint As Point2d In intersections
                        listOfPoints.Add(intPoint)
                    Next
                End If
            Next

            If listOfPoints.Count > 0 AndAlso Not pointsOnLine.ContainsKey(lineA) Then
                pointsOnLine.Add(lineA, listOfPoints)
            End If
        End If
    Next

    Return pointsOnLine
End Function

' Function to create new lines
Private Shared Sub CreateNewLines(app As Inventor.Application, def As PartComponentDefinition, f As Face, sk As PlanarSketch, linedata As Dictionary(Of SketchLine, List(Of Point2d)))
    ' Get a reference to the TransientGeometry object which is used to create geometry objects
    Dim tg As TransientGeometry = app.TransientGeometry

    ' Iterate through all lines and their associated intersection points
    For Each kvp As KeyValuePair(Of SketchLine, List(Of Point2d)) In linedata
        Dim sl As SketchLine = kvp.Key
        Dim intersectionPoints As List(Of Point2d) = kvp.Value
        ' Sort the intersection points by their distance from the start of the line
        intersectionPoints.Sort(Function(a, b) tg.CreatePoint2d(sl.StartSketchPoint.Geometry.X, sl.StartSketchPoint.Geometry.Y).DistanceTo(a).CompareTo(tg.CreatePoint2d(sl.StartSketchPoint.Geometry.X, sl.StartSketchPoint.Geometry.Y).DistanceTo(b)))

        ' Check if the line needs to be split
        If intersectionPoints.Count > 0 Then
            ' Iterate over each intersection point to split the line
            For i As Integer = 0 To intersectionPoints.Count - 1
                ' Check if the midpoint (intersection point) is on the face
                Dim midpoint3D As Point = tg.CreatePoint(intersectionPoints(i).X, intersectionPoints(i).Y, 0)
                midpoint3D.TransformBy(sk.SketchToModelTransform)
                If PointIsOnBoundary(f, midpoint3D) Then
                    ' Split the line at this intersection point
                    ' If this is the first intersection, use the line's start point
                    Dim startPoint As Point2d = If (i = 0, sl.StartSketchPoint.Geometry, intersectionPoints(i - 1))
                    ' Add the new line segment within the boundary
                    sk.SketchLines.AddByTwoPoints(startPoint, intersectionPoints(i))
                End If
            Next
            ' Remove the original line as it has been replaced by the split lines
            sl.Delete()
        Else
            ' If there are no intersection points and the line is not within the face boundary, delete it
            Dim startPoint3D As Point = tg.CreatePoint(sl.StartSketchPoint.Geometry.X, sl.StartSketchPoint.Geometry.Y, 0)
            Dim endPoint3D As Point = tg.CreatePoint(sl.EndSketchPoint.Geometry.X, sl.EndSketchPoint.Geometry.Y, 0)
            startPoint3D.TransformBy(sk.SketchToModelTransform)
            endPoint3D.TransformBy(sk.SketchToModelTransform)
            If Not (PointIsOnBoundary(f, startPoint3D) And PointIsOnBoundary(f, endPoint3D)) Then
                sl.Delete()
            End If
        End If
    Next
End Sub

' Function to calculate midpoint
Public Shared Function CalculateMidpoint(app As Inventor.Application, x1 As Double, y1 As Double, x2 As Double, y2 As Double) As Point2d
    Dim midX As Double = (x1 + x2) / 2
    Dim midY As Double = (y1 + y2) / 2
    Return app.TransientGeometry.CreatePoint2d(midX, midY)
End Function

' Function to check if point is on boundary
Public Shared Function PointIsOnBoundary(f As Face, oPoint As Point) As Boolean
    Dim closestPoint As Point = f.GetClosestPointTo(oPoint)
    Return closestPoint.IsEqualTo(oPoint, 0.0001)
End Function

 

 

0 Likes
Message 7 of 7

chewy_robot
Contributor
Contributor

Actually, getting ahead of myself here. I got it, thank you for your help! Here is my code:

Public Sub Main()
        ' Declare the application object and get the current application
        Dim oApp As Inventor.Application = ThisApplication
        Dim oDoc As Inventor.Document = oApp.ActiveDocument
        Dim oAssDoc As Inventor.AssemblyDocument = oApp.ActiveDocument
        Dim oAssDocDef As Inventor.AssemblyComponentDefinition = oAssDoc.ComponentDefinition
 
        ' Prompt user to select a face
        Dim oFaceProxy As FaceProxy = oApp.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Pick a face")
 
        ' Check if a face was selected
        If oFaceProxy Is Nothing Then
               MessageBox.Show("No face was selected.")
               Return
        End If
 
        ' Prompt the user to name the sketch
        Dim sketchName As String = InputBox("Please enter a name for the new sketch:", "Name Sketch", "SCRIBE LINES")
        If sketchName = "" Then
               MessageBox.Show("No name was entered for the sketch.")
               Return
        End If
 
        ' Access the occurrence containing the face
        Dim oOcc As ComponentOccurrence = oFaceProxy.ContainingOccurrence
        ' Access the part document's component definition
        Dim oPartCompDef As PartComponentDefinition = oOcc.Definition
 
        ' Initialize the sketch variable
        Dim oSketch As PlanarSketch = Nothing
 
        Try
               oSketch = oPartCompDef.Sketches.Add(oFaceProxy.NativeObject)
               oSketch.Name = sketchName
               oSketch.Edit()  ' Start the sketch editing mode
        Catch ex As Exception
               MessageBox.Show("Failed to create a sketch. Error: " & ex.Message)
               Return
        End Try
 
        ' Check for an active sketch
        If oSketch Is Nothing Then
               MessageBox.Show("There is no active sketch.")
               Return
        End If
 
        ' Iterate through the occurrences in the assembly to find parts touching the selected face
        Dim oOccurrenceList As New List(Of ComponentOccurrence)
        For Each oOccurrence As ComponentOccurrence In oAssDocDef.Occurrences
               Dim oOccCompDef As ComponentDefinition = oOccurrence.Definition
 
               ' Check for interference with the selected face
               If oApp.MeasureTools.GetMinimumDistance(oOccurrence, oFaceProxy) = 0 AndAlso Not oOccurrence Is oFaceProxy.ContainingOccurrence Then
                       oOccurrenceList.Add(oOccurrence)
               End If
        Next
 
        ' Start a transaction to project cut edges
        Dim oTrans As Transaction = oApp.TransactionManager.StartTransaction(oDoc, "Project Cut Edges")
 
        Try
               ' Project the touching parts' cut edges onto the sketch
               Dim oControlDef As ControlDefinition = oApp.CommandManager.ControlDefinitions.Item("SketchProjectCutEdgesCmd")
               oApp.ActiveDocument.SelectSet.Clear() ' Clear current selection
 
               ' Select occurrences that are touching
               For Each oOcc In oOccurrenceList
                       oApp.ActiveDocument.SelectSet.Select(oOcc)
               Next
 
               oControlDef.Execute() ' Execute the command
               oTrans.End() ' Commit the transaction
        Catch ex As Exception
               oTrans.Abort() ' Abort transaction on error
               MessageBox.Show("An error occurred while projecting cut edges: " & ex.Message)
               Return
        Finally
               oApp.CommandManager.StopActiveCommand() ' Ensure no command is left active
        End Try
 
        ' After projecting the edges, create intersection data and new lines
        Dim faceSelected As Face = oFaceProxy.NativeObject
        Dim intersectionData As Dictionary(Of SketchLine, List(Of Point2d)) = CreateIntersectPoints(oSketch, faceSelected)  ' Ensure CreateIntersectPoints doesn't need oApp
 
        ' Begin a new transaction to create trimmed lines
        Dim trimTrans As Transaction = oApp.TransactionManager.StartTransaction(oDoc, "Create Trimmed Lines")
        Try
               CreateNewLines(oApp, oPartCompDef, faceSelected, oSketch, intersectionData)
               trimTrans.End() ' End the transaction to apply the changes
        Catch ex As Exception
               MessageBox.Show("An error occurred while trimming the lines: " & ex.Message)
               trimTrans.Abort() ' Abort transaction on error
        Finally
               ' Optionally, clean up any unneeded resources or reset states here
        End Try
 
' Get a reference to the TransientGeometry object which is used to create geometry objects
Dim tg As TransientGeometry = oApp.TransientGeometry
 
Dim linesToDelete As New List(Of SketchLine)
 
' Iterate over all the lines in the sketch
For Each skLine As SketchLine In oSketch.SketchLines
    ' Check both the start and end points of the line to see if they are outside the boundary
    Dim startPt As Point = tg.CreatePoint(skLine.StartSketchPoint.Geometry.X, skLine.StartSketchPoint.Geometry.Y, 0)
    Dim endPt As Point = tg.CreatePoint(skLine.EndSketchPoint.Geometry.X, skLine.EndSketchPoint.Geometry.Y, 0)
    startPt.TransformBy(oSketch.SketchToModelTransform)
    endPt.TransformBy(oSketch.SketchToModelTransform)
 
    ' If both points are outside, add the line to the list for deletion
    If Not PointIsOnBoundary(faceSelected, startPt) AndAlso Not PointIsOnBoundary(faceSelected, endPt) Then
        linesToDelete.Add(skLine)
    End If
Next
 
' Now delete all lines that are confirmed to be outside the boundary
For Each line In linesToDelete
    Line.Delete()

Next
 
 
 
 
End Sub
 
' Function to create intersection points
Public Shared Function CreateIntersectPoints(sk As PlanarSketch, f As Face) As Dictionary(Of SketchLine, List(Of Point2d))
        Dim boundaryList As New List(Of SketchEntity)
        For Each ege As Edge In f.Edges
               Dim se As SketchEntity = sk.AddByProjectingEntity(ege)
               se.Construction = True
               boundaryList.Add(se)
        Next
 
        Dim pointsOnLine As New Dictionary(Of SketchLine, List(Of Point2d))
        For Each layoutEnt As SketchEntity In sk.SketchEntities
               If boundaryList.Contains(layoutEnt) Then Continue For ' Skip boundary entities
 
               If TypeOf layoutEnt Is SketchLine Then
                       Dim lineA As SketchLine = CType(layoutEnt, SketchLine)
                       Dim listOfPoints As New List(Of Point2d)
 
                       For Each boundaryEnt As SketchEntity In boundaryList
                               Dim intersections As ObjectsEnumerator = Nothing
                               Select Case boundaryEnt.Type
                                      Case ObjectTypeEnum.kSketchLineObject
                                              Dim lineB As SketchLine = CType(boundaryEnt, SketchLine)
                                              intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                                      Case ObjectTypeEnum.kSketchSplineObject
                                              Dim lineB As SketchSpline = CType(boundaryEnt, SketchSpline)
                                              intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                                      Case ObjectTypeEnum.kSketchCircleObject
                                              Dim lineB As SketchCircle = CType(boundaryEnt, SketchCircle)
                                              intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                                      Case ObjectTypeEnum.kSketchArcObject
                                              Dim lineB As SketchArc = CType(boundaryEnt, SketchArc)
                                              intersections = lineA.Geometry.IntersectWithCurve(lineB.Geometry)
                               End Select
 
                               If intersections IsNot Nothing AndAlso intersections.Count > 0 Then
                                      For Each intPoint As Point2d In intersections
                                              listOfPoints.Add(intPoint)
                                      Next
                               End If
                       Next
 
                       If listOfPoints.Count > 0 AndAlso Not pointsOnLine.ContainsKey(lineA) Then
                               pointsOnLine.Add(lineA, listOfPoints)
                       End If
               End If
        Next
 
        Return pointsOnLine
End Function
 
' Function to create new lines
Private Shared Sub CreateNewLines(app As Inventor.Application, def As PartComponentDefinition, f As Face, sk As PlanarSketch, linedata As Dictionary(Of SketchLine, List(Of Point2d)))
    ' Get a reference to the TransientGeometry object which is used to create geometry objects
    Dim tg As TransientGeometry = app.TransientGeometry
 
    ' Iterate through all lines and their associated intersection points
    For Each kvp As KeyValuePair(Of SketchLine, List(Of Point2d)) In linedata
        Dim sl As SketchLine = kvp.Key
        Dim intersectionPoints As List(Of Point2d) = kvp.Value
 
        ' Sort the intersection points by their distance from the start of the line
        intersectionPoints.Sort(Function(a, b) tg.CreatePoint2d(sl.StartSketchPoint.Geometry.X, sl.StartSketchPoint.Geometry.Y).DistanceTo(a).CompareTo(tg.CreatePoint2d(sl.StartSketchPoint.Geometry.X, sl.StartSketchPoint.Geometry.Y).DistanceTo(b)))
 
        ' List to hold all the points of the original line, including start, end, and intersections
        Dim allPoints As New List(Of Point2d)
        allPoints.Add(sl.StartSketchPoint.Geometry)
        allPoints.AddRange(intersectionPoints)
        allPoints.Add(sl.EndSketchPoint.Geometry)
 
        ' Now iterate through all segments of the line (formed by the points)
        For i As Integer = 0 To allPoints.Count - 2
            ' Each segment is between 'i' and 'i+1' in the sorted list
            Dim point1 As Point2d = allPoints(i)
            Dim point2 As Point2d = allPoints(i + 1)
           
            ' Check the midpoint of each segment to see if it's on the face
            Dim midpoint As Point2d = CalculateMidpoint(app, point1.X, point1.Y, point2.X, point2.Y)
            Dim midpoint3D As Point = tg.CreatePoint(midpoint.X, midpoint.Y, 0)
            midpoint3D.TransformBy(sk.SketchToModelTransform)
 
            ' If the midpoint of the segment is on the boundary, it means the segment is within the face
            If PointIsOnBoundary(f, midpoint3D) Then
                ' Add the segment as a new sketch line if it doesn't exist yet
                Dim segmentExists As Boolean = False
                For Each line As SketchLine In sk.SketchLines
                    If Line.StartSketchPoint.Geometry.IsEqualTo(point1) AndAlso Line.EndSketchPoint.Geometry.IsEqualTo(point2) Then
                        segmentExists = True
                        Exit For
                    End If
                Next
                If Not segmentExists Then
                    sk.SketchLines.AddByTwoPoints(point1, point2)
                End If
            End If
        Next
 
        ' Remove the original line as it has been replaced by the new segments
        sl.Delete()
    Next
End Sub
 
 
 
' Function to calculate midpoint
Public Shared Function CalculateMidpoint(app As Inventor.Application, x1 As Double, y1 As Double, x2 As Double, y2 As Double) As Point2d
        Dim midX As Double = (x1 + x2) / 2
        Dim midY As Double = (y1 + y2) / 2
        Return app.TransientGeometry.CreatePoint2d(midX, midY)
End Function
 
' Function to check if point is on boundary
Public Shared Function PointIsOnBoundary(f As Face, oPoint As Point) As Boolean
        Dim closestPoint As Point = f.GetClosestPointTo(oPoint)
        Return closestPoint.IsEqualTo(oPoint, 0.0001)
End Function