Overkill

Overkill

Anonymous
Not applicable
1,896 Views
5 Replies
Message 1 of 6

Overkill

Anonymous
Not applicable

.

Is this possible ?

 

AutoCAD has an Overkill command. Is it possible to do something similar in Inventor ?

 

I'll explain the scenario.

 

Point Cloud has been imported into AutoCAD the "PCEXTRACTCENTERLINE" (extracts centre lines from cylindrical parts of point clouds). Why Inventor can't do this I don't know. As many "Centre Lines" for pipes and vessels have been included into DWG.

 

The DWG is now imported into Inventor.

 

Unfortunately, the AutoCAD command has one accuracy setting and there are several centre lines that are close to each other, but not close enough for the Overkill command to see them.

 

There are others that could be co-linear extensions of the same pipe, but aren't quite co-linear.

 

What I want, if this is possible through the API, is to use these lines as Paths for 3D Sweeps in Inventor.

 

Any help or suggestions welcome.

 

See attached zipped DWG of the problem.

 

 

 

 

1,897 Views
5 Replies
Replies (5)
Message 2 of 6

ToddHarris7556
Collaborator
Collaborator

That's a great question, and sounds like IdeaStation material. 

 

We run into the issue (or at least the 2D version of it) frequently with imported Adobe geometry, where we'll have to go clean up a bunch of 'almost-intersecting' and overlapping entities.

 

The Mesh Section /Fit Curve to Section functionality (for remodeling imported mesh geometry) is beginning to take shape - it's still pretty manual, but at least it's headed in the right direction. It'd be nice to see all of this evolve. 


Todd
Product Design Collection (Inventor Pro, 3DSMax, HSMWorks)
Fusion 360 / Fusion Team
0 Likes
Message 3 of 6

Anonymous
Not applicable

.

@ToddHarris7556it would be a good request for Ideas Station, if it can be done.

 

I thought the best way of find out, initially, would be to ask API gurus.

 

Might be better for Scott Sheppard in Labs, if it still exists.

 

Message 4 of 6

JamieVJohnson2
Collaborator
Collaborator

I would like to chime in on this, as I am looking to get this same feature.  However, it appears that I will have to create one myself.  My task is to project a 3D solid onto a 2D sketch (at any angle anywhere), and have the entire set of linework come out clean for further processing (for distance to known point).  I can either calculate a bunch of 3D objects and miss out on the curve silhouettes, or I can just project them to a sketch then work the equation in 2D.  However, the projection methods tend to create many overlapping lines, arcs and such, so I will need to calculate the overlaps and remove them in advance, or the distance calculator will have too much work to do.  I will work on this in VB.Net and post back here when it is finished.  Perhaps anybody else who has worked this angle can offer advice along the way.

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 5 of 6

JamieVJohnson2
Collaborator
Collaborator

+Ok here is a rudely functional overkill for Inventor using vb.net and parallel threading.  Let me know if I left any pieces out.

 

Private Sub OverKillSketchLines(oSketch As Sketch)
        Dim booFound As Boolean
        'redo and split this into groups of line segments that all have the same unit vector first.
        Dim lstLinesByUnitVector As New SortedList(Of uVector, List(Of SketchLine))
        For Each sl1 As SketchLine In oSketch.SketchLines
            Dim uv2d As uVector = New uVector(sl1.Geometry.StartPoint.VectorTo(sl1.Geometry.EndPoint).AsUnitVector)
            If lstLinesByUnitVector.ContainsKey(uv2d) = False Then
                lstLinesByUnitVector.Add(uv2d, New List(Of SketchLine))
            End If
            lstLinesByUnitVector(uv2d).Add(sl1)
        Next
        Dim lstSketchLinesDelete As New List(Of SketchLine)
        System.Threading.Tasks.Parallel.ForEach(Of KeyValuePair(Of uVector, List(Of SketchLine)))(lstLinesByUnitVector.AsEnumerable,
            Sub(kvp)
                'For Each kvp As KeyValuePair(Of uVector, List(Of SketchLine))() In lstLinesByUnitVector
                Dim lstSketchLines As List(Of SketchLine) = kvp.Value
                Dim colGroup As New CollinearGroups
                SyncLock colGroup
                    For Each sl As SketchLine In lstSketchLines
                        colGroup.IsCollinear(sl)
                    Next
                    System.Threading.Tasks.Parallel.ForEach(Of CollinearLines)(colGroup,
                       Sub(cl)
                           SyncLock cl.SketchLines
                               Do
                                   For j As Integer = cl.SketchLines.Count - 1 To 0 Step -1
                                       Dim sl1 As SketchLine = cl.SketchLines(j)
                                       ' Dim sl1Vector As Vector2d = sl1.Geometry.StartPoint.VectorTo(sl1.Geometry.EndPoint)
                                       booFound = False
                                       For i As Integer = cl.SketchLines.Count - 1 To 0 Step -1
                                           Dim sl2 As SketchLine = cl.SketchLines(i)
                                           If sl1 Is sl2 Then Continue For
                                           If DoLineSegmentsOverlap(sl1, sl2) = True Then
                                               MergeLines(sl1, sl2)
                                               booFound = True
                                               cl.SketchLines.Remove(sl2)
                                               lstSketchLinesDelete.Add(sl2)
                                               Exit For 'exit both loops and restart, because we changed the underlying list by deleting a sketch line
                                           End If
                                       Next
                                       If booFound Then Exit For 'exit both loops and restart, because we changed the underlying list by deleting a sketch line
                                   Next
                               Loop Until booFound = False
                           End SyncLock
                       End Sub)
                End SyncLock
                'Next
            End Sub)
        For Each sl As SketchLine In lstSketchLinesDelete
            If sl IsNot Nothing Then sl.Delete()
        Next
    End Sub

    Private Sub MergeLines(ByRef sl1 As SketchLine, ByVal sl2 As SketchLine)
        Dim points As New List(Of Point2d)
        points.Add(sl1.StartSketchPoint.Geometry)
        points.Add(sl1.EndSketchPoint.Geometry)
        points.Add(sl2.StartSketchPoint.Geometry)
        points.Add(sl2.EndSketchPoint.Geometry)
        points.Sort(Function(x, y)
                        Dim comp As Integer = x.X.CompareTo(y.X)
                        If comp = 0 Then
                            comp = x.Y.CompareTo(y.Y)
                        End If
                        Return comp
                    End Function)
        sl1.Reference = False 'break reference to sl1 first.
        sl1.StartSketchPoint.Geometry.X = points(0).X
        sl1.StartSketchPoint.Geometry.Y = points(0).Y
        sl1.EndSketchPoint.Geometry.X = points(3).X
        sl1.EndSketchPoint.Geometry.Y = points(3).Y

    End Sub

    Public Function DoLineSegmentsOverlap(sl1 As SketchLine, sl2 As SketchLine, Optional sl1Vector As Vector2d = Nothing) As Boolean
        '  If sl1Vector Is Nothing Then
        '      sl1Vector = sl1.Geometry.StartPoint.VectorTo(sl1.Geometry.EndPoint)
        ' End If
        ' Dim sl2Vector As Vector2d = sl2.Geometry.StartPoint.VectorTo(sl2.Geometry.EndPoint)
        'If sl1Vector.IsParallelTo(sl2Vector, 4) Then  '  IsParallel(sl1Vector, sl2Vector) Then 
        If IsPointOnLineSegment_Distance(sl1.StartSketchPoint.Geometry3d, sl1.EndSketchPoint.Geometry3d, sl2.StartSketchPoint.Geometry3d) Then
            'merge these two lines
            Return True
        ElseIf IsPointOnLineSegment_Distance(sl1.StartSketchPoint.Geometry3d, sl1.EndSketchPoint.Geometry3d, sl2.EndSketchPoint.Geometry3d) Then
            'merge these two lines
            Return True
        End If
        'End If
        Return False
    End Function

End Class

Public Class uVector
    Implements IComparable

    Dim invVec As UnitVector2d

    Public Sub New(vec As Inventor.UnitVector2d)
        invVec = vec
    End Sub

    Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
        If invVec Is Nothing AndAlso obj Is Nothing Then Return 0
        If invVec IsNot Nothing AndAlso obj Is Nothing Then Return 1
        If obj IsNot Nothing AndAlso invVec Is Nothing Then Return -1
        Dim comp As Integer = 0
        If TypeOf obj Is uVector Then
            Dim objVec As uVector = obj
            comp = Math.Round(invVec.X, 6).CompareTo(Math.Round(objVec.X, 6))
            If comp = 0 Then
                comp = Math.Round(invVec.Y, 6).CompareTo(Math.Round(objVec.Y, 6))
                'If comp = 0 Then
                'comp = Math.Round(invVec.Z, 6).CompareTo(Math.Round(objVec.Z, 6))
                'End If
            End If
        End If
        Return comp
    End Function

    Public Property X As Double
        Get
            Return invVec.X
        End Get
        Set(value As Double)
            invVec.X = value
        End Set
    End Property

    Public Property Y As Double
        Get
            Return invVec.Y
        End Get
        Set(value As Double)
            invVec.Y = value
        End Set
    End Property

    Public Property Z As Double
        Get
            Return invVec.Z
        End Get
        Set(value As Double)
            invVec.Z = value
        End Set
    End Property

    Public ReadOnly Property Length As Double
        Get
            Return invVec.Length
        End Get
    End Property

    Public Overrides Function Equals(obj As Object) As Boolean
        If invVec Is Nothing AndAlso obj Is Nothing Then Return True
        If invVec IsNot Nothing AndAlso obj Is Nothing Then Return False
        If invVec Is Nothing AndAlso obj IsNot Nothing Then Return False
        If TypeOf obj Is uVector Then
            Dim intRound As Integer = 6
            Dim uVec As uVector = obj
            If Math.Round(uVec.X, intRound) = Math.Round(invVec.X, intRound) AndAlso Math.Round(uVec.Y, intRound) = Math.Round(invVec.Y, intRound) AndAlso Math.Round(uVec.Z, intRound) = Math.Round(invVec.Z, intRound) Then
                Return True
            End If
        End If
        Return False
    End Function

End Class

Public Class CollinearLines

    Public Property SketchLines As List(Of SketchLine)

    Public Sub New()
        SketchLines = New List(Of SketchLine)
    End Sub

    Public Function IsCollinear(slTest As SketchLine)
        If SketchLines.Count > 0 Then
            If AreaOfTriangle(SketchLines(0).Geometry.StartPoint, SketchLines(0).Geometry.EndPoint, slTest.Geometry.StartPoint) = 0 Then
                If AreaOfTriangle(SketchLines(0).Geometry.StartPoint, SketchLines(0).Geometry.EndPoint, slTest.Geometry.EndPoint) = 0 Then
                    SketchLines.Add(slTest)
                    Return True
                End If
            End If
        Else
            SketchLines.Add(slTest)
            Return True
        End If
        Return False
    End Function

End Class

Public Class CollinearGroups
    Inherits List(Of CollinearLines)

    Public Sub IsCollinear(slTest As SketchLine)
        'look for line in collection, if found, automatically add line and end sub
        For Each cl As CollinearLines In Me
            If cl.IsCollinear(slTest) = True Then
                Exit Sub
            End If
        Next
        'if not found add a new collection
        Dim clNew As New CollinearLines
        Me.Add(clNew)
        clNew.IsCollinear(slTest)
    End Sub

End Class

 

    Public Function IsPointOnLineSegment_Distance(pStart As Point, pEnd As Point, pTest As Point, Optional tol As Integer = 6) As Boolean
        If Math.Round(pStart.DistanceTo(pTest), tol) + Math.Round(pEnd.DistanceTo(pTest), tol) = Math.Round(pStart.DistanceTo(pEnd), tol) Then
            Return True
        End If
        Return False
    End Function

I use 6 decimal rounding, because in my experience Inventor gets goofy at 8, and we only really ever use 4 in our designs.

 

 

Also feel free to hurt my ego and make this run better, faster, and more efficient, just post the result here for prosperity, as I did.  This overkill's line entities only at this time.  My test reduced a 360+ count of sketchLines to 80+ items (projected from only 60+ faces).  The end result still left some overlapping lines.  Might be due to rounding errors.  A similar process could be created to detect other overlapping types such as arc and ellipses.  Also, it is not a fast process, it takes my Xeon E-2186G 6 core with 32gb ram and NVIDIA P5000 combo a minute or two to fully process (used divide and conquer, and parallel computing really helps). 

 

Note to multithreaded/tasking/parallel developers (so for everyone today) if attempting to make parallel computing work with Inventor, be sure to SyncLock any collections of Inventor's, such as sketch, sketch lines etc; in addition to your own collections if you are going to write-to them.  Think of SyncLock as a way to make all the threads wait in line to modify the source (place it outside of the loop).  Adding is can be the same problem as subtraction, also remember adding that fails = subtraction to back out.  Use Parallel.ForEach if your list is not going to change, otherwise collect items to delete, and remove them after the parallel processing has stopped.  Common errors are Inventor completely crashes (boom!  always good for a laugh!) stating 'memory is in inconsistent state' - solved with SyncLock on sketch object (used when adding sketch entities, not shown here), and a for each loop failing because collection has changed (even though I immediately exit loop after changing collection, and the loop is not a parallel task, but it resides in a parallel task)- solved with looping with index (in reverse as necessary) instead of with foreach.

 

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
Message 6 of 6

inulobo
Advocate
Advocate

Would you be willing to share the full ilogic script. I am have difficulty trying to use this and it would be very useful for what I'm trying to do. I gave it a shot in VBA and and I logic but I couldn't repair it.

0 Likes