Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - fixo

Pages: 1 2 [3] 4 5 ... 9
32
Text / Create Mtext using Notepad for input string (A2010)
« on: March 04, 2013, 10:00:47 AM »
     C#
Code: [Select]
        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("acad.exe", EntryPoint = "acedCmd", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        extern static private int acedCmd(IntPtr resbuf);
        //-----------------------------------------------------------//
        // AutoCAD 2010 (eng.)
        [CommandMethod("mtx")]
        public void createMtext()
        {
            Clipboard.Clear();
            Document doc = doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;
            Database db = doc.Database;
            Transaction tr = db.TransactionManager.StartTransaction();
            Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Add then \"Cut\" text from Notepad");
            System.Threading.Thread.Sleep(500);

            ResultBuffer rb = new ResultBuffer();

            rb.Add(new TypedValue((int)LispDataType.Text, "_startapp"));
            rb.Add(new TypedValue((int)LispDataType.Text, "notepad"));
            rb.Add(new TypedValue((int)LispDataType.Text, ""));// open Unnamed.txt
            rb.Add(new TypedValue((int)LispDataType.Text, "\n"));
            acedCmd(rb.UnmanagedObject);
            ed.Regen();
            using (tr)
            {   
                Point3d pt = ed.GetPoint("\nPick mtext location: ").Value;
                MText mtx = new MText();
                mtx.Location = pt;
                mtx.SetDatabaseDefaults();
                mtx.TextStyleId = db.Textstyle;// current text size
                mtx.TextHeight = db.Dimtxt;// current textstyle
                mtx.Width = 0.0;
                mtx.Contents = Clipboard.GetText();// paste mtext contents from clipboard
                // set alignment wharever you need:
                mtx.Attachment = AttachmentPoint.BottomCenter;
                mtx.SetAttachmentMovingLocation(mtx.Attachment);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(mtx);
                tr.AddNewlyCreatedDBObject(mtx, true);
                mtx.Width = mtx.ActualWidth;
                tr.Commit();
            }
           // Clipboard.Clear();// optional, if you won't use it then
        }

   VB.NET

   
Code: [Select]
  <System.Security.SuppressUnmanagedCodeSecurity()> _
<DllImport("acad.exe", EntryPoint:="acedCmd", CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Cdecl)> _
        Private Shared Function acedCmd(resbuf As IntPtr) As Integer
        End Function
        '-----------------------------------------------------------//
        ' AutoCAD 2010 (32bit eng.) Win7
        <CommandMethod("mtx")> _
        Public Sub createMtext()
            System.Windows.Clipboard.Clear()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Add then ""Cut"" text from Notepad")
            System.Threading.Thread.Sleep(500)

            Dim rb As New ResultBuffer()

            rb.Add(New TypedValue(CInt(LispDataType.Text), "_startapp"))
            rb.Add(New TypedValue(CInt(LispDataType.Text), "notepad"))
            rb.Add(New TypedValue(CInt(LispDataType.Text), ""))
            ' open file Unnamed.txt:
            rb.Add(New TypedValue(CInt(LispDataType.Text), vbLf))
            acedCmd(rb.UnmanagedObject)
            ed.Regen()
            Using tr
                Dim pt As Point3d = ed.GetPoint(vbLf & "Pick mtext location: ").Value
                Dim mtx As New MText()
                mtx.Location = pt
                mtx.SetDatabaseDefaults()
                mtx.TextStyleId = db.Textstyle
                ' current text size
                mtx.TextHeight = db.Dimtxt
                ' current textstyle
                mtx.Width = 0.0
                ' paste mtext contents from clipboard
                mtx.Contents = System.Windows.Clipboard.GetText()
                ' set alignment wharever you need:
                mtx.Attachment = AttachmentPoint.BottomCenter
                mtx.SetAttachmentMovingLocation(mtx.Attachment)
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                btr.AppendEntity(mtx)
                tr.AddNewlyCreatedDBObject(mtx, True)
                mtx.Width = mtx.ActualWidth
                tr.Commit()
            End Using
            ' System.Windows.Clipboard.Clear();'' optional, if you won't use it then
        End Sub

33
Text / Copy mtext to new location
« on: March 03, 2013, 03:09:42 PM »
      Reliable way to check every user input, the result should displayed
      in the command line after the command will end 


     C#

Code: [Select]
        [CommandMethod("AMMC", CommandFlags.UsePickSet)]     // copy mtext to new location
        public void testPlaceMtextBetween()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            Entity ent;
            bool isok = true;
            Transaction tr = db.TransactionManager.StartTransaction();
           
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);
                try
                {
            PromptPointOptions ppo = new PromptPointOptions("\nLeft Point: ");
            PromptPointResult ppr = ed.GetPoint(ppo);
            Point3d p1 = ppr.Value;
            if (ppr.Status != PromptStatus.OK)
            {
                isok = false;
                return;
            }
            ppo = new PromptPointOptions("\nRight point: ");
            ppo.UseBasePoint = true;
            ppo.BasePoint = p1;
            PromptPointResult pcr = ed.GetPoint(ppo);
            if (pcr.Status != PromptStatus.OK)
            {
                isok = false;
                return;
            }
            Point3d p2 = pcr.Value;
            if (p1.X == p2.X || p1.Y == p2.Y)
            {
                ed.WriteMessage("\nInvalid coordinate specification");
                isok = false;
                return;
            }
            Point3d mp = new Point3d((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, (p1.Z + p2.Z) / 2).TransformBy(Matrix3d.Identity);
            PromptSelectionOptions pso = new PromptSelectionOptions();
            pso.MessageForRemoval = "\nNot a mtext object, exit.";
            pso.MessageForAdding = "\nPick a single MText: ";
            pso.SingleOnly = true;
            pso.SinglePickInSpace = true;
             pso.PrepareOptionalDetails = true;

            SelectionFilter filter = new SelectionFilter(new TypedValue[] { new TypedValue(0, "mtext") });
            PromptSelectionResult res = ed.GetSelection(pso, filter);
            SelectionSet sset = res.Value;
            if (sset.Count == 0) return;

           
                    SelectedObject sobj = res.Value[0];

                    if (!sobj.ObjectId.IsValid) return;

                    ent = (Entity)tr.GetObject(sobj.ObjectId, OpenMode.ForRead);

                    if (ent is MText)
                    {
                        ent.UpgradeOpen();
                        Plane plan = new Plane(Point3d.Origin, Vector3d.ZAxis);
                        MText mtxt = ent as MText;
                        Point3d ip = mtxt.Location.TransformBy(Matrix3d.Identity);

                        Entity clonen = (Entity)ent.Clone();
                        MText clon = (MText)clonen as MText;
                        if (clon == null) return;
                        if (!clon.IsWriteEnabled) clon.UpgradeOpen();
                        Matrix3d mx = Matrix3d.Displacement(mp.GetVectorTo(ip));
                        clon.TransformBy(mx);
                        clon.Rotation = 0.0;
                        double ang = p1.GetVectorTo(p2).AngleOnPlane(plan);
                        // justify mtext to be more readable
                        if ((ang > Math.PI / 2) && (ang < Math.PI * 1.5))
                            ang = ang + Math.PI;
                        mx = Matrix3d.Rotation(p1.GetVectorTo(p2).AngleOnPlane(plan), Vector3d.ZAxis, mp);
                        clon.TransformBy(mx);
                        clon.Location = mp;
                        clon.Attachment = AttachmentPoint.MiddleCenter;
                        clon.SetAttachmentMovingLocation(clon.Attachment);
                        PromptKeywordOptions pko = new PromptKeywordOptions
                            ("\nSave old text or create new one instead? " + "[Old/New]: ", "Old New");
                        pko.AllowNone = true;
                        // The default depends on our current settings
                        pko.Keywords.Default = "Old";
                        PromptResult pr = ed.GetKeywords(pko);
                        if (pr.Status != PromptStatus.OK) return;
                        if (pr.StringResult == "New")
                        {

                            PromptStringOptions psto =
                                 new PromptStringOptions("\nEnter text (use \\P to jump next line): ");
                            psto.AllowSpaces = true;
                           
                            PromptResult stres = ed.GetString(psto);
                            if (stres.Status != PromptStatus.OK)   return;
                            string cont = stres.StringResult;
                            if (string.IsNullOrEmpty(cont))
                            {
                                isok = false;
                                return;
                            }
                            else
                            clon.Contents = cont;
                        }
                        else
                        clon.Contents = mtxt.Contents;
                        clon.Width = clon.ActualWidth;
                        clon.Height = clon.ActualHeight;
                        btr.UpgradeOpen();
                        btr.AppendEntity(clon);
                        tr.AddNewlyCreatedDBObject(clon, true);

                        tr.Commit();
                        isok = true;
                    }
                }
                catch (System.Exception ex)
                {
                    isok = false;
                    ed.WriteMessage(ex.Message);
                    tr.Abort();
                }
                finally
                {
                    string result = isok == true ? "success" : "fail";
                    Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage
                        ("\n\t---\tCommand is ended up with result of {0}.  \t---\n",result);
                    tr.Dispose();
                }
            }

 VB.NET

 
Code: [Select]
      ' copy mtext to new location
        <CommandMethod("AMMC", CommandFlags.UsePickSet)> _
        Public Sub testPlaceMtextBetween()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim ent As Entity
            Dim isok As Boolean = True
            Dim tr As Transaction = db.TransactionManager.StartTransaction()

            Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead), BlockTableRecord)
            Try
                Dim ppo As New PromptPointOptions(vbLf & "Left Point: ")
                Dim ppr As PromptPointResult = ed.GetPoint(ppo)
                Dim p1 As Point3d = ppr.Value
                If ppr.Status <> PromptStatus.OK Then
                    isok = False
                    Return
                End If
                ppo = New PromptPointOptions(vbLf & "Right point: ")
                ppo.UseBasePoint = True
                ppo.BasePoint = p1
                Dim pcr As PromptPointResult = ed.GetPoint(ppo)
                If pcr.Status <> PromptStatus.OK Then
                    isok = False
                    Return
                End If
                Dim p2 As Point3d = pcr.Value
                If p1.X = p2.X OrElse p1.Y = p2.Y Then
                    ed.WriteMessage(vbLf & "Invalid coordinate specification")
                    isok = False
                    Return
                End If
                Dim mp As Point3d = New Point3d((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2, (p1.Z + p2.Z) / 2).TransformBy(Matrix3d.Identity)
                Dim pso As New PromptSelectionOptions()
                pso.MessageForRemoval = vbLf & "Not a mtext object, exit."
                pso.MessageForAdding = vbLf & "Pick a single MText: "
                pso.SingleOnly = True
                pso.SinglePickInSpace = True
                pso.PrepareOptionalDetails = True

                Dim filter As New SelectionFilter(New TypedValue() {New TypedValue(0, "mtext")})
                Dim res As PromptSelectionResult = ed.GetSelection(pso, filter)
                Dim sset As SelectionSet = res.Value
                If sset.Count = 0 Then
                    Return
                End If


                Dim sobj As SelectedObject = res.Value(0)

                If Not sobj.ObjectId.IsValid Then
                    Return
                End If

                ent = DirectCast(tr.GetObject(sobj.ObjectId, OpenMode.ForRead), Entity)

                If TypeOf ent Is MText Then
                    ent.UpgradeOpen()
                    Dim plan As New Plane(Point3d.Origin, Vector3d.ZAxis)
                    Dim mtxt As MText = TryCast(ent, MText)
                    Dim ip As Point3d = mtxt.Location.TransformBy(Matrix3d.Identity)

                    Dim clonen As Entity = DirectCast(ent.Clone(), Entity)
                    Dim clon As MText = TryCast(DirectCast(clonen, MText), MText)
                    If clon Is Nothing Then
                        Return
                    End If
                    If Not clon.IsWriteEnabled Then
                        clon.UpgradeOpen()
                    End If
                    Dim mx As Matrix3d = Matrix3d.Displacement(mp.GetVectorTo(ip))
                    clon.TransformBy(mx)
                    clon.Rotation = 0.0
                    Dim ang As Double = p1.GetVectorTo(p2).AngleOnPlane(plan)
                    ' justify mtext to be more readable
                    If (ang > Math.PI / 2) AndAlso (ang < Math.PI * 1.5) Then
                        ang = ang + Math.PI
                    End If
                    mx = Matrix3d.Rotation(p1.GetVectorTo(p2).AngleOnPlane(plan), Vector3d.ZAxis, mp)
                    clon.TransformBy(mx)
                    clon.Location = mp
                    clon.Attachment = AttachmentPoint.MiddleCenter
                    clon.SetAttachmentMovingLocation(clon.Attachment)
                    Dim pko As New PromptKeywordOptions(vbLf & "Save old text or create new one instead? " & "[Old/New]: ", "Old New")
                    pko.AllowNone = True
                    ' The default depends on our current settings
                    pko.Keywords.[Default] = "Old"
                    Dim pr As PromptResult = ed.GetKeywords(pko)
                    If pr.Status <> PromptStatus.OK Then
                        Return
                    End If
                    If pr.StringResult = "New" Then

                        Dim psto As New PromptStringOptions(vbLf & "Enter text (use \P to jump next line): ")
                        psto.AllowSpaces = True

                        Dim stres As PromptResult = ed.GetString(psto)
                        If stres.Status <> PromptStatus.OK Then
                            Return
                        End If
                        Dim cont As String = stres.StringResult
                        If String.IsNullOrEmpty(cont) Then
                            isok = False
                            Return
                        Else
                            clon.Contents = cont
                        End If
                    Else
                        clon.Contents = mtxt.Contents
                    End If
                    clon.Width = clon.ActualWidth
                    clon.Height = clon.ActualHeight
                    btr.UpgradeOpen()
                    btr.AppendEntity(clon)
                    tr.AddNewlyCreatedDBObject(clon, True)

                    tr.Commit()
                    isok = True
                End If
            Catch ex As System.Exception
                isok = False
                ed.WriteMessage(ex.Message)
                tr.Abort()
            Finally
                Dim result As String = If(isok = True, "success", "fail")
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & vbTab & "---" & vbTab & "Command is ended up with result of {0}.  " & vbTab & "---" & vbLf, result)
                tr.Dispose()
            End Try
        End Sub

34
Layers / Work on locked layers sample
« on: February 28, 2013, 08:42:56 PM »
 
Code: [Select]
       [CommandMethod("WorkWithLockedLayers","wlock", CommandFlags.UsePickSet | CommandFlags.Redraw)]
        public void testWorkOnLockedLayers()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            bool fine = true;
            ObjectIdCollection locked = new ObjectIdCollection();
            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);

                    foreach (ObjectId ltId in lt)
                    {
                        if (ltId.IsValid && ltId.IsResident && !ltId.IsErased) // just drawing layers were allowed
                        {
                            LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(ltId, OpenMode.ForRead);

                            if (ltr.IsLocked)
                            {
                                locked.Add(ltId);
                                ltr.UpgradeOpen();
                                ltr.IsLocked = false;
                                ltr.DowngradeOpen();// optional
                            }
                        }
                    }
                    //
                    // Here you begin to work with objects and not worry that they are in the locked layers
                    // e.g. itrerate through selection etc. (poor code commented)
                    //SelectionSet ss = ed.SelectAll().Value;
                    //foreach (ObjectId id in ss.GetObjectIds())
                    //{
                    //    Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
                    //    ent.ColorIndex = 121;
                    //}
                    //
                    foreach (ObjectId ltId in lt)
                    {
                        LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(ltId, OpenMode.ForWrite);
                        ltr.IsLocked = true;

                    }
                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                fine = false;
                ed.WriteMessage(ex.ToString());
            }
            finally
            {
                if (!fine)
                    doc.SendStringToExecute("_layerp", true, false, false);
            }
        }

35
Polylines / Offset curve toward centroid
« on: February 26, 2013, 07:13:16 PM »
// Offset curve toward centroid

Code: [Select]
        [CommandMethod("OFT")]
        public static void OffsetTowardCentroid()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Database db = doc.Database;

            Transaction tr = doc.TransactionManager.StartTransaction();

                using (tr)
                {
                    try
                    {
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                        PromptEntityOptions peo = new PromptEntityOptions("\nSelect curve to Offset Toward: ");

                        peo.SetRejectMessage("\nSelect curve only: ");

                        peo.AddAllowedClass(typeof(Line), true);

                        peo.AddAllowedClass(typeof(Arc), true);

                        peo.AddAllowedClass(typeof(Circle), true);

                        peo.AddAllowedClass(typeof(Ellipse), true);

                        peo.AddAllowedClass(typeof(Polyline), true);

                        peo.AddAllowedClass(typeof(Spline), true);

                        PromptEntityResult pres = ed.GetEntity(peo);

                        if ((pres.Status != PromptStatus.OK)) return;

                        Entity ent = (Entity)tr.GetObject(pres.ObjectId, OpenMode.ForRead);

                        // add the polylines to the array
                        DBObjectCollection dbobjs = new DBObjectCollection();
                        dbobjs.Add(ent);
                        // create the region
                        Region objreg = new Region();

                        DBObjectCollection objRegions = new DBObjectCollection();

                        objRegions = Region.CreateFromCurves(dbobjs);

                        objreg = objRegions[0] as Region;
                       
                        Curve curv = ent as Curve;

                        PromptDoubleResult dres = ed.GetDouble("\nDistance for Offset: ");

                        double dist = dres.Value;

                        DBObjectCollection ids = curv.GetOffsetCurves(dist);
                        DBObjectCollection ids2 = curv.GetOffsetCurves(-1 * dist);
                       double leg= ((ids[0]) as Curve).Area;
                       double leg2 = ((ids2[0]) as Curve).Area;
                       if (leg - leg2 < 0)
                       {
                           foreach (Entity oEnt in ids)
                           {
                               btr.AppendEntity(oEnt);
                               tr.AddNewlyCreatedDBObject(oEnt, true);
                           }
                       }
                       else
                       {

                           foreach (Entity oEnt in ids2)
                           {
                               btr.AppendEntity(oEnt);
                               tr.AddNewlyCreatedDBObject(oEnt, true);
                           }
                       }
                       
                       objRegions.Dispose();
                       ids.Dispose();
                       ids2.Dispose();
                       doc.TransactionManager.FlushGraphics();
                        tr.Commit();
                        ed.UpdateScreen();
                    }

                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        ed.WriteMessage("\nError: {0}\nTrace: {1}", ex.Message, ex.StackTrace);
                    }
                }
            }

36
C# language / Re: How to offset polyline
« on: February 26, 2013, 04:46:37 PM »
Absolutely no,
I'm just an old freak and forever beginner,
ha-ha :)

37
Tables / How to change cell value in previously selected table (A2010)
« on: February 24, 2013, 09:40:48 PM »
       
Code: [Select]
        // Select table on screen, then perform command SelCell:
        [CommandMethod("SelCell", CommandFlags.UsePickSet)]
        public static void testSelectFromTable()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            ObjectId id = ObjectId.Null;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                PromptSelectionResult res = ed.SelectImplied();
                if (res.Status == PromptStatus.OK)
                {
                    SelectionSet sset = res.Value;
                    id = sset.GetObjectIds()[0];
                    Table table = tr.GetObject(id, OpenMode.ForRead) as Table;

                    PromptPointOptions pto = new PromptPointOptions("\nPick inside a single cell: ");

                    PromptPointResult pres = ed.GetPoint(pto);

                    if (pres.Status != PromptStatus.OK)
                    {
                        ed.WriteMessage("\nInvalid point specification!");
                        return;
                    }
                    Point3d pt = pres.Value;
                    TableHitTestInfo hit = table.HitTest(pt, Vector3d.ZAxis);
                    int i = hit.Row;
                    int j = hit.Column;
                    Cell cell = table.Cells[i, j];
                    CellRange cr = CellRange.Create(table, i, j, i, j);
                    table.SubSelection = cr;
                    Vector3d vec = table.Normal;
                    Point3dCollection pts = cell.GetExtents();
                    double ht = table.Rows[cell.TopRow].Height;
                    double wid = table.Columns[cell.LeftColumn].Width;
                    table.SelectSubRegion(pts[0], pts[2], vec, vec, SelectType.Window, false, true, new FullSubentityPath[] { });
                    if (table.HasSubSelection)
                    {
                        cr = table.SubSelection;
                        if (cr.IsSingleCell)
                        {
                            cell = table.Cells[cr.TopRow, cr.LeftColumn];
                            string celltxt = cell.GetTextString(FormatOption.ForExpression);
                            ed.WriteMessage("\n{0}\n", celltxt);
                            table.UpgradeOpen();
                            cell.Contents[0].TextString = "Abracadabra";// add your value here
                        }

                    }
                    if (table.HasSubSelection)
                    {
                        ed.WriteMessage("\nSubSelection remove");
                        ed.GetString("\nPress any key: ");
                        table.ClearSubSelection();
                    }
                }
                tr.Commit();
            }
        }

38
Math and Geometry / Re: Convex Hull
« on: February 24, 2013, 07:26:04 PM »
Another convexhull code, not sure about if this
working good

Code: [Select]
        // See for more
       // https://github.com/lein/ConvexHull
       // http://www.chrisharrison.net/projects/convexHull/jarvis.cpp
        [CommandMethod("cxx")]
        public void testConvexHull()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            testConvexHull(db, ed);
        }

        public static List<Point2d> ConvexHull(List<Point2d> points) 
        {     
            if (points.Count < 3) 
            {       
                throw new ArgumentException("At least 3 points reqired", "points"); 
 
            }       
            List<Point2d> convex = new List<Point2d>();   
            // get leftmost point   
            Point2d ptOnHull = points.Where(p => p.X == points.Min(min => min.X)).First();     
            Point2d ptNext;     
            do         
            {
                convex.Add(ptOnHull);     
                ptNext = points[0];     
                for (int i = 1; i < points.Count; i++)       
                {             
                    if ((ptOnHull == ptNext)
                        || (CCW(ptOnHull, ptNext, points[i]) == -1))    // check direction
                    {                     
                        ptNext = points[i];     
                    }           
                }           
                ptOnHull = ptNext; 
            }
            while (ptNext != convex[0]);
            return convex;     
        }   

        private static int CCW(Point2d p1, Point2d p2, Point2d p)     
        {           
            // Determinant   
            int ptDir = Convert.ToInt32((p2.X - p1.X) * (p.Y - p1.Y) - (p.X - p1.X) * (p2.Y - p1.Y));
            if (ptDir > 0)       
                return -1;  // clockwise   
            if (ptDir < 0)           
                return 1; // counterclockwise 
            return 0; //  collinear direction   
        }

        //--------------------------------------------------------------------------//

        public void testConvexHull(Database db, Editor ed)
        {
            List<Point2d> points = new List<Point2d>();
            List<Point2d> convex = new List<Point2d>();
            Point2d pt;
            Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                TypedValue[] values = { new TypedValue(0, "point,line,lwpolyline,circle") };// add other types you need here
                SelectionFilter filter = new SelectionFilter(values);

                PromptSelectionResult res = ed.GetSelection(filter);

                if (res.Status != PromptStatus.OK) return;

                SelectionSet sset = res.Value;
                //   iterate through selected objects
                foreach (SelectedObject selobj in sset)
                {
                    Entity pEnt = (Entity)tr.GetObject(selobj.ObjectId, OpenMode.ForRead, false);

                    if (pEnt == null) return;
                    //----------------------------DBPOint----------------------------//
                    if (pEnt is DBPoint)
                    {
                        DBPoint dp = pEnt as DBPoint;
                        if (dp != null)
                        {

                            Point3d pp = dp.Position.TransformBy(ucs);
                            pt = new Point2d(pp.X, pp.Y);
                            points.Add(pt);
                        }
                    }
                    //----------------------------Line----------------------------//
                    if (pEnt is Line)
                    {
                        Line ln = pEnt as Line;
                        if (ln != null)
                        {

                            Point3d pp = ln.StartPoint.TransformBy(ucs);
                            pt = new Point2d(pp.X, pp.Y);
                            points.Add(pt);
                            pp = ln.EndPoint.TransformBy(ucs);
                            pt = new Point2d(pp.X, pp.Y);
                            points.Add(pt);
                        }
                    }

                    //---------------------------Polyline----------------------------//
                    if (pEnt is Polyline)
                    {
                        Polyline poly = pEnt as Polyline;
                        if (poly != null)
                        {
                            for (int m = 0; m < poly.NumberOfVertices; m++)
                            {
                                Point3d pp = poly.GetPoint3dAt(m).TransformBy(ucs);
                                pt = new Point2d(pp.X, pp.Y);
                                points.Add(pt);
                            }

                        }
                    }
                    //---------------------------Circle----------------------------//
                    if (pEnt is Circle)
                    {
                        Circle circ = pEnt as Circle;
                        if (circ != null)
                        {
                            int num = 64;
                            double dp = (circ.EndParam - circ.StartParam) / num;
                            for (int a = 0; a < num; a++)
                            {
                                Point3d pp = circ.GetPointAtParameter(dp * a).TransformBy(ucs);
                                pt = new Point2d(pp.X, pp.Y);
                                points.Add(pt);
                            }

                        }
                    }
                }
                convex=ConvexHull(points);
                ed.WriteMessage("\nAll Points Count:\t{0}\n", points.Count.ToString());
                ed.WriteMessage("\nConvexHull points Count:\t{0}\n", convex.Count.ToString());
                //-------------------------------------------------------//
                // Create a polyline by boundary points
                Polyline pline = new Polyline();
                pline.SetDatabaseDefaults();

                for (int cnt = 0; cnt < convex.Count; cnt++)
                {

                    pline.AddVertexAt(cnt, convex[cnt], 0, 0, 0);

                }

                // close boundary
                pline.Closed = true;
                pline.ColorIndex = 121;

                // Add the new object to the block table record and the transaction
                btr.AppendEntity(pline);
                tr.AddNewlyCreatedDBObject(pline, true);
                tr.Commit();

            }
        }

39
C# language / Re: How to offset polyline
« on: February 24, 2013, 07:53:31 AM »
You may want to use command using API invoke method acedCmd
e.g. open desired block in block editor then perform this code
(it's not mine though)

Code: [Select]
        // Replace "accore.dll" by "acad.exe" for AutoCAD versions prior to 2013
        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("acad.exe", EntryPoint = "acedCmd", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        extern static private int acedCmd(IntPtr resbuf);
        [CommandMethod("offpl")]

        public void cmdOffset()
        {

            ResultBuffer rb = new ResultBuffer();

            // RTSTR = 5005

            rb.Add(new TypedValue(5005, "_.OFFSET"));

            // start the insert command

            acedCmd(rb.UnmanagedObject);



            bool quit = false;

            // loop round while the insert command is active

            while (!quit)
            {

                // see what commands are active

                string cmdNames = (string)Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("CMDNAMES");

                // if the INSERT command is active

                if (cmdNames.ToUpper().IndexOf("OFFSET") >= 0)
                {

                    // then send a PAUSE to the command line

                    rb = new ResultBuffer();

                    // RTSTR = 5005 - send a user pause to the command line

                    rb.Add(new TypedValue(5005, "\\"));

                    acedCmd(rb.UnmanagedObject);

                }

                else

                    // otherwise quit

                    quit = true;

            }

        }

40
Polylines / Regular polygons example
« on: February 21, 2013, 08:19:48 AM »
          C#
Code: [Select]
       // by Tony Tanzillo
        public static Point3d PolarPoint(Point3d basepoint, double angle, double distance)
        {
            return new Point3d(
            basepoint.X + (distance * Math.Cos(angle)),
            basepoint.Y + (distance * Math.Sin(angle)),
            basepoint.Z);
        }
        [CommandMethod("preg", CommandFlags.UsePickSet)]
        public void testPolygonRegular()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptIntegerOptions pio = new PromptIntegerOptions("");
            pio.Message = "\nNumber of sides: ";

            // Restrict input to positive and non-negative values
            pio.AllowZero = false;
            pio.AllowNegative = false;
            // Add default value
            pio.DefaultValue = 3;
            pio.AllowNone = true;
            // Get the value entered by the user
            PromptIntegerResult ires = ed.GetInteger(pio);
            if (ires.Status != PromptStatus.OK) return;
            int n = ires.Value;

            PromptDoubleOptions pdo = new PromptDoubleOptions("\nEnter radius: ");
            pdo.AllowZero = false;
            pdo.AllowNegative = false;
            pdo.AllowNone = true;
            pdo.UseDefaultValue = true;
            pdo.DefaultValue = 3.0;

            PromptDoubleResult res;
            res = ed.GetDouble(pdo);
            if (res.Status != PromptStatus.OK) return;

            double rad = res.Value;

            double ang = Math.PI * 2 / n;
            Point3d cp, p1,p2;
            // Center point
            cp = new Point3d(0, 0,0);

            Polyline poly = new Polyline(n);
            Polyline poly2 = new Polyline(n);
            for (int th = 0; th < n; th++)
            {
                // Circumscribed
                p1 = PolarPoint(cp, th * ang, rad / Math.Cos(ang / 2)).TransformBy(Matrix3d.Identity);
                poly.AddVertexAt(th, new Point2d(p1.X, p1.Y), 0, 0, 0);
                // Inscribed
                 p2 = PolarPoint(cp, th * ang, rad).TransformBy(Matrix3d.Identity);
                poly2.AddVertexAt(th, new Point2d(p2.X, p2.Y), 0, 0, 0);
            }
            poly.Closed = true;
            poly.ColorIndex = 1;
            poly2.Closed = true;
            poly2.ColorIndex = 3;
            // Add circle for imagination only
            Circle circ = new Circle(new Point3d(0, 0, 0), Vector3d.ZAxis, rad);
            circ.ColorIndex = 5;
            Transaction tr = doc.TransactionManager.StartTransaction();

            using (tr)
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(poly);
                tr.AddNewlyCreatedDBObject(poly, true);
                btr.AppendEntity(poly2);
                tr.AddNewlyCreatedDBObject(poly2, true);
                btr.AppendEntity(circ);
                tr.AddNewlyCreatedDBObject(circ, true);
                tr.Commit();
            }
        }
      VB.NET
Code: [Select]
        ' by Tony Tanzillo
        Public Shared Function PolarPoint(basepoint As Point3d, angle As Double, distance As Double) As Point3d
            Return New Point3d(basepoint.X + (distance * Math.Cos(angle)), basepoint.Y + (distance * Math.Sin(angle)), basepoint.Z)
        End Function

        <CommandMethod("preg", CommandFlags.UsePickSet)> _
        Public Sub testPolygonRegular()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim pio As New PromptIntegerOptions("")
            pio.Message = vbLf & "Number of sides: "

            ' Restrict input to positive and non-negative values
            pio.AllowZero = False
            pio.AllowNegative = False
            ' Add default value
            pio.DefaultValue = 3
            pio.AllowNone = True
            ' Get the value entered by the user
            Dim ires As PromptIntegerResult = ed.GetInteger(pio)
            If ires.Status <> PromptStatus.OK Then
                Return
            End If
            Dim n As Integer = ires.Value

            Dim pdo As New PromptDoubleOptions(vbLf & "Enter radius: ")
            pdo.AllowZero = False
            pdo.AllowNegative = False
            pdo.AllowNone = True
            pdo.UseDefaultValue = True
            pdo.DefaultValue = 3.0

            Dim res As PromptDoubleResult
            res = ed.GetDouble(pdo)
            If res.Status <> PromptStatus.OK Then
                Return
            End If

            Dim rad As Double = res.Value

            Dim ang As Double = Math.PI * 2 / n
            Dim cp As Point3d, p1 As Point3d, p2 As Point3d
            ' Center point
            cp = New Point3d(0, 0, 0)

            Dim poly As New Polyline(n)
            Dim poly2 As New Polyline(n)
            For th As Integer = 0 To n - 1
                ' Circumscribed
                p1 = PolarPoint(cp, th * ang, rad / Math.Cos(ang / 2)).TransformBy(Matrix3d.Identity)
                poly.AddVertexAt(th, New Point2d(p1.X, p1.Y), 0, 0, 0)
                ' Inscribed
                p2 = PolarPoint(cp, th * ang, rad).TransformBy(Matrix3d.Identity)
                poly2.AddVertexAt(th, New Point2d(p2.X, p2.Y), 0, 0, 0)
            Next
            poly.Closed = True
            poly.ColorIndex = 1
            poly2.Closed = True
            poly2.ColorIndex = 3
            ' Add circle for imagination only
            Dim circ As New Circle(New Point3d(0, 0, 0), Vector3d.ZAxis, rad)
            circ.ColorIndex = 5
            Dim tr As Transaction = doc.TransactionManager.StartTransaction()

            Using tr
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                btr.AppendEntity(poly)
                tr.AddNewlyCreatedDBObject(poly, True)
                btr.AppendEntity(poly2)
                tr.AddNewlyCreatedDBObject(poly2, True)
                btr.AppendEntity(circ)
                tr.AddNewlyCreatedDBObject(circ, True)
                tr.Commit()
            End Using
        End Sub

41
Math and Geometry / Draw bisector between 2 lines
« on: February 19, 2013, 08:02:37 PM »
Code: [Select]
        [CommandMethod("bis", CommandFlags.UsePickSet)]
        public static void drawBisector()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = doc.Editor;
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect first line: ");
            peo.SetRejectMessage("Wrong object or nothing selected.");
            peo.AddAllowedClass(typeof(Line), false);
            PromptEntityResult res;
            ObjectId objId1 = ObjectId.Null;
            ObjectId objId2 = ObjectId.Null;
            Entity ent;
            Point3d p1, p2;
            res = ed.GetEntity(peo);

            if (res.Status != PromptStatus.OK)
                return;;
            objId1 = res.ObjectId;
            p1 = res.PickedPoint;
            peo.Message="\nSelect second line: ";
            res = ed.GetEntity(peo);

            if (res.Status != PromptStatus.OK)
                return;
            objId2 = res.ObjectId;
            p2 = res.PickedPoint;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                ent = tr.GetObject(objId1, OpenMode.ForRead) as Entity;
                if (ent == null)   return;
                Line ln1 = ent as Line;
                if (ln1 == null) return;
                ent = tr.GetObject(objId2, OpenMode.ForRead) as Entity;
                if (ent == null) return;
                Line ln2 = ent as Line;
                if (ln2 == null) return;

                p1 = ln1.GetClosestPointTo(p1,false);
                p2 = ln2.GetClosestPointTo(p2, false);

                Point3d tmp,p1f, p2f, p1n, p2n;

                p1f = ln1.StartPoint;
                p2f = ln1.EndPoint;
                p1n = ln2.StartPoint;
                p2n = ln2.EndPoint;
                // swap poins for easier math
                if (p1f.DistanceTo(p1n) > p1f.DistanceTo(p2n))
                {
                    tmp = p2n;
                    p2n = p1n;
                    p1n=tmp;
                }
   
                Point3d mp1 = new Point3d((p1f.X + p1n.X) / 2, (p1f.Y + p1n.Y) / 2, (p1f.Z + p1n.Z) / 2);
                Point3d mp2 = new Point3d((p2f.X + p2n.X) / 2, (p2f.Y + p2n.Y) / 2, (p2f.Z + p2n.Z) / 2);
                Line bis = new Line(mp1, mp2);

                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(bis);
                tr.AddNewlyCreatedDBObject(bis, true);
                tr.Commit();
            }
        }

42
Polylines / Write polyline points to CSV file
« on: February 19, 2013, 04:37:10 PM »
Code: [Select]
        [CommandMethod("PolylineToCSV", "plcsv",CommandFlags.Modal | CommandFlags.UsePickSet)]
        public static void ExportPolyPointsToCSV()
        {
            Document doc =Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            try
            {

                using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
                {
                    string dec = ((short)Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("LUPREC")).ToString();

                    PromptSelectionOptions pso = new PromptSelectionOptions();

                    pso.MessageForRemoval = "\n >>  Nothing selected....";

                    pso.MessageForAdding = "\n  >>  Select a single polyline >> ";

                    pso.AllowDuplicates = false;

                    pso.SingleOnly = true;

                    SelectionFilter sf = new SelectionFilter
                        (new TypedValue[] { new TypedValue(0, "lwpolyline") });

                    PromptSelectionResult res = ed.GetSelection(pso, sf);

                    if (res.Status != PromptStatus.OK)  return;

                    StringBuilder sb = new StringBuilder();
                    ObjectId[] ids = res.Value.GetObjectIds();

                    Polyline poly = (Polyline)tr.GetObject(ids[0], OpenMode.ForRead, false);
                    for (int i = 0; i < poly.NumberOfVertices; i++)
                    {
                        Point2d pt = poly.GetPoint2dAt(i);
                        string vexstr = string.Format("{0:f" + dec + "};{1:f" + dec + "}", pt.X, pt.Y);
                        sb.AppendLine(vexstr);
                    }
                    String csvFile = String.Empty;

                    System.Windows.Forms.SaveFileDialog sfd =  new System.Windows.Forms.SaveFileDialog();
                    sfd.ValidateNames = true;
                    sfd.Title = "Save polyline vertices to CSV file";
                    sfd.DefaultExt = ".csv";
                    sfd.InitialDirectory=@"C:\Test\";
                    sfd.RestoreDirectory = true;
                   
                    if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK)  return;

                    csvFile = sfd.FileName;

                    // write point to defined file
                    using (StreamWriter sw = new StreamWriter(csvFile))
                    {
                        sw.Write(sb.ToString());

                        sw.Flush();
                    }
                    sfd.Dispose();// non resident object, so kill 'em

                    tr.Commit();
                }
           }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n" + ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace);
            }
        }

43
3D entities / Create extruded cylinder
« on: February 19, 2013, 03:20:13 PM »
        [CommandMethod("testCylinder")]
        public void DrawExtrudedCylinder()
        {

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            Point3d cp;

            PromptPointOptions ptopts = new PromptPointOptions("\nSelect center point of circel: ");

            PromptPointResult ptres = ed.GetPoint(ptopts);

            // Exit if the user presses ESC or cancels the command
            if (ptres.Status != PromptStatus.OK) return;

            cp = ptres.Value;
            //base point
           
            PromptDistanceOptions pdo = new PromptDistanceOptions("\nEnter a radius: ");
            pdo.AllowNone = true;
            pdo.UseDefaultValue = true;
            pdo.DefaultValue = 100.0;
            pdo.BasePoint = cp;
            pdo.UseBasePoint = true;
            pdo.UseDashedLine = true;
           
            PromptDoubleResult res;
            res = ed.GetDistance(pdo);
            if (res.Status != PromptStatus.OK)
                return;

            double rad = res.Value;

            ed.WriteMessage("\nRadius Entered\t{0}", rad);
            pdo = new PromptDistanceOptions("\nEnter cylinder height: ");
            pdo.AllowNone = true;
            pdo.UseDefaultValue = true;
            pdo.DefaultValue = 1000.0;
            pdo.BasePoint = cp;
            pdo.UseBasePoint = true;
            pdo.UseDashedLine = true;

            res = ed.GetDistance(pdo);
            if (res.Status != PromptStatus.OK)
                return;

            double height = res.Value;
 
            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                Circle circ = new Circle(cp, Vector3d.ZAxis, rad);
               

                BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                ObjectId objId = btr.AppendEntity(circ);

                tr.AddNewlyCreatedDBObject(circ, true);

                // Get the boundary curves to create a region
                DBObjectCollection regs = new DBObjectCollection();

                regs.Add(circ);

                // Create a region from the circle.

                DBObjectCollection regions = new DBObjectCollection();

                regions = Region.CreateFromCurves(regs);
               
                if (regions.Count == 0)
                {
                    ed.WriteMessage("\nFailed to create region\n");
                    return;
                }

                Region reg = (Region)regions[0];

                // Extrude the region to create a solid.

                Solid3d sol = new Solid3d();

                sol.RecordHistory = true;// important

                sol.ShowHistory = true;// important

                sol.Extrude(reg, height, 0.0);// < --- set taper angle here

                ObjectId solId = ObjectId.Null;

                solId = btr.AppendEntity(sol);

                tr.AddNewlyCreatedDBObject(sol, true);

                if (!circ.IsWriteEnabled) circ.UpgradeOpen();

                circ.Erase();

                tr.Commit();
            }

        }

44
Dimensions / Display sum of selected dimensions
« on: February 15, 2013, 09:30:41 PM »
Code: [Select]
        [CommandMethod("DisplayDimSum", "dds", CommandFlags.Modal | CommandFlags.UsePickSet)]
        public void SumOfDims()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            double sum = 0;
            TypedValue[] values = new TypedValue[] { new TypedValue(0, "DIMENSION") };
            SelectionFilter filter = new SelectionFilter(values);
            PromptSelectionOptions opts = new PromptSelectionOptions();

            opts.MessageForRemoval = "\nMust be a type of Dimension!";
            opts.MessageForAdding = "\nSelect dimensions to reset : ";
            opts.PrepareOptionalDetails = false;
            opts.SingleOnly = false;
            opts.SinglePickInSpace = false;
            opts.AllowDuplicates = true;
            PromptSelectionResult result = ed.GetSelection(opts, filter);
            if (result.Status != PromptStatus.OK) return;

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    SelectionSet sset = result.Value;
                    foreach (SelectedObject selobj in sset)
                    {
                        DBObject obj = tr.GetObject(selobj.ObjectId, OpenMode.ForWrite, false) as DBObject;
                        Dimension dim = obj as Dimension;

                        if (dim != null)
                        {
                            sum += dim.Measurement;

                        }
                    }

                    tr.Commit();
                }
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(string.Format("Sum of dimensions = {0:f3}", sum));
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nProblem with selection dimensions.\n");
                ed.WriteMessage(ex.Message);
            }
        }

45
Layers / Load base or custom linetypes
« on: February 14, 2013, 06:40:08 PM »
This code allow user to load both linetypes from "acad.lin" or "acadiso.lin" file
and from the custom linetype file,
see attachment, both C# and VB.NET code included

Pages: 1 2 [3] 4 5 ... 9