VB .net Line to Polyline

VB .net Line to Polyline

Anonymous
Not applicable
7,052 Views
12 Replies
Message 1 of 13

VB .net Line to Polyline

Anonymous
Not applicable

I am trying to convert a Line / Arc into a Polyline, and then join them to others:

The problem is in this line of code:

 

NPoli.ConvertFrom(oEnt, False)

I want to convert a line or Arc to Polyline but all the examples I've seen, this code converts polyline 2D, and I do not want that.
How do I convert an arc or line into polyline?

 

       <CommandMethod("UneLine")>
    Public Sub UneLine()
        Dim acTypValAr(4) As TypedValue
        acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<or"), 0)
        acTypValAr.SetValue(New TypedValue(DxfCode.Start, "LINE"), 1)
        acTypValAr.SetValue(New TypedValue(DxfCode.Start, "LWPOLYLINE"), 2)
        acTypValAr.SetValue(New TypedValue(DxfCode.Start, "Arc"), 3)
        acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "or>"), 4)
        Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr)
        Dim acSSPrompt As PromptSelectionResult = acDocEd.GetSelection(acSelFtr)
        If acSSPrompt.Status = PromptStatus.Cancel Then Exit Sub
        Dim acSSet As SelectionSet = acSSPrompt.Value
        Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
            Dim NPoli As Polyline = New Polyline()
            For Each oSel As SelectedObject In acSSet
                Dim oEnt As Entity = TryCast(acTrans.GetObject(oSel.ObjectId, OpenMode.ForWrite, True), Entity)
                If NPoli.NumberOfVertices = 0 Then
                    NPoli.ConvertFrom(oEnt, False) ''Not Fount
                Else
                    NPoli.JoinEntity(oEnt)
                    oEnt.Erase()
                End If
            Next
            acTrans.Commit()
        End Using
    End Sub
0 Likes
Accepted solutions (2)
7,053 Views
12 Replies
Replies (12)
Message 2 of 13

ActivistInvestor
Mentor
Mentor
Accepted solution

See if this works (sorry, I don't speak VB, so you'll need to convert it):

 

/// Pass a database-resident line or arc to this method, and it will 
/// return a new Polyline, which you must add to a database or dispose.

public static Polyline ConvertToPolyline(Curve curve)
{
   if(!(curve is Line || curve is Arc))
      throw new ArgumentException("requires a Line or Arc");
   Polyline pline = new Polyline();
   pline.TransformBy(curve.Ecs);
   Point3d start = curve.StartPoint.TransformBy(pline.Ecs.Inverse());
   pline.AddVertexAt(0, new Point2d(start.X, start.Y), 0, 0, 0);
   pline.JoinEntity(curve);
   return pline;
}
0 Likes
Message 3 of 13

Anonymous
Not applicable

Hi, I have not programmed in VB for years and C# I do not know.
I only want convert a Line in a Polyline, Referring to the code I do not know that does .ecs:

Pline.TransformBy (curve.Ecs);  
''This Transforms the line / or Arc into polyline? Is Curve Entity, Line or Arc?

The rest is to prioritize the vertices?

I Change my code for:
NPoli.TransformBy(oEnt.Ecs)

Now it does not give error like before, but it does not make the line

0 Likes
Message 4 of 13

ActivistInvestor
Mentor
Mentor

The method I posted takes either a Line or an Arc, and returns a new Polyline that is identical to the Line/Arc.

 

Call the method, and pass it the Line or the Arc, and it returns the Polyline.  

 

You can use online translators that can translate the code to VB.NET.

 

If you don't understand what the code does, look up the methods it uses in the documentation.

0 Likes
Message 5 of 13

Anonymous
Not applicable

Hi!
I originally looked for the command equivalent to "_Pedit" function that has Autocad. Thus it would absorb all its properties Color layer etc.
The problem with your code is that it don't  know convert from C # to VB. I have tried with this code. But it still gives me error

 

 

 

    Function ConvertToPolyline(ByVal LineArc As Entity) As Polyline
        If LineArc.ObjectId.ObjectClass().DxfName = "LINE" Or LineArc.ObjectId.ObjectClass().DxfName = "Arc" Then
            Dim Pline As Polyline = New Polyline()
            Pline.TransformBy(LineArc.Ecs)
            Dim start As Point3d = Pline.StartPoint.TransformBy(Pline.Ecs.Inverse())
            Pline.AddVertexAt(0, New Point2d(start.X, start.Y), 0, 0, 0)
            Pline.JoinEntity(LineArc)
            Return Pline
        End If
    End Function

Thank you very much.

0 Likes
Message 6 of 13

kerry_w_brown
Advisor
Advisor
Accepted solution

 


Activist_Investor wrote:

See if this works (sorry, I don't speak VB, so you'll need to convert it):

 

/// Pass a database-resident line or arc to this method, and it will 
/// return a new Polyline, which you must add to a database or dispose.

public static Polyline ConvertToPolyline(Curve curve)
{
   if(!(curve is Line || curve is Arc))
      throw new ArgumentException("requires a Line or Arc");
   Polyline pline = new Polyline();
   pline.TransformBy(curve.Ecs);
   Point3d start = curve.StartPoint.TransformBy(pline.Ecs.Inverse());
   pline.AddVertexAt(0, new Point2d(start.X, start.Y), 0, 0, 0);
   pline.JoinEntity(curve);
   return pline;
}

 

 

 

 


phoeloes wrote:


The problem with your code is that it don't  know convert from C # to VB. 

 

 

 

 

http://lmgtfy.com/?q=C%23+convert+to+VB

 

''' Pass a database-resident line or arc to this method, and it will 
''' return a new Polyline, which you must add to a database or dispose.

Public Shared Function ConvertToPolyline(curve As Curve) As Polyline
	If Not (TypeOf curve Is Line OrElse TypeOf curve Is Arc) Then
		Throw New ArgumentException("requires a Line or Arc")
	End If
	Dim pline As New Polyline()
	pline.TransformBy(curve.Ecs)
	Dim start As Point3d = curve.StartPoint.TransformBy(pline.Ecs.Inverse())
	pline.AddVertexAt(0, New Point2d(start.X, start.Y), 0, 0, 0)
	pline.JoinEntity(curve)
	Return pline
End Function

'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik
'Facebook: facebook.com/telerik
'=======================================================

 

 I don't do VB : all care , no responsibility.

 Regards,

 



 

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 7 of 13

Anonymous
Not applicable

I'm  Draftsman and I understand how valuable:
Line, Arc, Polyline, Insert, ect or Entity - An element of cad.
But I do not know what kind of element is Curve.

Another thing is that it seems strange to me that there is not any type of command : Pline.convert (line)

Autocad has "_Pedit", I would save, match all properties color, layer, etc.

 

Well, the case now with the new code, if that works!
Thank you all

0 Likes
Message 8 of 13

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

Hi!

The problem with your code is that it don't  know convert from C # to VB. I have tried with this code. But it still gives me error

 

 

 

 

There's no problem with the code. The problem is that you don't really have very much experience with AutoCAD development using .NET, and don't know that you must add the returned Polyline to the database and model space block using BlockTableRecord.AppendEntity(), and you must also add it to the Transaction using the Transaction.AddNewlyCreatedDBObject() method.

 

Also, if you really want help from others, "but it still gives me error" isn't going to cut it. You have to be specific and say exactly what the error is, with a screenshot if necessary, because "error" is basically saying nothing.

 

If you read the comments above the code I posted again, you note that it says that the returned Polyline must be added to a database or disposed. Your original code added nothing to the database, so it shouldn't be too much of a surprise that it doesn't work.

 

Unless/until you've gained a reasonable level of experience with AutoCAD development, you should probably not try to cherry-pick bits and pieces out of code examples others post here, and try to integrate them into your code.

 

I'll agree that something that does what you seek should be part of the API, but that's unfortunately not the case. ObjectARX is not a high-level scripting API that makes things easy. It's very powerful and equally complicated.

 

The easiest solution to the problem is to simply script the PEDIT command using the Editor's Command() method:

 

 

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

ObjectId lineOrArcId = /// assign to the objectid of a line or arc
ed.Command("._PEDIT", lineOrArcId, "Y", "");

 

And you're done.

 

 

 

0 Likes
Message 9 of 13

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

I'm  Draftsman and I understand how valuable:
Line, Arc, Polyline, Insert, ect or Entity - An element of cad.
But I do not know what kind of element is Curve.

Another thing is that it seems strange to me that there is not any type of command : Pline.convert (line)

Autocad has "_Pedit", I would save, match all properties color, layer, etc.

 

Well, the case now with the new code, if that works!
Thank you all


The code I showed and @kerry_w_brown kindly translated is not a complete solution, and knowing that you would have to struggle to reach one using it, here is a more-complete solution (again, in C#). It also handles arcs/lines that aren't in the WCS XY plane (the previous code doesn't do that).

 

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

using AcRx = Autodesk.AutoCAD.Runtime;

namespace ConvertToPolyline
{
   public static class ConvertToPolylineCommands
   {
      /// <summary>
      /// Replaces a selected Line or Arc with an equivalent Polyline.
      /// The polyline that replaces the Line or Arc inherits the
      /// handle, application data, and common properties of the
      /// Line or Arc.
      /// </summary>
      
      [CommandMethod("CVPOLY")]
      public static void ConvertToPolyLineCommand()
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         PromptEntityOptions peo = new PromptEntityOptions("\nSelect a Line or Arc: ");
         peo.SetRejectMessage("\nInvalid input, requires a Line or Arc,\n");
         peo.AddAllowedClass(typeof(Line), false);
         peo.AddAllowedClass(typeof(Arc), false);
         peo.AllowObjectOnLockedLayer = false;
         var per = doc.Editor.GetEntity(peo);
         if(per.Status != PromptStatus.OK)
            return;
         ObjectId curveId = per.ObjectId;
         using(var trans = doc.TransactionManager.StartOpenCloseTransaction())
         {
            Curve curve = (Curve) trans.GetObject(curveId, OpenMode.ForRead);
            try
            {
               curve.ReplaceWithPolyline(trans);
               trans.Commit();
            }
            catch(System.Exception ex)
            {
               doc.Editor.WriteMessage(ex.ToString());
            }
         }

      }
   }
}

namespace Autodesk.AutoCAD.DatabaseServices
{
   public static class ConvertToPolylineExtensions
   {
      /// <summary>
      /// Replaces the given database-resident Line or Arc 
      /// with an equivalent polyline
      /// </summary>
      
      public static Polyline ReplaceWithPolyline(this Curve curve, OpenCloseTransaction trans)
      {
         return Convert(curve, trans);
      }

      /// <summary>
      /// Creates a new Polyline that is equivalent to the given 
      /// Line or Arc. 
      /// 
      /// The resulting Polyline is not database-resident and 
      /// must be disposed or added to a database.
      /// </summary>
      
      public static Polyline ConvertToPolyline(this Curve curve)
      {
         return ReplaceWithPolyline(curve, null);
      }

      /// <summary>
      /// Creates a Polyline that is equivalent to a given Arc or Line,
      /// and optionally replaces the Arc or Line with the Polyline in
      /// the Database where the Arc or Line resides.
      /// </summary>
      /// <remarks>The curve argument must be a Line or Arc. If the curve
      /// argument is database-resident and the second transaction argument 
      /// is provided, the curve MUST be opened via that transaction. 
      /// 
      /// If the curve argument is database-resident and a transaction is
      /// provided, the new Polyline will replace the curve in the database
      /// and inherit the common entity properties, handle, and application 
      /// data of the curve. The curve argument will no longer be usable 
      /// upon return. If the curve argument is not database-resident, the 
      /// resulting polyline will not be database-resident and <em>must</em> 
      /// be disposed or added to a database. The curve argument will be 
      /// unchanged and still be usable.
      /// </remarks>
      /// <param name="curve">The Line or Arc to convert/replace</param>
      /// <param name="trans">The OpenCloseTransaction which the database-
      /// resident curve was obtained from.</param>
      /// <returns>The Polyline equivalent of the given curve</returns>

      static Polyline Convert(Curve curve, OpenCloseTransaction trans = null)
      {
         if(curve == null)
            throw new ArgumentNullException("curve");
         if(!(curve is Line || curve is Arc))
            ErrorStatus.WrongObjectType.Throw("requires a Line or Arc");
         if(curve.IsTransactionResident)
            ErrorStatus.InvalidInput.Throw("curve must be from an OpenCloseTransaction");
         Polyline pline = new Polyline(1);
         try
         {
            var start = curve.StartPoint.TransformBy(curve.Ecs.Inverse());
            if(curve is Arc)
               pline.TransformBy(curve.Ecs);
            pline.Elevation = start.Z;
            pline.Thickness = curve.GetThickness();
            pline.AddVertexAt(0, new Point2d(start.X, start.Y), 0, 0, 0);
            pline.JoinEntity(curve);
            pline.SetPropertiesFrom(curve);
            if(curve.Database != null && trans != null)
            {
               if(!curve.IsWriteEnabled)
                  curve.UpgradeOpen();
               curve.HandOverTo(pline, true, true);
               trans.AddNewlyCreatedDBObject(pline, true);
               trans.AddNewlyCreatedDBObject(curve, false);
               curve.Dispose();
            }
            return pline;
         }
         catch
         {
            pline.Dispose();
            throw;
         }
      }

      public static void Throw(this AcRx.ErrorStatus es, string message = null)
      {
         throw new AcRx.Exception(es, message);
      }

      public static double GetThickness(this Curve curve)
      {
         Line line = curve as Line;
         return line != null ? line.Thickness : ((Arc) curve).Thickness;
      }
   }
}

0 Likes
Message 10 of 13

ActivistInvestor
Mentor
Mentor

See the comments in the code...

 

 

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

using AcRx = Autodesk.AutoCAD.Runtime;

namespace ConvertToPolyline
{
   public static class ConvertToPolylineCommands
   {
      /// <summary>
      /// Replaces a selected Line or Arc with an equivalent Polyline.
      /// The polyline that replaces the Line or Arc inherits the
      /// handle, application data, and common properties of the
      /// Line or Arc.
      /// </summary>
      
      [CommandMethod("CVPOLY")]
      public static void ConvertToPolyLineCommand()
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         PromptEntityOptions peo = new PromptEntityOptions("\nSelect a Line or Arc: ");
         peo.SetRejectMessage("\nInvalid input, requires a Line or Arc,\n");
         peo.AddAllowedClass(typeof(Line), false);
         peo.AddAllowedClass(typeof(Arc), false);
         peo.AllowObjectOnLockedLayer = false;
         var per = doc.Editor.GetEntity(peo);
         if(per.Status != PromptStatus.OK)
            return;
         using(var trans = doc.TransactionManager.StartOpenCloseTransaction())
         {
            Curve curve = (Curve) trans.GetObject(per.ObjectId, OpenMode.ForRead);
            try
            {
               curve.ReplaceWithPolyline(trans);
               trans.Commit();
            }
            catch(System.Exception ex)
            {
               doc.Editor.WriteMessage(ex.ToString());
            }
         }
      }
   }
}

namespace Autodesk.AutoCAD.DatabaseServices
{
   public static class ConvertToPolylineExtensions
   {
      /// <summary>
      /// Replaces the given database-resident Line or Arc 
      /// with an equivalent polyline
      /// </summary>
      
      public static Polyline ReplaceWithPolyline(this Curve curve, OpenCloseTransaction trans)
      {
         return Convert(curve, trans);
      }

      /// <summary>
      /// Creates a new Polyline that is equivalent to the given 
      /// Line or Arc. 
      /// 
      /// The resulting Polyline is not database-resident and 
      /// must be disposed or added to a database.
      /// </summary>
      
      public static Polyline ConvertToPolyline(this Curve curve)
      {
         return Convert(curve, null);
      }

      /// <summary>
      /// Creates a Polyline that is equivalent to a given Arc or Line,
      /// and optionally replaces the Arc or Line with the Polyline in
      /// the Database where the Arc or Line resides.
      /// </summary>
      /// <remarks>The curve argument must be a Line or Arc. If the curve
      /// argument is database-resident and the second transaction argument 
      /// is provided, the curve MUST be opened via that transaction. 
      /// 
      /// If the curve argument is database-resident and a transaction is
      /// provided, the new Polyline will replace the curve in the database
      /// and inherit the common entity properties, handle, and application 
      /// data of the curve. The curve argument will no longer be usable 
      /// upon return. If the curve argument is not database-resident, the 
      /// resulting polyline will not be database-resident and <em>must</em> 
      /// be disposed or added to a database. The curve argument will be 
      /// unchanged and remain usable.
      /// </remarks>
      /// <param name="curve">The Line or Arc to convert/replace</param>
      /// <param name="trans">The OpenCloseTransaction which the database-
      /// resident curve was obtained from.</param>
      /// <returns>The Polyline equivalent of the given curve</returns>

      static Polyline Convert(Curve curve, OpenCloseTransaction trans = null)
      {
         if(curve == null)
            throw new ArgumentNullException("curve");
         if(!(curve is Line || curve is Arc))
            ErrorStatus.WrongObjectType.Throw("requires a Line or Arc");
         if(curve.IsTransactionResident)
            ErrorStatus.InvalidInput.Throw("curve must be from an OpenCloseTransaction");
         Polyline pline = new Polyline(1);
         try
         {
            Line line = null;
            if(curve is Arc)
            {
               pline.Normal = ((Arc) curve).Normal;
            }
            else
            {
               line = (Line) curve;

               /// Special case: Lines that are not perpendicular to
               /// their normal/extrusion direction are handled in a 
               /// peculiar way by PEDIT. I haven't had the time to 
               /// reverse-engineer it fully, but it seems that PEDIT 
               /// simply takes the line as a vector and rotates it 
               /// 90 degrees (Vector3d.GetPerpendicularVector()), 
               /// and uses that as the polyline's normal, which is
               /// not the same as the line's extrusion direction, 
               /// and which produces seemingly-odd behavior that's
               /// only obvious if the Line has a non-zero thickness.
               /// 
               /// Drawing a line in the WCS with endpoints that are
               /// at different elevations, and giving it a non-zero
               /// thickness will reveal what PEDIT does in cases like
               /// this (not what a user might expect).
               /// 
               /// Unfortunately, JoinEntity() does not like lines that
               /// have a non-perpendicular extrusion direction/normal, 
               /// and as such, can't be used to convert such a line into 
               /// a polyline. So, just compute the normal and add both
               /// the start and end vertices, thereby avoiding the use 
               /// of JoinEntity() entirely.
               /// 
               /// This iteraton should more-closely emulate the PEDIT 
               /// command's behavior (the initial intent of this code) 
               /// when an arc or line is selected:

               Vector3d normal = line.Normal;
               Vector3d vec = line.StartPoint.GetVectorTo(line.EndPoint);
               if(!vec.IsPerpendicularTo(normal))
                  normal = vec.GetPerpendicularVector();
               pline.Normal = normal;
            }
            pline.Elevation = curve.StartPoint.TransformBy(curve.Ecs.Inverse()).Z;
            pline.Thickness = curve.GetThickness();
            Plane plane = pline.GetPlane();
            Point2d vertex1 = curve.StartPoint.Convert2d(plane);
            Point2d vertex2 = curve.EndPoint.Convert2d(plane);
            pline.AddVertexAt(0, vertex1, 0, 0, 0);
            if(line != null)
               pline.AddVertexAt(1, vertex2, 0, 0, 0);
            else
               pline.JoinEntity(curve);
            pline.SetPropertiesFrom(curve);
            if(curve.Database != null && trans != null)
            {
               if(!curve.IsWriteEnabled)
                  curve.UpgradeOpen();
               curve.HandOverTo(pline, true, true);
               trans.AddNewlyCreatedDBObject(pline, true);
               trans.AddNewlyCreatedDBObject(curve, false);
               curve.Dispose();
            }
            return pline;
         }
         catch
         {
            pline.Dispose();
            throw;
         }
      }

      public static void Throw(this AcRx.ErrorStatus es, string message = null)
      {
         throw new AcRx.Exception(es, message);
      }

      public static double GetThickness(this Curve curve)
      {
         Line line = curve as Line;
         return line != null ? line.Thickness : ((Arc) curve).Thickness;
      }
   }
}

 

0 Likes
Message 11 of 13

ActivistInvestor
Mentor
Mentor

@Activist_Investor wrote:

See the comments in the code...

 

 


I broke the above code while cleaning it up to post.

 

This one comes with a limited 30 day money-back guarantee.

 

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

using AcRx = Autodesk.AutoCAD.Runtime;

namespace ConvertToPolyline
{
   public static class ConvertToPolylineCommands
   {
      /// <summary>
      /// Replaces a selected Line or Arc with an equivalent Polyline.
      /// The polyline that replaces the Line or Arc inherits the
      /// handle, application data, and common properties of the
      /// Line or Arc.
      /// </summary>

      [CommandMethod("CVPOLY")]
      public static void ConvertToPolyLineCommand()
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         PromptEntityOptions peo = new PromptEntityOptions("\nSelect a Line or Arc: ");
         peo.SetRejectMessage("\nInvalid input, requires a Line or Arc,\n");
         peo.AddAllowedClass(typeof(Line), false);
         peo.AddAllowedClass(typeof(Arc), false);
         peo.AllowObjectOnLockedLayer = false;
         var per = doc.Editor.GetEntity(peo);
         if(per.Status != PromptStatus.OK)
            return;
         using(var trans = doc.TransactionManager.StartOpenCloseTransaction())
         {
            Curve curve = (Curve) trans.GetObject(per.ObjectId, OpenMode.ForRead);
            try
            {
               curve.ReplaceWithPolyline(trans);
               trans.Commit();
            }
            catch(System.Exception ex)
            {
               doc.Editor.WriteMessage(ex.ToString());
            }
         }
      }
   }
}

namespace Autodesk.AutoCAD.DatabaseServices
{
   public static class ConvertToPolylineExtensions
   {
      /// <summary>
      /// Replaces the given database-resident Line or Arc 
      /// with an equivalent polyline
      /// </summary>

      public static Polyline ReplaceWithPolyline(this Curve curve, OpenCloseTransaction trans)
      {
         return Convert(curve, trans);
      }

      /// <summary>
      /// Creates a new Polyline that is equivalent to the given 
      /// Line or Arc. 
      /// 
      /// The resulting Polyline is not database-resident and 
      /// must be disposed or added to a database.
      /// </summary>

      public static Polyline ConvertToPolyline(this Curve curve)
      {
         return Convert(curve);
      }

      /// <summary>
      /// Creates a Polyline that is equivalent to a given Arc or Line,
      /// and optionally replaces the Arc or Line with the Polyline in
      /// the Database where the Arc or Line resides.
      /// </summary>
      /// <remarks>The curve argument must be a Line or Arc. If the curve
      /// argument is database-resident and the second transaction argument 
      /// is provided, the curve MUST be opened via that transaction. 
      /// 
      /// If the curve argument is database-resident and a transaction is
      /// provided, the new Polyline will replace the curve in the database
      /// and inherit the common entity properties, handle, and application 
      /// data of the curve. The curve argument will no longer be usable 
      /// upon return. If the curve argument is not database-resident, the 
      /// resulting polyline will not be database-resident and <em>must</em> 
      /// be disposed or added to a database. The curve argument will be 
      /// unchanged and remain usable.
      /// </remarks>
      /// <param name="curve">The Line or Arc to convert/replace</param>
      /// <param name="trans">The OpenCloseTransaction which the database-
      /// resident curve was obtained from.</param>
      /// <returns>The Polyline equivalent of the given curve</returns>

      static Polyline Convert(Curve curve, OpenCloseTransaction trans = null)
      {
         if(curve == null)
            throw new ArgumentNullException("curve");
         if(!(curve is Line || curve is Arc))
            ErrorStatus.WrongObjectType.Throw("requires a Line or Arc");
         if(curve.IsTransactionResident)
            ErrorStatus.InvalidInput.Throw("curve must be from an OpenCloseTransaction");
         Polyline pline = new Polyline(1);
         try
         {
            Line line = null;
            Arc arc = curve as Arc;
            if(arc != null)
            {
               pline.Thickness = arc.Thickness;
               pline.Normal = arc.Normal;
            }
            else
            {
               line = (Line) curve;
               pline.Thickness = line.Thickness;

               /// Special case: Lines that are not perpendicular to
               /// their normal/extrusion direction are handled in a 
               /// peculiar way by PEDIT. I haven't had the time to 
               /// reverse-engineer it fully, but it seems that PEDIT 
               /// simply takes the line as a vector and rotates it 
               /// 90 degrees (Vector3d.GetPerpendicularVector()), 
               /// and uses that as the polyline's normal, which is
               /// not the same as the line's extrusion direction, 
               /// which produces seemingly-odd behavior that is only
               /// obvious if the Line has a non-zero thickness.
               /// 
               /// Drawing a line in the WCS with endpoints that are
               /// at different elevations, and giving it a non-zero
               /// thickness will reveal what PEDIT does in cases like
               /// this (not what a user might expect).
               /// 
               /// Unfortunately, JoinEntity() does not like lines that
               /// have a non-perpendicular extrusion vector/normal, and
               /// as such, can't be used to convert any such line into 
               /// a polyline. So, just compute the normal and add both
               /// the start and end vertices, thereby avoiding the use 
               /// of JoinEntity() entirely.
               /// 
               /// This iteraton should more-closely emulate the PEDIT 
               /// command's behavior (the initial intent of this code) 
               /// when an arc or line is selected:

               Vector3d normal = line.Normal;
               Vector3d vector = line.StartPoint.GetVectorTo(line.EndPoint);
               if(!vector.IsPerpendicularTo(normal))
                  normal = vector.GetPerpendicularVector();
               pline.Normal = normal;
            }
            Point3d startPoint = curve.StartPoint.TransformBy(pline.Ecs.Inverse());
            Point3d endPoint = curve.EndPoint.TransformBy(pline.Ecs.Inverse());
            pline.Elevation = startPoint.Z;
            pline.AddVertexAt(0, new Point2d(startPoint.X, startPoint.Y), 0, 0, 0);
            if(line != null)
               pline.AddVertexAt(1, new Point2d(endPoint.X, endPoint.Y), 0, 0, 0);
            else
               pline.JoinEntity(curve);
            pline.SetPropertiesFrom(curve);
            if(curve.Database != null && trans != null)
            {
               if(!curve.IsWriteEnabled)
                  curve.UpgradeOpen();
               curve.HandOverTo(pline, true, true);
               trans.AddNewlyCreatedDBObject(pline, true);
               trans.AddNewlyCreatedDBObject(curve, false);
               curve.Dispose();
            }
            return pline;
         }
         catch
         {
            pline.Dispose();
            throw;
         }
      }

      public static void Throw(this AcRx.ErrorStatus es, string message = null)
      {
         throw new AcRx.Exception(es, message);
      }
   }
}

 

Message 12 of 13

fieldguy
Advisor
Advisor

>>This one comes with a limited 30 day money-back guarantee.<<

 

I thought the standard was 30 minutes.

0 Likes
Message 13 of 13

ActivistInvestor
Mentor
Mentor

@fieldguy wrote:

>>This one comes with a limited 30 day money-back guarantee.<<

 

I thought the standard was 30 minutes.


Are you a Trump University alumni ?

0 Likes