Tracing an Arc In a Polyline in line intervals

tristan.jonas8XAAW
Advocate

Tracing an Arc In a Polyline in line intervals

tristan.jonas8XAAW
Advocate
Advocate

Hello, 

Hope everyone's doing well today 🙂 I'm creating a script (ARC2PLINE) that's supposed to trace a polyline perfectly at the lines, but when it finds an arc within the polyline, it iterates a straight line segment every 100 units along the arc until the end, and then continues on its merry way to more adventures with more lines and arcs along the polyline.

So I got this script working for just plain arcs (the ARCAA command below demonstrates this), but i'm having some difficulties making it work for arcs within polylines I've gotten all manners of strange iterations (I present two below) when it should be basically tracing, it's not connecting to the line segments that surround the arc properly, I'm just really at a loss for what's going on here. Here's what I got:

 

 

<CommandMethod("ARC2PLINE")>
    Public Sub ArcToPolyline_Main()
        Dim ed = Application.DocumentManager.MdiActiveDocument.Editor

        ' Prompt the user to select a polyline
        Dim plineOptions = New PromptEntityOptions(vbLf & "Select a polyline: ")
        plineOptions.SetRejectMessage(vbLf & "Selected entity must be a Polyline.")
        plineOptions.AddAllowedClass(GetType(Polyline), True)
        Dim plineResult = ed.GetEntity(plineOptions)
        If plineResult.Status <> PromptStatus.OK Then Return

        Dim db = Application.DocumentManager.MdiActiveDocument.Database

        Using tr = db.TransactionManager.StartTransaction()
            ' Get the selected polyline
            Dim selectedPline = CType(tr.GetObject(plineResult.ObjectId, OpenMode.ForRead), Polyline)

            ' Create a new polyline for the output
            Dim newPline As New Polyline()

            ' Iterate through the polyline segments
            For index As Integer = 0 To selectedPline.NumberOfVertices - 2
                Dim startPoint As Point2d = selectedPline.GetPoint2dAt(index)
                Dim endPoint As Point2d = selectedPline.GetPoint2dAt(index + 1)

                If selectedPline.GetSegmentType(index) = SegmentType.Arc Then
                    Dim arcSegment As CircularArc2d = selectedPline.GetArcSegment2dAt(index)
                    Dim arc As New Arc(New Point3d(arcSegment.Center.X, arcSegment.Center.Y, 0), arcSegment.Radius, arcSegment.StartAngle, arcSegment.EndAngle)

                    ' Orient the arc correctly
                    If selectedPline.GetBulgeAt(index) > 0 Then
                        Dim temp = arc.StartAngle
                        arc.StartAngle = arc.EndAngle
                        arc.EndAngle = temp
                    End If

                    Dim arcPoints As List(Of Point2d) = GenerateArcPoints(arc)

                    For i As Integer = 0 To arcPoints.Count - 1
                        newPline.AddVertexAt(newPline.NumberOfVertices, arcPoints(i), 0, 0, 0)
                    Next
                Else
                    ' Add line segment points to the new polyline
                    If newPline.NumberOfVertices = 0 OrElse newPline.GetPoint2dAt(newPline.NumberOfVertices - 1) <> startPoint Then
                        newPline.AddVertexAt(newPline.NumberOfVertices, startPoint, 0, 0, 0)
                    End If
                    newPline.AddVertexAt(newPline.NumberOfVertices, endPoint, 0, 0, 0)
                End If
            Next

            ' Add the new polyline to the current space
            Dim curSpace = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
            curSpace.AppendEntity(newPline)
            tr.AddNewlyCreatedDBObject(newPline, True)

            tr.Commit()
        End Using
    End Sub


    Public Function GenerateArcPoints(arc As Arc) As List(Of Point2d)
        Dim points As New List(Of Point2d)

        Dim startPoint As Point2d = New Point2d(arc.StartPoint.X, arc.StartPoint.Y)
        Dim endPoint As Point2d = New Point2d(arc.EndPoint.X, arc.EndPoint.Y)

        points.Add(startPoint)

        Dim interval As Double = 100.0
        Dim arcLength As Double = arc.Length
        Dim numIntervals As Integer = CInt(Math.Floor(arcLength / interval))

        ' Ensure that the end angle is greater than the start angle
        Dim endAngle As Double = arc.EndAngle
        If endAngle < arc.StartAngle Then
            endAngle += 2 * Math.PI
        End If

        ' Add a small tolerance to account for floating-point arithmetic
        Dim tolerance As Double = 0.0000000001
        If Math.Abs(endAngle - 2 * Math.PI) < tolerance Then
            endAngle -= tolerance
        End If

        For i As Integer = 1 To numIntervals + 1
            Dim angle = arc.StartAngle + (i * (endAngle - arc.StartAngle) / numIntervals)

            ' Ensure the angle stays within bounds
            If angle > endAngle Then
                angle = endAngle
            ElseIf angle < arc.StartAngle Then
                angle = arc.StartAngle
            End If

            ' Convert angle to point on the arc using center, radius, and angle
            Dim pointOnArc = New Point3d(arc.Center.X + arc.Radius * Math.Cos(angle), arc.Center.Y + arc.Radius * Math.Sin(angle), arc.Center.Z)
            Dim pointOnArc2d = New Point2d(pointOnArc.X, pointOnArc.Y)

            points.Add(pointOnArc2d)

            If angle = endAngle Then
                Exit For
            End If
        Next

        Return points
    End Function

    <CommandMethod("ARCAA")>
    Public Sub TestGenerateArcPoints()
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim db = doc.Database
        Dim ed = doc.Editor

        ' Prompt the user to select an arc
        Dim arcOptions = New PromptEntityOptions(vbLf & "Select an arc: ")
        arcOptions.SetRejectMessage(vbLf & "Selected entity must be an Arc.")
        arcOptions.AddAllowedClass(GetType(Arc), True)
        Dim arcResult = ed.GetEntity(arcOptions)

        If arcResult.Status <> PromptStatus.OK Then Return

        Using tr = db.TransactionManager.StartTransaction()
            ' Get the selected arc
            Dim selectedArc = CType(tr.GetObject(arcResult.ObjectId, OpenMode.ForRead), Arc)

            ' Generate the points on the arc
            Dim points = GenerateArcPoints(selectedArc)

            ' Draw the points on the arc
            Dim curSpace = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
            For Each point In points
                Dim point3d = New Point3d(point.X, point.Y, 0)
                Dim dbPoint = New DBPoint(point3d)

                curSpace.AppendEntity(dbPoint)
                tr.AddNewlyCreatedDBObject(dbPoint, True)
            Next

            tr.Commit()
        End Using
    End Sub

 

 

And here is the before and after, notice the exotic shape it makes if I attempt to use it on a very simple filleted polyline:

tristanjonas8XAAW_0-1682028788561.png

And here is what it would look like an earlier version i still have access to:

tristanjonas8XAAW_1-1682028845365.png

 

0 Likes
Reply
Accepted solutions (3)
1,721 Views
10 Replies
Replies (10)

tristan.jonas8XAAW
Advocate
Advocate

Hey all, I actually got it working relatively well, I'm just stuck at one part and I don't really know how to push forward here. I made a little test command called GRRR and it basically does what I wanted the code above to do, and it works when the arc in the polyline is padded between two lines, so in theory it should work. However when there are arcs on the start and end points it really scrambles it up.

Here is the before-and-after of what it looks like when I attempt to use it on polylines that have multiple arcs, and the code:

tristanjonas8XAAW_0-1682103255428.png

 



 

 <CommandMethod("GRRR")>
    Public Sub GRRR_Main()
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim db = doc.Database
        Dim ed = doc.Editor

        Dim filter = New SelectionFilter({New TypedValue(0, "LWPOLYLINE")})
        Dim selection = ed.GetSelection(filter)
        If selection.Status <> PromptStatus.OK Then Return

        If selection.Value.Count <> 1 Then
            ed.WriteMessage("Please select exactly one polyline." & vbCrLf)
            Return
        End If

        Using tr = db.TransactionManager.StartTransaction()
            Dim polylineObjectId = selection.Value.GetObjectIds()(0)
            ProcessPolylineWithArcs(tr, polylineObjectId)
            tr.Commit()
        End Using
    End Sub
    Private Function ProcessPolylineWithArcs(tr As Transaction, plineObjectId As ObjectId) As Polyline
        Dim inputPline As Polyline = CType(tr.GetObject(plineObjectId, OpenMode.ForRead), Polyline)
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim db = doc.Database
        ' Create a new polyline for the output
        Dim newPline As Polyline
        Using nestedTr = db.TransactionManager.StartTransaction()
            newPline = New Polyline()
            ' Rest of the code in the ProcessPolylineWithArcs function

            ' Add the new polyline to the current space
            Dim curSpace2 = CType(nestedTr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
            curSpace2.AppendEntity(newPline)
            nestedTr.AddNewlyCreatedDBObject(newPline, True)
            nestedTr.Commit()
        End Using


        Dim isClosed As Boolean = inputPline.Closed
        If isClosed Then
            inputPline.Closed = False
        End If



        ' Iterate through the polyline segments
        For index As Integer = 0 To inputPline.NumberOfVertices - 2
            Dim startPoint As Point2d = inputPline.GetPoint2dAt(index)
            Dim endPoint As Point2d
            doc.Editor.WriteMessage(vbCrLf & "Index: " & index & " SegmentType: " & inputPline.GetSegmentType(index).ToString())
            doc.Editor.WriteMessage(vbCrLf & "InputPline.NumberOfVertices: " & inputPline.NumberOfVertices)

            endPoint = inputPline.GetPoint2dAt(index + 1)

            Dim prevEndPoint As Point2d = Nothing
            If inputPline.GetSegmentType(index) = SegmentType.Arc Then
                Dim arcSegment As CircularArc2d = inputPline.GetArcSegment2dAt(index)

                ' Calculate absolute start and end angles
                Dim center As Point2d = arcSegment.Center
                Dim startAngle As Double = Math.Atan2(startPoint.Y - center.Y, startPoint.X - center.X)
                Dim endAngle As Double = Math.Atan2(endPoint.Y - center.Y, endPoint.X - center.X)

                If index = 0 AndAlso inputPline.NumberOfVertices > 2 Then
                    Dim nextPoint As Point2d = inputPline.GetPoint2dAt(index + 2)
                    If startPoint.GetDistanceTo(nextPoint) < endPoint.GetDistanceTo(nextPoint) Then
                        Dim temp = startAngle
                        startAngle = endAngle
                        endAngle = temp
                    End If
                ElseIf prevEndPoint <> Nothing AndAlso Not startPoint.IsEqualTo(prevEndPoint) AndAlso Not endPoint.IsEqualTo(prevEndPoint) Then
                    Dim temp = startAngle
                    startAngle = endAngle
                    endAngle = temp
                End If

                Dim arc As New Arc(New Point3d(center.X, center.Y, 0), arcSegment.Radius, startAngle, endAngle)

                ' Orient the arc correctly
                If inputPline.GetBulgeAt(index) < 0 Then
                    Dim temp = arc.StartAngle
                    arc.StartAngle = arc.EndAngle
                    arc.EndAngle = temp
                End If

                doc.Editor.WriteMessage(vbCrLf & "StartAngle: " & startAngle & " EndAngle: " & endAngle)
                Dim arcPoints As List(Of Point2d) = GenerateArcPoints(arc)
                doc.Editor.WriteMessage(vbCrLf & "Arc Points: " & String.Join(", ", arcPoints))


                For i As Integer = 0 To arcPoints.Count - 1
                    newPline.AddVertexAt(newPline.NumberOfVertices, arcPoints(i), 0, 0, 0)
                Next

                prevEndPoint = endPoint
                doc.Editor.WriteMessage(vbCrLf & "NewPline.NumberOfVertices: " & newPline.NumberOfVertices)

            Else
                ' Add line segment points to the new polyline
                If newPline.NumberOfVertices = 0 OrElse newPline.GetPoint2dAt(newPline.NumberOfVertices - 1) <> startPoint Then
                    newPline.AddVertexAt(newPline.NumberOfVertices, startPoint, 0, 0, 0)
                End If
                If index < inputPline.NumberOfVertices - 1 Then
                    newPline.AddVertexAt(newPline.NumberOfVertices, endPoint, 0, 0, 0)
                End If
                doc.Editor.WriteMessage(vbCrLf & "Line Start: " & startPoint.ToString() & " End: " & endPoint.ToString())

                prevEndPoint = endPoint
                doc.Editor.WriteMessage(vbCrLf & "NewPline.NumberOfVertices: " & newPline.NumberOfVertices)

            End If
        Next
        doc.Editor.WriteMessage(vbCrLf & "NewPline.NumberOfVertices: " & newPline.NumberOfVertices)

        ' Add the new polyline to the current space
        Dim plineClone As Polyline = newPline.Clone()
        Dim curSpace = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
        curSpace.AppendEntity(plineClone)
        tr.AddNewlyCreatedDBObject(plineClone, True)

        If isClosed Then
            newPline.Closed = True
        End If


        Return newPline


    End Function

    Public Function GenerateArcPoints(arc As Arc) As List(Of Point2d)
        Dim points As New List(Of Point2d)

        Dim startPoint As Point2d = New Point2d(arc.StartPoint.X, arc.StartPoint.Y)
        Dim endPoint As Point2d = New Point2d(arc.EndPoint.X, arc.EndPoint.Y)

        points.Add(startPoint)

        Dim interval As Double = 100.0
        Dim arcLength As Double = arc.Length
        Dim numIntervals As Integer = CInt(Math.Floor(arcLength / interval))

        ' Ensure that the end angle is greater than the start angle
        Dim endAngle As Double = arc.EndAngle
        If endAngle < arc.StartAngle Then
            endAngle += 2 * Math.PI
        End If

        ' Add a small tolerance to account for floating-point arithmetic
        Dim tolerance As Double = 0.0000000001
        If Math.Abs(endAngle - 2 * Math.PI) < tolerance Then
            endAngle -= tolerance
        End If

        For i As Integer = 1 To numIntervals + 1
            Dim angle = arc.StartAngle + (i * (endAngle - arc.StartAngle) / numIntervals)

            ' Ensure the angle stays within bounds
            If angle > endAngle Then
                angle = endAngle
            ElseIf angle < arc.StartAngle Then
                angle = arc.StartAngle
            End If

            ' Convert angle to point on the arc using center, radius, and angle
            Dim pointOnArc = New Point3d(arc.Center.X + arc.Radius * Math.Cos(angle), arc.Center.Y + arc.Radius * Math.Sin(angle), arc.Center.Z)
            Dim pointOnArc2d = New Point2d(pointOnArc.X, pointOnArc.Y)

            points.Add(pointOnArc2d)

            If angle = endAngle Then
                Exit For
            End If
        Next

        Return points
    End Function

 

 

edit: and for the record, I'm aware this is a lot to ask help for, but I want it to be known that if I can just get pointed in the right direction, like a link to what i'm looking for or the name of some method that would be useful, then that's literally all I need, I'm not asking anyone to write an ounce of code for me, to be VERY clear. I just feel like there's a discrepancy between regular arcs and arcs on a polyline and it's hard to make a script work with both but I can't put my finger on exactly what their difference is.

0 Likes

cuongtk2
Advocate
Advocate
Accepted solution

Maybe you should change your approach

 

Public Shared Function PlineToLinear(ByVal pline As Polyline, ByVal Optional interval As Double = 100) As Polyline
    Dim newpline As Polyline = New Polyline()
    Dim onum As Integer = pline.NumberOfVertices
    Dim plan As Plane = New Plane()

    For i As Integer = 0 To onum - 1
        Dim bulge = pline.GetBulgeAt(i)

        If bulge = 0 Or i = onum - 1 Then
            newpline.AddVertexAt(newpline.NumberOfVertices, pline.GetPoint2dAt(i), 0, 0, 0)
        Else
            Dim dist1 As Double = pline.GetDistanceAtParameter(i)
            Dim dist2 As Double = pline.GetDistanceAtParameter(i + 1)
            Dim arcseglength As Double = dist2 - dist1
            Dim num As Integer = CInt((arcseglength / interval))

            For j As Integer = 0 To num
                Dim pt As Point2d = pline.GetPointAtDist(dist1 + j * interval).Convert2d(plan)
                newpline.AddVertexAt(newpline.NumberOfVertices, pt, 0, 0, 0)
            Next
        End If
    Next

    Return newpline
End Function

 

0 Likes

tristan.jonas8XAAW
Advocate
Advocate

That's very good, that seemed to work really well on the first polyline with arc that I posted originally, but unfortunately when I click a polyline with an arc as the end segment this function unfortunately doesn't work. Once again I don't need any code written out I just need the right direction. My suspicion is that it has to do with possibly 2 things:

1. arcs at the beginning and or end of the polyline
2. arcs that cross over the 0 degree threshold, for example an arc where the start angle is 5 and the end angle is 355.
3. the 'rotation' of the angle, meaning depending on the bulge being positive or negative dictates which direction the rendering is applied, meaning if it's positive the end angle will always be greater than the start angle so from the start point it'll always move clockwise. if it's negative then from start to end it'll move counter clockwise.

Am I on the right track?

0 Likes

_gile
Consultant
Consultant
Accepted solution

Hi,

You should use the Polyline parameters (Curve.GetDistanceAtParameter and Curve.GetPointAtParameter)

Here's an example:

 

 

        static void ArcToSegments(Polyline pline, double intervalMax)
        {
            int numberOfSegments = pline.Closed ?
                pline.NumberOfVertices :
                pline.NumberOfVertices - 1;
            var plane = new Plane(Point3d.Origin, pline.Normal);
            for (int i = 0; i < numberOfSegments; i++)
            {
                if (pline.GetSegmentType(i) == SegmentType.Arc)
                {
                    var points = new Point2dCollection();
                    double param = pline.GetParameterAtPoint(pline.GetPoint3dAt(i));
                    double arcLength =
                        pline.GetDistanceAtParameter(param + 1.0) - pline.GetDistanceAtParameter(param);
                    int numIntervals = (int)Math.Ceiling(arcLength / intervalMax);
                    double increment = 1.0 / numIntervals;
                    for (int j = 1; j < numIntervals; j++)
                    {
                        points.Add(pline.GetPointAtParameter(i + j * increment).Convert2d(plane));
                    }
                    pline.SetBulgeAt(i, 0.0);
                    foreach (Point2d pt in points)
                    {
                        i++;
                        numberOfSegments++;
                        pline.AddVertexAt(i, pt, 0.0, 0.0, 0.0);
                    }
                }
            }
        }

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes

_gile
Consultant
Consultant
Accepted solution

My purpose is similar to @cuongtk2 .

Here's a testing command:

        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var options = new PromptEntityOptions("\nSelect Polyline: ");
            options.SetRejectMessage("\nMust be a Polyline.");
            options.AddAllowedClass(typeof(Polyline), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK) return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var pline = (Polyline)tr.GetObject(result.ObjectId, OpenMode.ForRead);
                if (pline.HasBulges)
                {
                    tr.GetObject(result.ObjectId, OpenMode.ForWrite);
                    ArcToSegments(pline, 100.0);
                }
                tr.Commit();
            }
        }

Arc_to_segments.mp4
Video Player is loading.
Current Time 0:00
Duration 0:46
Loaded: 21.55%
Stream Type LIVE
Remaining Time 0:46
 
1x
    • Chapters
    • descriptions off, selected
    • captions off, selected
    • en (Main), selected
    (view in My Videos)



    Gilles Chanteau
    Programmation AutoCAD LISP/.NET
    GileCAD
    GitHub

    0 Likes

    tristan.jonas8XAAW
    Advocate
    Advocate

    Ok Gile I converted it to .NET and made a tweak and it works like a charm. I'll post the final version and explained what I had to change and why:

     <CommandMethod("TEST")>
            Public Shared Sub Test()
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim db As Database = doc.Database
                Dim ed As Editor = doc.Editor
                Dim options As New PromptEntityOptions(vbLf & "Select Polyline: ")
                options.SetRejectMessage(vbLf & "Must be a Polyline.")
                options.AddAllowedClass(GetType(Polyline), True)
                Dim result As PromptEntityResult = ed.GetEntity(options)
    
                If result.Status <> PromptStatus.OK Then Return
    
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    Dim pline As Polyline = CType(tr.GetObject(result.ObjectId, OpenMode.ForRead), Polyline)
    
                    If pline.HasBulges Then
                        tr.GetObject(result.ObjectId, OpenMode.ForWrite)
                        ArcToSegments(pline, 100.0)
                    End If
    
                    tr.Commit()
                End Using
            End Sub
    
            Private Shared Sub ArcToSegments(ByVal pline As Polyline, ByVal intervalMax As Double)
                Dim numberOfSegments As Integer = If(pline.Closed, pline.NumberOfVertices, pline.NumberOfVertices - 1)
                Dim plane As New Plane(Point3d.Origin, pline.Normal)
                Dim i As Integer = 0
    
                While i < numberOfSegments
                    If pline.GetSegmentType(i) = SegmentType.Arc Then
                        Dim points As New Point2dCollection()
                        Dim param As Double = pline.GetParameterAtPoint(pline.GetPoint3dAt(i))
                        Dim arcLength As Double = pline.GetDistanceAtParameter(param + 1.0) - pline.GetDistanceAtParameter(param)
                        Dim numIntervals As Integer = CInt(Math.Ceiling(arcLength / intervalMax))
                        Dim increment As Double = 1.0 / numIntervals
    
                        For j As Integer = 1 To numIntervals - 1
                            points.Add(pline.GetPointAtParameter(param + j * increment).Convert2d(plane))
                        Next
    
                        pline.SetBulgeAt(i, 0.0)
    
                        For Each pt As Point2d In points
                            i += 1
                            numberOfSegments += 1
                            pline.AddVertexAt(i, pt, 0.0, 0.0, 0.0)
                        Next
                    End If
                    i += 1
                End While
            End Sub


    So when I converted the code and originally tested it it worked very close, the only thing was that when I clicked an object with polylines it would redraw the first arc in the polyline according to my specifications but it would redraw every subsequent arc as arcs, not as the staggered polyline I wanted. I noticed though if I rand the test on it again, it would fix the next arc but leave the one after it again. So it seemed like something may have been going on with the loop.

    I replaced the "For i As Integer = 0 To numberOfSegments - 1" loop with a "While i < numberOfSegments" loop, so that the "i" counter can be incremented within the loop itself. After that it seemed to work in all use cases. Bravo, thank you both for your help.

    0 Likes

    _gile
    Consultant
    Consultant

    This is a difference in behavior between C# and VB with the "for" statement. In C#, the limit condition of the loop is evaluated at each iteration. In VB.NET, it is only evaluated at the loop entry.



    Gilles Chanteau
    Programmation AutoCAD LISP/.NET
    GileCAD
    GitHub

    tristan.jonas8XAAW
    Advocate
    Advocate

    I hate to be a bother but this is the last finish line I need to cross and it's eternally done, once again nobody has to write me code, it's appreciated but I know it's effort and the right direction is all I need.

    The basic idea of the functions I wrote is, one of the parameters for ProcessPolylineWithArcs is pointsOnOtherPolylines which is a list of endpoints that may or may not fall on one of the arcs we're iterating through, and if one of those points ends up being the case, we want to insert that vertex in between the most sensible consecutive points on the arc in the polyline supplied by the polylineId. It was working perfectly but adding the new points may have broken it. It was iterating cleanly before but now it seems to "skip" now:




     

     

    Private Function ProcessPolylineWithArcs(ByVal tr As Transaction, ByVal polylineId As ObjectId) As ObjectId
            Dim pline As Polyline = CType(tr.GetObject(polylineId, OpenMode.ForRead), Polyline)
            Dim updatedPline As Polyline = CType(pline.Clone(), Polyline)
    
            If pline.HasBulges Then
                ArcToSegments(updatedPline, 100.0)
            End If
    
            Dim curSpace As BlockTableRecord = CType(tr.GetObject(pline.Database.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
            curSpace.AppendEntity(updatedPline)
            tr.AddNewlyCreatedDBObject(updatedPline, True)
    
            Return updatedPline.ObjectId
        End Function
    
    
    
        Private Shared Sub ArcToSegments(ByVal pline As Polyline, ByVal intervalMax As Double)
            Dim numberOfSegments As Integer = If(pline.Closed, pline.NumberOfVertices, pline.NumberOfVertices - 1)
            Dim plane As New Plane(Point3d.Origin, pline.Normal)
            Dim i As Integer = 0
            While i < numberOfSegments
                If pline.GetSegmentType(i) = SegmentType.Arc Then
                    Dim points As New Point2dCollection()
                    Dim param As Double = pline.GetParameterAtPoint(pline.GetPoint3dAt(i))
                    Dim arcLength As Double = pline.GetDistanceAtParameter(param + 1.0) - pline.GetDistanceAtParameter(param)
                    Dim numIntervals As Integer = CInt(Math.Ceiling(arcLength / intervalMax))
                    Dim increment As Double = 1.0 / numIntervals
    
                    For j As Integer = 1 To numIntervals - 1
                        points.Add(pline.GetPointAtParameter(param + j * increment).Convert2d(plane))
                    Next
                    pline.SetBulgeAt(i, 0.0)
    
                    For Each pt As Point2d In points
                        i += 1
                        numberOfSegments += 1
                        pline.AddVertexAt(i, pt, 0.0, 0.0, 0.0)
                    Next
                End If
                i += 1
            End While
        End Sub
    
        Private Function PointOnOtherPolylineAndNotEndpoint(point As Point3d, polylineObjectId As ObjectId, selectedPolylineIds As List(Of ObjectId)) As Boolean
            For Each objectId As ObjectId In selectedPolylineIds
                If objectId <> polylineObjectId Then
                    Using tr = polylineObjectId.Database.TransactionManager.StartTransaction()
                        Dim otherPline As Polyline = CType(tr.GetObject(objectId, OpenMode.ForRead), Polyline)
    
                        ' Check if the point is on the polyline
                        If IsPointOnCurveGCP(otherPline, point) Then
                            ' Check if the point is not an endpoint of the polyline
                            If Not point.IsEqualTo(otherPline.StartPoint, Tolerance.Global) AndAlso
                        Not point.IsEqualTo(otherPline.EndPoint, Tolerance.Global) Then
                                Return True
                            End If
                        End If
                    End Using
                End If
            Next
            Return False
        End Function
    
        Private Function IsPointOnCurveGCP(ByVal curve As Curve, ByVal point As Point3d) As Boolean
            Dim param As Double
            Dim closestPoint As Point3d = curve.GetClosestPointTo(point, param)
    
            Return closestPoint.IsEqualTo(point, Tolerance.Global)
        End Function

     

     

     

    I also got a working version of the concept to function below but for the life of me I cannot get it to translate to the above code.




     

     

    <CommandMethod("AddPointToArcPline")>
        Public Sub AddPointToArcPline()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
    
            Dim peo As New PromptEntityOptions(vbLf & "Select polyline containing an arc: ")
            peo.SetRejectMessage("Selected entity is not a polyline.")
            peo.AddAllowedClass(GetType(Polyline), True)
            Dim per As PromptEntityResult = ed.GetEntity(peo)
    
            If per.Status <> PromptStatus.OK Then
                Return
            End If
    
            Dim ppr As PromptPointResult = ed.GetPoint(vbLf & "Select a point on the entity: ")
    
            If ppr.Status <> PromptStatus.OK Then
                Return
            End If
    
            Dim pickedPoint As Point3d = ppr.Value
    
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim pline As Polyline = tr.GetObject(per.ObjectId, OpenMode.ForWrite)
                Dim newPline As Polyline = PlineToLinear2(pline, pickedPoint, 100)
                pline.Erase()
    
                Dim bt As BlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead)
                Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
                btr.AppendEntity(newPline)
                tr.AddNewlyCreatedDBObject(newPline, True)
    
                tr.Commit()
            End Using
        End Sub
    
    
    
    
        Public Shared Function PlineToLinear2(ByVal pline As Polyline, ByVal pickedPoint As Point3d, ByVal Optional interval As Double = 100) As Polyline
    
            Dim newPline As Polyline = New Polyline()
            Dim onum As Integer = pline.NumberOfVertices
            Dim plan As Plane = New Plane()
    
            For i As Integer = 0 To onum - 1
                Dim bulge = pline.GetBulgeAt(i)
    
                If bulge = 0 Or i = onum - 1 Then
                    newPline.AddVertexAt(newPline.NumberOfVertices, pline.GetPoint2dAt(i), 0, 0, 0)
                Else
                    Dim dist1 As Double = pline.GetDistanceAtParameter(i)
                    Dim dist2 As Double = pline.GetDistanceAtParameter(i + 1)
                    Dim arcseglength As Double = dist2 - dist1
                    Dim num As Integer = CInt((arcseglength / interval))
                    Dim pickedPointInserted As Boolean = False
    
                    For j As Integer = 0 To num
                        Dim currentDist As Double = Math.Min(dist1 + j * interval, pline.Length)
                        Dim pt As Point2d = pline.GetPointAtDist(currentDist).Convert2d(plan)
                        Dim nextDist As Double = Math.Min(dist1 + (j + 1) * interval, pline.Length)
                        Dim nextPt As Point2d = pline.GetPointAtDist(nextDist).Convert2d(plan)
    
                        newPline.AddVertexAt(newPline.NumberOfVertices, pt, 0, 0, 0)
    
                        If Not pickedPointInserted AndAlso IsPointBetween(pickedPoint.Convert2d(plan), pt, nextPt) Then
                            newPline.AddVertexAt(newPline.NumberOfVertices, pickedPoint.Convert2d(plan), 0, 0, 0)
                            pickedPointInserted = True
                        End If
                    Next
    
                End If
            Next
            Return newPline
        End Function
    
        Public Shared Function IsPointBetween(testPoint As Point2d, startPoint As Point2d, endPoint As Point2d) As Boolean
            Dim vec1 As Vector2d = testPoint - startPoint
            Dim vec2 As Vector2d = endPoint - startPoint
    
            ' Check if the test point is in the same direction as the endPoint relative to the startPoint
            If vec1.DotProduct(vec2) < 0 Then
                Return False
            End If
    
            ' Check if the test point is closer to the startPoint than the endPoint is
            If vec1.Length > vec2.Length Then
                Return False
            End If
    
            Return True
        End Function


    Lastly I'm sorry if this is code overload but I'm trying to be thorough, here's the main command, basically you click the entities and press enter and it will draw 6 offset lines that meld pretty nicely into one another. But yes here is the main code, the portion above is for writing the 'skeleton' of what will be artificially lengthened and offset and connected together into said lines:



        <CommandMethod("BRDRS")>
        Public Sub BRDRS_Main()
    
            Dim layerName As String = "MVIEW"
    
            If Not LayerExists(layerName) Then
                Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Error: Layer """ & layerName & """ does not exist." & vbCrLf)
                Return
            End If
    
            Dim doc = Application.DocumentManager.MdiActiveDocument
            Dim db = doc.Database
            Dim ed = doc.Editor
    
            Dim filter = New SelectionFilter({New TypedValue(0, "ARC,LINE,LWPOLYLINE")})
            Dim selection = ed.GetSelection(filter)
            If selection.Status <> PromptStatus.OK Then Return
    
            Dim baseOffsetDistance As Double = 100.0
            Dim numOffsets As Integer = 6
            Dim offsetStep As Double = 50.0
    
            Using tr = db.TransactionManager.StartTransaction()
                Dim curSpace = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
    
                Dim polylineIds As New List(Of ObjectId)()
    
                Dim pointsOnOtherPolylines As New List(Of Point3d)()
                Dim overlappingEndpoints As New List(Of Point3d)()
    
                For Each objectId In selection.Value.GetObjectIds()
                    Dim entity As Entity = tr.GetObject(objectId, OpenMode.ForRead)
                    Dim pline As Polyline
    
                    If TypeOf entity Is Line OrElse TypeOf entity Is Arc Then
                        pline = ConvertToPolyline(CType(entity, Curve))
                    Else
                        pline = CType(entity, Polyline)
                    End If
    
                    ' Process the polyline with the new function by determind whether or not the polyline selected has an arc inside it
                    Dim hasArc As Boolean = False
    
                    Dim otherPolylineEndpoints As New List(Of Point3d)()
    
                    For Each otherObjectId In polylineIds
                        If objectId <> otherObjectId Then
                            Dim otherPline As Polyline = tr.GetObject(otherObjectId, OpenMode.ForRead)
                            otherPolylineEndpoints.Add(otherPline.StartPoint)
                            otherPolylineEndpoints.Add(otherPline.EndPoint)
                        End If
                    Next
    
                    For index As Integer = 0 To pline.NumberOfVertices - 2
                        If pline.GetSegmentType(index) = SegmentType.Arc Then
                            hasArc = True
                            Exit For
                        End If
                    Next
    
                    If hasArc Then
                        For Each otherEndpoint In otherPolylineEndpoints
                            If pline.IsPointOnPolyline(otherEndpoint) AndAlso Not IsEndpoint(otherEndpoint, pline) Then
                                pointsOnOtherPolylines.Add(otherEndpoint)
                            End If
                        Next
                    End If
    
                    ' Check if the endpoints have the same coordinates as another polyline's endpoint
                    For Each otherObjectId In polylineIds
                        If objectId <> otherObjectId Then
                            Dim otherPline As Polyline = tr.GetObject(otherObjectId, OpenMode.ForRead)
    
                            If pline.StartPoint.IsEqualTo(otherPline.StartPoint, Tolerance.Global) OrElse
                pline.StartPoint.IsEqualTo(otherPline.EndPoint, Tolerance.Global) Then
                                overlappingEndpoints.Add(pline.StartPoint)
                            End If
    
                            If pline.EndPoint.IsEqualTo(otherPline.StartPoint, Tolerance.Global) OrElse
                pline.EndPoint.IsEqualTo(otherPline.EndPoint, Tolerance.Global) Then
                                overlappingEndpoints.Add(pline.EndPoint)
                            End If
                        End If
                    Next
    
                    ' Print the lists of coordinates
                    For Each point In pointsOnOtherPolylines
                        ed.WriteMessage(vbLf & "Endpoint on another polyline:  {0}", point.ToString())
                    Next
    
                    For Each point In overlappingEndpoints
                        ed.WriteMessage(vbLf & "Overlapping endpoint:  {0}", point.ToString())
                    Next
    
                    Dim processedPlineId As ObjectId
                    If hasArc Then
                        processedPlineId = ProcessPolylineWithArcs(tr, pline.ObjectId)
                    Else
                        processedPlineId = pline.ObjectId
                    End If
                    polylineIds.Add(processedPlineId)
    
                Next
    
                Dim polylineIntersections As New Dictionary(Of ObjectId, List(Of Point3d))()
    
                For Each objectId In polylineIds
                    Dim pline As Polyline = tr.GetObject(objectId, OpenMode.ForRead)
                    Dim otherEndpoints = FindIntersections(pline, polylineIds.ToArray())
                    polylineIntersections.Add(objectId, otherEndpoints)
                Next
    
                For i = 0 To numOffsets - 1
                    Dim offsetDistance = baseOffsetDistance + (i * offsetStep)
                    Dim region = polylineIds.Select(Function(id) CType(tr.GetObject(id, OpenMode.ForRead), Polyline)).Select(Function(originalPline)
                                                                                                                                 Dim cleanedPoints = GetCleanedPointsFromPolyline(originalPline)
                                                                                                                                 Dim newPline As New Polyline()
                                                                                                                                 For index As Integer = 0 To cleanedPoints.Count - 1
                                                                                                                                     newPline.AddVertexAt(index, cleanedPoints(index), 0, 0, 0)
                                                                                                                                 Next
    
                                                                                                                                 Dim otherCurvesEndpoints = polylineIntersections(originalPline.ObjectId)
                                                                                                                                 Dim extendedPline = ExtendCurve(newPline, offsetDistance, otherCurvesEndpoints)
    
                                                                                                                                 Return CreateRegionFromCurves(CreateBoundary(extendedPline, offsetDistance))
                                                                                                                             End Function).Aggregate(Function(r1, r2)
                                                                                                                                                         r1.BooleanOperation(BooleanOperationType.BoolUnite, r2)
                                                                                                                                                         r2.Dispose()
                                                                                                                                                         Return r1
                                                                                                                                                     End Function)
    
                    Dim pline = RegionToPolyline(region)
    
                    curSpace.AppendEntity(pline)
                    tr.AddNewlyCreatedDBObject(pline, True)
                Next
    
                tr.Commit()
            End Using
        End Sub





     

     




    0 Likes

    cuongtk2
    Advocate
    Advocate

    Sorry I can't communicate in English. I can only express through c# code how to do it.

    0 Likes

    tristan.jonas8XAAW
    Advocate
    Advocate

    Sorry, didn't mean to make it sound like you aren't allowed to use code, you may if that's your preference 🙂

    0 Likes

    Type a product name

    ______
    icon-svg-close-thick

    Cookie preferences

    Your privacy is important to us and so is an optimal experience. To help us customize information and build applications, we collect data about your use of this site.

    May we collect and use your data?

    Learn more about the Third Party Services we use and our Privacy Statement.

    Strictly necessary – required for our site to work and to provide services to you

    These cookies allow us to record your preferences or login information, respond to your requests or fulfill items in your shopping cart.

    Improve your experience – allows us to show you what is relevant to you

    These cookies enable us to provide enhanced functionality and personalization. They may be set by us or by third party providers whose services we use to deliver information and experiences tailored to you. If you do not allow these cookies, some or all of these services may not be available for you.

    Customize your advertising – permits us to offer targeted advertising to you

    These cookies collect data about you based on your activities and interests in order to show you relevant ads and to track effectiveness. By collecting this data, the ads you see will be more tailored to your interests. If you do not allow these cookies, you will experience less targeted advertising.

    icon-svg-close-thick

    THIRD PARTY SERVICES

    Learn more about the Third-Party Services we use in each category, and how we use the data we collect from you online.

    icon-svg-hide-thick

    icon-svg-show-thick

    Strictly necessary – required for our site to work and to provide services to you

    Qualtrics
    We use Qualtrics to let you give us feedback via surveys or online forms. You may be randomly selected to participate in a survey, or you can actively decide to give us feedback. We collect data to better understand what actions you took before filling out a survey. This helps us troubleshoot issues you may have experienced. Qualtrics Privacy Policy
    Akamai mPulse
    We use Akamai mPulse to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Akamai mPulse Privacy Policy
    Digital River
    We use Digital River to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Digital River Privacy Policy
    Dynatrace
    We use Dynatrace to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Dynatrace Privacy Policy
    Khoros
    We use Khoros to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Khoros Privacy Policy
    Launch Darkly
    We use Launch Darkly to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Launch Darkly Privacy Policy
    New Relic
    We use New Relic to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. New Relic Privacy Policy
    Salesforce Live Agent
    We use Salesforce Live Agent to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Salesforce Live Agent Privacy Policy
    Wistia
    We use Wistia to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Wistia Privacy Policy
    Tealium
    We use Tealium to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Tealium Privacy Policy
    Upsellit
    We use Upsellit to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Upsellit Privacy Policy
    CJ Affiliates
    We use CJ Affiliates to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. CJ Affiliates Privacy Policy
    Commission Factory
    We use Commission Factory to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Commission Factory Privacy Policy
    Google Analytics (Strictly Necessary)
    We use Google Analytics (Strictly Necessary) to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Google Analytics (Strictly Necessary) Privacy Policy
    Typepad Stats
    We use Typepad Stats to collect data about your behaviour on our sites. This may include pages you’ve visited. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our platform to provide the most relevant content. This allows us to enhance your overall user experience. Typepad Stats Privacy Policy
    Geo Targetly
    We use Geo Targetly to direct website visitors to the most appropriate web page and/or serve tailored content based on their location. Geo Targetly uses the IP address of a website visitor to determine the approximate location of the visitor’s device. This helps ensure that the visitor views content in their (most likely) local language.Geo Targetly Privacy Policy
    SpeedCurve
    We use SpeedCurve to monitor and measure the performance of your website experience by measuring web page load times as well as the responsiveness of subsequent elements such as images, scripts, and text.SpeedCurve Privacy Policy
    Qualified
    Qualified is the Autodesk Live Chat agent platform. This platform provides services to allow our customers to communicate in real-time with Autodesk support. We may collect unique ID for specific browser sessions during a chat. Qualified Privacy Policy

    icon-svg-hide-thick

    icon-svg-show-thick

    Improve your experience – allows us to show you what is relevant to you

    Google Optimize
    We use Google Optimize to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Google Optimize Privacy Policy
    ClickTale
    We use ClickTale to better understand where you may encounter difficulties with our sites. We use session recording to help us see how you interact with our sites, including any elements on our pages. Your Personally Identifiable Information is masked and is not collected. ClickTale Privacy Policy
    OneSignal
    We use OneSignal to deploy digital advertising on sites supported by OneSignal. Ads are based on both OneSignal data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that OneSignal has collected from you. We use the data that we provide to OneSignal to better customize your digital advertising experience and present you with more relevant ads. OneSignal Privacy Policy
    Optimizely
    We use Optimizely to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Optimizely Privacy Policy
    Amplitude
    We use Amplitude to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Amplitude Privacy Policy
    Snowplow
    We use Snowplow to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Snowplow Privacy Policy
    UserVoice
    We use UserVoice to collect data about your behaviour on our sites. This may include pages you’ve visited. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our platform to provide the most relevant content. This allows us to enhance your overall user experience. UserVoice Privacy Policy
    Clearbit
    Clearbit allows real-time data enrichment to provide a personalized and relevant experience to our customers. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID.Clearbit Privacy Policy
    YouTube
    YouTube is a video sharing platform which allows users to view and share embedded videos on our websites. YouTube provides viewership metrics on video performance. YouTube Privacy Policy

    icon-svg-hide-thick

    icon-svg-show-thick

    Customize your advertising – permits us to offer targeted advertising to you

    Adobe Analytics
    We use Adobe Analytics to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Adobe Analytics Privacy Policy
    Google Analytics (Web Analytics)
    We use Google Analytics (Web Analytics) to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Google Analytics (Web Analytics) Privacy Policy
    AdWords
    We use AdWords to deploy digital advertising on sites supported by AdWords. Ads are based on both AdWords data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that AdWords has collected from you. We use the data that we provide to AdWords to better customize your digital advertising experience and present you with more relevant ads. AdWords Privacy Policy
    Marketo
    We use Marketo to send you more timely and relevant email content. To do this, we collect data about your online behavior and your interaction with the emails we send. Data collected may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, email open rates, links clicked, and others. We may combine this data with data collected from other sources to offer you improved sales or customer service experiences, as well as more relevant content based on advanced analytics processing. Marketo Privacy Policy
    Doubleclick
    We use Doubleclick to deploy digital advertising on sites supported by Doubleclick. Ads are based on both Doubleclick data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Doubleclick has collected from you. We use the data that we provide to Doubleclick to better customize your digital advertising experience and present you with more relevant ads. Doubleclick Privacy Policy
    HubSpot
    We use HubSpot to send you more timely and relevant email content. To do this, we collect data about your online behavior and your interaction with the emails we send. Data collected may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, email open rates, links clicked, and others. HubSpot Privacy Policy
    Twitter
    We use Twitter to deploy digital advertising on sites supported by Twitter. Ads are based on both Twitter data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Twitter has collected from you. We use the data that we provide to Twitter to better customize your digital advertising experience and present you with more relevant ads. Twitter Privacy Policy
    Facebook
    We use Facebook to deploy digital advertising on sites supported by Facebook. Ads are based on both Facebook data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Facebook has collected from you. We use the data that we provide to Facebook to better customize your digital advertising experience and present you with more relevant ads. Facebook Privacy Policy
    LinkedIn
    We use LinkedIn to deploy digital advertising on sites supported by LinkedIn. Ads are based on both LinkedIn data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that LinkedIn has collected from you. We use the data that we provide to LinkedIn to better customize your digital advertising experience and present you with more relevant ads. LinkedIn Privacy Policy
    Yahoo! Japan
    We use Yahoo! Japan to deploy digital advertising on sites supported by Yahoo! Japan. Ads are based on both Yahoo! Japan data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Yahoo! Japan has collected from you. We use the data that we provide to Yahoo! Japan to better customize your digital advertising experience and present you with more relevant ads. Yahoo! Japan Privacy Policy
    Naver
    We use Naver to deploy digital advertising on sites supported by Naver. Ads are based on both Naver data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Naver has collected from you. We use the data that we provide to Naver to better customize your digital advertising experience and present you with more relevant ads. Naver Privacy Policy
    Quantcast
    We use Quantcast to deploy digital advertising on sites supported by Quantcast. Ads are based on both Quantcast data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Quantcast has collected from you. We use the data that we provide to Quantcast to better customize your digital advertising experience and present you with more relevant ads. Quantcast Privacy Policy
    Call Tracking
    We use Call Tracking to provide customized phone numbers for our campaigns. This gives you faster access to our agents and helps us more accurately evaluate our performance. We may collect data about your behavior on our sites based on the phone number provided. Call Tracking Privacy Policy
    Wunderkind
    We use Wunderkind to deploy digital advertising on sites supported by Wunderkind. Ads are based on both Wunderkind data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Wunderkind has collected from you. We use the data that we provide to Wunderkind to better customize your digital advertising experience and present you with more relevant ads. Wunderkind Privacy Policy
    ADC Media
    We use ADC Media to deploy digital advertising on sites supported by ADC Media. Ads are based on both ADC Media data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that ADC Media has collected from you. We use the data that we provide to ADC Media to better customize your digital advertising experience and present you with more relevant ads. ADC Media Privacy Policy
    AgrantSEM
    We use AgrantSEM to deploy digital advertising on sites supported by AgrantSEM. Ads are based on both AgrantSEM data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that AgrantSEM has collected from you. We use the data that we provide to AgrantSEM to better customize your digital advertising experience and present you with more relevant ads. AgrantSEM Privacy Policy
    Bidtellect
    We use Bidtellect to deploy digital advertising on sites supported by Bidtellect. Ads are based on both Bidtellect data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Bidtellect has collected from you. We use the data that we provide to Bidtellect to better customize your digital advertising experience and present you with more relevant ads. Bidtellect Privacy Policy
    Bing
    We use Bing to deploy digital advertising on sites supported by Bing. Ads are based on both Bing data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Bing has collected from you. We use the data that we provide to Bing to better customize your digital advertising experience and present you with more relevant ads. Bing Privacy Policy
    G2Crowd
    We use G2Crowd to deploy digital advertising on sites supported by G2Crowd. Ads are based on both G2Crowd data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that G2Crowd has collected from you. We use the data that we provide to G2Crowd to better customize your digital advertising experience and present you with more relevant ads. G2Crowd Privacy Policy
    NMPI Display
    We use NMPI Display to deploy digital advertising on sites supported by NMPI Display. Ads are based on both NMPI Display data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that NMPI Display has collected from you. We use the data that we provide to NMPI Display to better customize your digital advertising experience and present you with more relevant ads. NMPI Display Privacy Policy
    VK
    We use VK to deploy digital advertising on sites supported by VK. Ads are based on both VK data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that VK has collected from you. We use the data that we provide to VK to better customize your digital advertising experience and present you with more relevant ads. VK Privacy Policy
    Adobe Target
    We use Adobe Target to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Adobe Target Privacy Policy
    Google Analytics (Advertising)
    We use Google Analytics (Advertising) to deploy digital advertising on sites supported by Google Analytics (Advertising). Ads are based on both Google Analytics (Advertising) data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Google Analytics (Advertising) has collected from you. We use the data that we provide to Google Analytics (Advertising) to better customize your digital advertising experience and present you with more relevant ads. Google Analytics (Advertising) Privacy Policy
    Trendkite
    We use Trendkite to deploy digital advertising on sites supported by Trendkite. Ads are based on both Trendkite data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Trendkite has collected from you. We use the data that we provide to Trendkite to better customize your digital advertising experience and present you with more relevant ads. Trendkite Privacy Policy
    Hotjar
    We use Hotjar to deploy digital advertising on sites supported by Hotjar. Ads are based on both Hotjar data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Hotjar has collected from you. We use the data that we provide to Hotjar to better customize your digital advertising experience and present you with more relevant ads. Hotjar Privacy Policy
    6 Sense
    We use 6 Sense to deploy digital advertising on sites supported by 6 Sense. Ads are based on both 6 Sense data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that 6 Sense has collected from you. We use the data that we provide to 6 Sense to better customize your digital advertising experience and present you with more relevant ads. 6 Sense Privacy Policy
    Terminus
    We use Terminus to deploy digital advertising on sites supported by Terminus. Ads are based on both Terminus data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Terminus has collected from you. We use the data that we provide to Terminus to better customize your digital advertising experience and present you with more relevant ads. Terminus Privacy Policy
    StackAdapt
    We use StackAdapt to deploy digital advertising on sites supported by StackAdapt. Ads are based on both StackAdapt data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that StackAdapt has collected from you. We use the data that we provide to StackAdapt to better customize your digital advertising experience and present you with more relevant ads. StackAdapt Privacy Policy
    The Trade Desk
    We use The Trade Desk to deploy digital advertising on sites supported by The Trade Desk. Ads are based on both The Trade Desk data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that The Trade Desk has collected from you. We use the data that we provide to The Trade Desk to better customize your digital advertising experience and present you with more relevant ads. The Trade Desk Privacy Policy
    RollWorks
    We use RollWorks to deploy digital advertising on sites supported by RollWorks. Ads are based on both RollWorks data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that RollWorks has collected from you. We use the data that we provide to RollWorks to better customize your digital advertising experience and present you with more relevant ads. RollWorks Privacy Policy

    Are you sure you want a less customized experience?

    We can access your data only if you select "yes" for the categories on the previous screen. This lets us tailor our marketing so that it's more relevant for you. You can change your settings at any time by visiting our privacy statement

    Your experience. Your choice.

    We care about your privacy. The data we collect helps us understand how you use our products, what information you might be interested in, and what we can improve to make your engagement with Autodesk more rewarding.

    May we collect and use your data to tailor your experience?

    Explore the benefits of a customized experience by managing your privacy settings for this site or visit our Privacy Statement to learn more about your options.