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.


Topics - fixo

Pages: [1] 2 3 ... 8
1
Dimensions / Create leader with mtext
« on: January 28, 2014, 12:29:10 PM »
        C#
Code: [Select]
         [CommandMethod("LDM")]
        public void CreateLeaderWithMText()
        {

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            PromptPointOptions prOpt = new PromptPointOptions("\nSelect first point ");
            PromptPointResult es = ed.GetPoint(prOpt);
            if (es.Status != PromptStatus.OK)
            {
                if (es.Status == PromptStatus.Cancel)
                {
                    ed.WriteMessage("\nInterrupted by user"); return;
                }
                else
                {
                    ed.WriteMessage("\nError on specifying a point"); return;
                }
            }
            Point3d p1 = es.Value;
            prOpt = new PromptPointOptions("\nSelect Second point ");
            prOpt.UseBasePoint = true;
            prOpt.UseDashedLine = true;
            prOpt.BasePoint = p1;
            es = ed.GetPoint(prOpt);
            if (es.Status != PromptStatus.OK)
            {
                if (es.Status == PromptStatus.Cancel)
                {
                    ed.WriteMessage("\nInterrupted by user"); return;
                }
                else
                {
                    ed.WriteMessage("\nError on specifying a point"); return;
                }
            }
            Point3d p2 = es.Value;

            Transaction tr = doc.TransactionManager.StartTransaction();

            using (tr)
            {

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

                ObjectId mtextId = ObjectId.Null;
                MText mtx = new MText();
                mtx.SetDatabaseDefaults();
                mtx.Contents = "TEXT STRING\\PNEW STRING";
                mtx.Location = p2;
                mtextId = btr.AppendEntity(mtx);
                tr.AddNewlyCreatedDBObject(mtx, true);
                // mtx.DowngradeOpen();
                ObjectId leaderId = ObjectId.Null;
                Leader ld = new Leader();
                ld.AppendVertex(p1);
                ld.AppendVertex(p2);
                ld.SetDatabaseDefaults();
                leaderId = btr.AppendEntity(ld);

                ld.Annotation = mtextId;
                if (p2.X < p1.X)
                {
                    mtx.Attachment = AttachmentPoint.MiddleRight;
                    mtx.Location = p2;
                }
                ld.EvaluateLeader();

                tr.AddNewlyCreatedDBObject(ld, true);
                tr.Commit();
            }
        }
VB.NET
Code: [Select]
<CommandMethod("LDM")> _
        Public Sub CreateLeaderWithMText()

            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database

            Dim prOpt As New PromptPointOptions(vbLf & "Select first point ")
            Dim es As PromptPointResult = ed.GetPoint(prOpt)
            If es.Status <> PromptStatus.OK Then
                If es.Status = PromptStatus.Cancel Then
                    ed.WriteMessage(vbLf & "Interrupted by user")
                    Return
                Else
                    ed.WriteMessage(vbLf & "Error on specifying a point")
                    Return
                End If
            End If
            Dim p1 As Point3d = es.Value
            prOpt = New PromptPointOptions(vbLf & "Select Second point ")
            prOpt.UseBasePoint = True
            prOpt.UseDashedLine = True
            prOpt.BasePoint = p1
            es = ed.GetPoint(prOpt)
            If es.Status <> PromptStatus.OK Then
                If es.Status = PromptStatus.Cancel Then
                    ed.WriteMessage(vbLf & "Interrupted by user")
                    Return
                Else
                    ed.WriteMessage(vbLf & "Error on specifying a point")
                    Return
                End If
            End If
            Dim p2 As Point3d = es.Value

            Dim tr As Transaction = doc.TransactionManager.StartTransaction()

            Using tr

                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                Dim mtextId As ObjectId = ObjectId.Null
                Dim mtx As New MText()
                mtx.SetDatabaseDefaults()
                mtx.Contents = "TEXT STRING\PNEW STRING"
                mtx.Location = p2
                mtextId = btr.AppendEntity(mtx)
                tr.AddNewlyCreatedDBObject(mtx, True)
                ' mtx.DowngradeOpen();
                Dim leaderId As ObjectId = ObjectId.Null
                Dim ld As New Leader()
                ld.AppendVertex(p1)
                ld.AppendVertex(p2)
                ld.SetDatabaseDefaults()
                leaderId = btr.AppendEntity(ld)

                ld.Annotation = mtextId
                If p2.X < p1.X Then
                    mtx.Attachment = AttachmentPoint.MiddleRight
                    mtx.Location = p2
                End If
                ld.EvaluateLeader()

                tr.AddNewlyCreatedDBObject(ld, True)
                tr.Commit()
            End Using
        End Sub

2
Selection sets / Polar increment of objects
« on: December 13, 2013, 02:41:11 PM »
     Code tested in A2014, in other release you probably may change the sorting alghoritm
     Editor handler function was brrowed from Gilles Chanteau
      VB.NET code
Code: [Select]
   <CommandMethod("TOCC")> _
        Public Sub SelectCirclesObjectsByCrossingWindow()
            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 plan As Plane = New Plane
            '  Dim points As Point3dCollection = New Point3dCollection
            Dim points As List(Of Point3d) = New List(Of Point3d)
            AddHandler ed.SelectionAdded, AddressOf ed_CircleSelectionAdded
            Try
                '' Create a crossing window from picked corner points
                Dim ppo As New PromptPointOptions(vbLf & "Select first corner: ")

                ppo.AllowNone = False

                Dim ppr As PromptPointResult = ed.GetPoint(ppo)

                If ppr.Status <> PromptStatus.OK Then

                    Return

                End If

                Dim pt1 As Point3d = ppr.Value

                Dim pco As New PromptCornerOptions(vbLf & "Select second clip corner: ", pt1)

                ppr = ed.GetCorner(pco)

                If ppr.Status <> PromptStatus.OK Then

                    Return
                End If

                Dim pt2 As Point3d = ppr.Value

                Dim res As PromptSelectionResult

                res = ed.SelectCrossingWindow(pt1, pt2)

                '' If the prompt status is OK, objects were selected
                If res.Status <> PromptStatus.OK Then Return

                Dim sset As SelectionSet = res.Value
                If sset.Count > 0 Then

                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Number of objects selected: " & _
                                                sset.Count.ToString())
                Else
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Number of objects selected: 0")
                    Return
                End If
                Dim tr As Transaction = doc.TransactionManager.StartTransaction
                Using tr
                    For Each sobj As SelectedObject In sset
                        ent = TryCast(tr.GetObject(sobj.ObjectId, OpenMode.ForRead), Entity)
                        If ent Is Nothing Then Return
                        Dim circ As Circle = TryCast(ent, Circle)
                        If circ Is Nothing Then Return
                        plan = circ.GetPlane
                        points.Add(circ.Center)
                    Next


                    Dim cp As Point3d = New Point3d( _
                                                         points.Average(Function(x) Convert.ToDouble(x.X)), _
                                                       points.Average(Function(x) Convert.ToDouble(x.Y)), _
                                                       points.Average(Function(x) Convert.ToDouble(x.Z)))
                    cp.GetVectorTo(Point3d.Origin).AngleOnPlane(plan)

                    Dim sorted = points.OrderBy(Function(x) cp.GetVectorTo(x).AngleOnPlane(plan))
                    '' debug only
                    '' Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(String.Format("{0:f2},{1:f2},{2:f2} ", cp.X, cp.Y, cp.Z))
                    Dim cr As Circle = New Circle(cp, Vector3d.ZAxis, 10)
                    cr.ColorIndex = 130

                    Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
                    btr.AppendEntity(cr)
                    tr.AddNewlyCreatedDBObject(cr, True)
                    Dim i As Integer = 1
                    For Each p As Point3d In sorted
                        Dim mtxt As MText = New MText
                        mtxt.Location = p
                        mtxt.Attachment = AttachmentPoint.MiddleCenter
                        mtxt.Contents = i.ToString
                        mtxt.ColorIndex = 1
                        btr.AppendEntity(mtxt)
                        tr.AddNewlyCreatedDBObject(mtxt, True)
                        i += 1
                    Next
                    tr.Commit()
                End Using

            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.ErrorStatus)
            Finally
                RemoveHandler ed.SelectionAdded, AddressOf ed_CircleSelectionAdded
            End Try
        End Sub

        Private Shared Sub ed_CircleSelectionAdded(sender As Object, e As SelectionAddedEventArgs)
            Dim ids As ObjectId() = e.AddedObjects.GetObjectIds()
            For i As Integer = 0 To ids.Length - 1
                If Not ids(i).ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(Circle))) Then
                    e.Remove(i)
                End If
            Next
        End Sub


      C# code
Code: [Select]
        [CommandMethod("TOCC")]
        public void SelectCirclesObjectsByCrossingWindow()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            Entity ent = default(Entity);

            Plane plan = new Plane();

            List<Point3d> points = new List<Point3d>();
            // add editor SelectionAdded handler for sure the user selected circles only
            ed.SelectionAdded += ed_CircleSelectionAdded;
            try
            {
                // Create a crossing window from picked corner points
                PromptPointOptions ppo = new PromptPointOptions("\nSelect first corner: \n");

                ppo.AllowNone = false;

                PromptPointResult ppr = ed.GetPoint(ppo);


                if (ppr.Status != PromptStatus.OK)
                {
                    return;

                }

                Point3d pt1 = ppr.Value;

                PromptCornerOptions pco = new PromptCornerOptions("\nSelect second clip corner: \n", pt1);

                ppr = ed.GetCorner(pco);


                if (ppr.Status != PromptStatus.OK)
                {
                    return;
                }

                Point3d pt2 = ppr.Value;

                PromptSelectionResult res = default(PromptSelectionResult);

                res = ed.SelectCrossingWindow(pt1, pt2);
                // If the prompt status is OK, objects were selected
                if (res.Status != PromptStatus.OK)
                    return;

                SelectionSet sset = res.Value;
                // display inform message for user, may be removed
                if (sset.Count > 0)
                {
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Number of objects selected: " + sset.Count.ToString());
                }
                else
                {
                    Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Nothing selected!");

                    return;
                }
                // start transaction
                Transaction tr = doc.TransactionManager.StartTransaction();

                using (tr)
                {
                    foreach (SelectedObject sobj in sset)
                    {
                        ent = tr.GetObject(sobj.ObjectId, OpenMode.ForRead) as Entity;

                        if (ent == null) return;

                        Circle circ = ent as Circle;

                        if (circ == null) return;

                        plan = circ.GetPlane();

                        points.Add(circ.Center);
                    }


                    Point3d cp =
                        new Point3d(
                        points.Average(x => Convert.ToDouble(x.X)),
                        points.Average(x => Convert.ToDouble(x.Y)),
                        points.Average(x => Convert.ToDouble(x.Z))
                        );

                    cp.GetVectorTo(Point3d.Origin).AngleOnPlane(plan);

                    dynamic sorted = points.OrderBy(x => cp.GetVectorTo(x).AngleOnPlane(plan));
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    // debug only, commented
                    // Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(String.Format("{0:f2},{1:f2},{2:f2} ", cp.X, cp.Y, cp.Z))
                    //Circle cr = new Circle(cp, Vector3d.ZAxis, 10);
                    //cr.ColorIndex = 130;                   
                    //btr.AppendEntity(cr);
                    //tr.AddNewlyCreatedDBObject(cr, true);
                    // set increment starting number:
                    int i = 1;
                    foreach (Point3d p in sorted)
                    {
                        MText mtxt = new MText();
                        mtxt.SetDatabaseDefaults();
                        //_______________________
                        // you have put appropriate text size here instead:
                        mtxt.TextHeight = db.Dimtxt;
                        //__________________________
                        mtxt.Location = p;
                        mtxt.Attachment = AttachmentPoint.MiddleCenter;
                        mtxt.Contents = i.ToString();
                        mtxt.ColorIndex = 1;
                        btr.AppendEntity(mtxt);
                        tr.AddNewlyCreatedDBObject(mtxt, true);
                        // increase a number
                        i += 1;
                    }
                    // commit transaction
                    tr.Commit();
                }// end of using is meant to dispose transaction

            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.ErrorStatus.ToString());
            }
            finally
            {
                // remove editor SelectionAdded haandler at the end
                ed.SelectionAdded -= ed_CircleSelectionAdded;
            }
        }

        private static void ed_CircleSelectionAdded(object sender, SelectionAddedEventArgs e)
        {
            ObjectId[] ids = e.AddedObjects.GetObjectIds();
            for (int i = 0; i <= ids.Length - 1; i++)
            {
                if (!ids[i].ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Circle))))
                {
                    e.Remove(i);
                }
            }
        }

3
Cumulative and total sum of the distances indicated with selected points
Code: [Select]
        <CommandMethod("cud")> _
        Public Shared Sub CumulDist()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

            Dim db As Database = doc.Database

            Dim points As New Point3dCollection()

            Dim ed As Editor = doc.Editor

            Dim ptres2 As PromptPointResult
            Dim lst As List(Of Point3d)
            Dim cd As Double = 0
            Dim pto1 As New PromptPointOptions(vbLf & "Select first point, or press Enter to close: ")

            Dim ptres1 As PromptPointResult = ed.GetPoint(pto1)

            If ptres1.Status = PromptStatus.OK Then
                lst = New List(Of Point3d)
                Dim basept As Point3d = ptres1.Value
                lst.Add(basept)
                points.Add(basept)

                Do
                    Dim pto2 As New PromptPointOptions(vbLf & "Next point or [Enter to exit]: ", "Enter")

                    pto2.Keywords.[Default] = "Enter"

                    pto2.BasePoint = basept

                    pto2.UseBasePoint = True

                    ptres2 = ed.GetPoint(pto2)

                    basept = ptres2.Value

                    If ptres2.Status <> PromptStatus.Keyword Then
                        lst.Add(basept)
                        points.Add(basept)
                    End If
                   
                    If lst.Count = 2 Then
                        Dim td As Double = lst(0).DistanceTo(lst(1))
                        cd += td
                        ed.WriteMessage("Latest distance = {0:f3};  Cumulative distance = {1:f3}", td, cd)
                        lst.RemoveAt(0)
                    End If
                Loop While ptres2.Status <> PromptStatus.Keyword
                ed.WriteMessage("Total distance = {0:f3}", cd)

            End If
        End Sub

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

            Database db = doc.Database;

            Point3dCollection points = new Point3dCollection();

            Editor ed = doc.Editor;

            PromptPointResult ptres2 = default(PromptPointResult);

            List<Point3d> lst = default(List<Point3d>);

            double cd = 0;

            PromptPointOptions pto1 = new PromptPointOptions("\nSelect first point, or press Enter to close: ");

            PromptPointResult ptres1 = ed.GetPoint(pto1);

            if (ptres1.Status == PromptStatus.OK)
            {
                lst = new List<Point3d>();

                Point3d basept = ptres1.Value;

                lst.Add(basept);

                points.Add(basept);

                do
                {
                    PromptPointOptions pto2 = new PromptPointOptions("\nNext point or [Enter to exit]: ", "Enter");

                    pto2.Keywords.Default = "Enter";

                    pto2.BasePoint = basept;

                    pto2.UseBasePoint = true;

                    ptres2 = ed.GetPoint(pto2);

                    basept = ptres2.Value;

                    if (ptres2.Status != PromptStatus.Keyword)
                    {
                        lst.Add(basept);
                        points.Add(basept);
                    }

                    if (lst.Count == 2)
                    {
                        double td = lst[0].DistanceTo(lst[1]);
                        cd += td;
                        ed.WriteMessage("\nLatest distance = {0:f3};  Cumulative distance = {1:f3}", td, cd);
                        lst.RemoveAt(0);
                    }
                } while (ptres2.Status != PromptStatus.Keyword);
                ed.WriteMessage("\nTotal distance = {0:f3}", cd);
            }
        }

4
Tables / How to merge cells
« on: August 16, 2013, 01:24:30 PM »
Here is very basic code to creating dummy table
with merged cells, tested from A2010 through A2014:

Code: [Select]
        [CommandMethod("mcit")]
        public void MergeCellsInTable()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            int numRows = 7;
            int numCols = 4;
            double rowHeight = 15.0;
            double colWidth = 45.0;
            double verMarg = 2.5;
            double horMarg = 2.5;
            double txtHeight = 10.0;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                Table tb = new Table();
                tb.SetDatabaseDefaults();
               // Pick location
                tb.Position = ed.GetPoint("\nSpecify table location: ").Value;
                tb.Color = Color.FromRgb(107, 27, 0);         
                tb.LineWeight = LineWeight.LineWeight035;
                tb.Normal = new Vector3d(0, 0, 1);// or the same as Vector3d.Zaxis
                //To speed up regenerate table
                tb.SuppressRegenerateTable(true); //<-- optional
                tb.TableStyle = db.Tablestyle;
                // Set the height and width of the initial row and
                // column belonging by default to the blank Table
                tb.Rows[0].Height = rowHeight;
                tb.Rows[0].BackgroundColor = Color.FromRgb(148, 153, 194);
               
                tb.Columns[0].Width = colWidth;
                // Add the remaining rows and columns
                tb.InsertRows(1, rowHeight, numRows);
                tb.InsertColumns(1, colWidth, numCols - 1);
                tb.Rows[0].IsMergeAllEnabled = true;
                tb.Rows[0].Height = rowHeight;
                tb.Rows[0].TextHeight = txtHeight;
                tb.Rows[1].Height = rowHeight;
                tb.Rows[1].TextHeight = txtHeight;
                // Add the contents of the Title cell
                Cell tc = tb.Cells[0, 0];
                tc.Contents.Add();
                tc.Contents[0].TextHeight = txtHeight;
                tc.Contents[0].TextString = "Title";
                // Add some flowers
                // Column widths might be vary
                List<double> wids = new List<double>(new double[] { 65,70,70,65 });
                List<string[]> tabledata = new List<string[]>(){
                     new string[]{"alpha","bravo","charlie","delta"},
                     new string[]{"echo","foxtrott","golf","hotel"},
                     new string[]{"india","juliett","kilo","lima"},
                     new string[]{"mike","november","oscar","papa"},
                     new string[]{"quebec","romeo","sierra","tango"},
                     new string[]{"uniform","victor","whiskey","x-ray"},
                 new string[]{"yankee","zulu","fixo","over"}};
                for (int j = 0; j < numCols; j++)
                {
                    tb.Columns[j].Width = wids[j];
                    tb.Columns[j].Alignment = CellAlignment.MiddleCenter;
                    short color=16;
                    if (j > 0)  color = 16;
                    tb.Columns[j].ContentColor = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, color);
                }
                for (int i = 1; i <= numRows; i++)
                {
                    tb.Rows[i].Height = rowHeight; tb.Rows[i].TextStyleId = db.Textstyle;
                    //tb.Rows[i].TextStyleId = txtId '<-- potential crash of Acad, you can  use SetTextStyle method also, not sure about, maybe it obsolete in this Acad version
                    tb.Rows[i].Borders.Horizontal.Margin = rowHeight * 0.1;
                    tb.Rows[i].Borders.Vertical.Margin = rowHeight * 0.1;
                }

                // Align Title text to center
                tb.Rows[0].Alignment = CellAlignment.MiddleCenter;
                tb.Rows[0].ContentColor = Color.FromRgb(255, 200, 36);
                // Populate the contents of the header and data sections
                // int n = 0;
                for (int i = 1; i <= numRows; i++)
                {
                    string[] items = tabledata[i - 1];
                    // tb.Rows[i].Style = "Data";

                    for (int j = 0; j <= numCols - 1; j++)
                    {
                        Cell c = tb.Cells[i, j];
                        c.Contents.Add();
                        c.Contents[0].TextHeight = txtHeight;
                        string txt = items[j];
                        c.Contents[0].TextString = txt;
                        c.Alignment = CellAlignment.MiddleCenter;
                        // Set the vertical margins
                        c.Borders.Top.Margin = verMarg;
                        c.Borders.Bottom.Margin = verMarg;
                        // Set the horizontal margins
                        c.Borders.Left.Margin = horMarg;
                        c.Borders.Right.Margin = horMarg;
                    }
                }
                tb.Rows[1].Alignment = CellAlignment.MiddleCenter;
                tb.InsertRows(1, rowHeight, 2);
                tb.Rows[1].BackgroundColor = Color.FromRgb(226, 214, 187);
                tb.Rows[2].BackgroundColor = Color.FromRgb(226, 214, 187);
               
               CellRange mcells = CellRange.Create(tb, 1, 0, 1, 1);
               tb.MergeCells(mcells);
               Cell mc = tb.Cells[1, 0];
               mc.Contents.Add();
               mc.Contents[0].TextHeight = txtHeight;
               string mtxt = "Merged";
               mc.Contents[0].TextString = mtxt;
               mc.Alignment = CellAlignment.MiddleCenter;


               mcells = CellRange.Create(tb, 2, 1, 2, 2);
               tb.MergeCells(mcells);
                mc = tb.Cells[2, 1];
               mc.Contents.Add();
               mc.Contents[0].TextHeight = txtHeight;
                mtxt = "Merged";
               mc.Contents[0].TextString = mtxt;
               mc.Alignment = CellAlignment.MiddleCenter;

               mcells = CellRange.Create(tb, 1, 3, 2, 3);
               tb.MergeCells(mcells);
               mc = tb.Cells[1, 3];
               mc.Contents.Add();
               mc.Contents[0].TextHeight = txtHeight;
               mtxt = "Merged";
               mc.Contents[0].TextString = mtxt;
               mc.Alignment = CellAlignment.MiddleCenter;

               //tb.Height = tb.Rows.Count * rowHeight; //<-- optional

               tb.Rows[0].Height *=2.0;
                // insert very last row
               tb.InsertRows(tb.Rows.Count, rowHeight, 1);
               tb.Rows[tb.Rows.Count-1].Style = "Data";
                // merge the first 3 cells in row
               mcells = CellRange.Create(tb, tb.Rows.Count-1, 0, tb.Rows.Count-1, 2);
               tb.MergeCells(mcells);
               mc = tb.Cells[tb.Rows.Count-1, 0];
               mc.Contents.Add();
               mc.Contents[0].TextHeight = txtHeight;
               mtxt = "Total:";
               mc.Contents[0].TextString = mtxt;
               mc.Alignment = CellAlignment.MiddleRight;

                // alternate coloring rows
               for (int i = 3; i < tb.Rows.Count-1; i++)
               {
                   if (i % 2 == 0)
                       tb.Rows[i].BackgroundColor = Color.FromRgb(241, 238, 234);
                   else tb.Rows[i].BackgroundColor = Color.FromRgb(233, 241, 246);

               }
               tb.Rows[tb.Rows.Count - 1].BackgroundColor = Color.FromRgb(222, 248, 242);
                tb.GenerateLayout();
                 tb.SuppressRegenerateTable(false); //<-- optional

                 btr.AppendEntity(tb);

                tr.AddNewlyCreatedDBObject(tb, true);
               
                tr.Commit();
                // change lwdisplay to on so the display will be show the table lineweight
                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("lwdisplay", 1);
               
            }
        }

5
Blocks / Write selected blocks to .csv file
« on: July 01, 2013, 08:24:18 PM »
Code: [Select]
        [CommandMethod("BCSV")]
        public static void WriteBlocksToCSV()
        {
            System.Globalization.CultureInfo oldcult = System.Threading.Thread.CurrentThread.CurrentCulture;
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("EN-us");

            Database db = HostApplicationServices.WorkingDatabase;
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            string fname = @"C:\Test\Block_PART.csv";


            // Enter block name to be written
            PromptStringOptions psto = new PromptStringOptions("\nEnter block name: ");
            psto.AllowSpaces = true;
            PromptResult res;
            res = ed.GetString(psto);
            if (res.Status != PromptStatus.OK)
                return;
            string blkname = res.StringResult;

            ed.WriteMessage("\nBlock Name Entered:\t{0}", blkname);

            // put appropriate delimiter here I've used semicolon (it's default delimiter on my local machine)
            string sep = ";";

            Matrix3d mtx = ed.CurrentUserCoordinateSystem;
            List<string> data = new List<string>();
            PromptSelectionOptions pso = new PromptSelectionOptions();
            pso.MessageForRemoval = "\nNothing selected, try again...";
            pso.MessageForAdding = "\nPlease select blocks on screen: ";
            TypedValue[] tv = new TypedValue[] { new TypedValue(0, "insert"), new TypedValue(2, blkname), new TypedValue(66, 1) };
            SelectionFilter filter = new SelectionFilter(tv);
            PromptSelectionResult psr = ed.GetSelection(pso, filter);

            if (psr.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\nSelection Result: {0}", psr.Status);
                return;
            }

            SelectionSet sset = psr.Value;
            ed.WriteMessage("\nSelected blocks: {0}", sset.Count);
            if (sset.Count == 0)
            {
                ed.WriteMessage("\nNothing Selected, exit...");
                return;
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                try
                {
                    string headers = string.Format("{0}{8}{1:f3}{8}{2:f3}{8}{3:f3}{8}{4:f3}{8}{5:f3}{8}{6:f3}{8}{7:f3}{8}{9}",
                                "HANDLE", "X_Coordinate", "Y_Coordinate", "Z_Coordinate", "Rotation", "X_Scale", "Y_Scale", "Z_Scale", sep, "Attributes >>");
                    data.Add(headers);
                    foreach (SelectedObject sobj in sset)
                    {
                        ObjectId id = sobj.ObjectId;
                        Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                        if (ent == null) return;
                        BlockReference bref = ent as BlockReference;
                        if (bref == null) return;
                        string hdl = bref.Handle.ToString();
                        Point3d pp = bref.Position.TransformBy(Matrix3d.Identity);
                        double rot = bref.Rotation;
                        Scale3d scl = bref.ScaleFactors;
                        AttributeCollection attids = bref.AttributeCollection;
                        string attvalues = sep;
                        foreach (ObjectId attid in attids)
                        {
                            AttributeReference attref = tr.GetObject(attid, OpenMode.ForRead) as AttributeReference;
                            string attval = attref.TextString;
                            // to avoid writing text like 04-01 as "04 Jan." in csv file add single quote at the start
                            if (attval.Contains("-")) attval = string.Format("'{0}", attval);
                            attvalues = attvalues + attval + sep;
                        }
                        attvalues = attvalues.TrimEnd(',');
                        // create delimted text line for every block
                        string strtmp = string.Format("{0}{8}{1:f3}{8}{2:f3}{8}{3:f3}{8}{4:f3}{8}{5:f3}{8}{6:f3}{8}{7:f3}{9}",
                                hdl, pp.X, pp.Y, pp.Z, rot, scl.X, scl.Y, scl.Z, sep, attvalues);

                        data.Add(strtmp);
                    }
                    if (data.Count > 1)
                    {
                        try
                        {
                            if (File.Exists(fname))
                            {
                             // delete existing file
                            File.Delete(fname);// to write always to newly created file
                            }
                            using (StreamWriter sw = new StreamWriter(fname, true, Encoding.Default, 4096))
                            {
                                foreach (string coords in data)
                                {
                                    sw.WriteLine(coords);
                                }

                            }

                        }
                        catch (IOException iex)
                        {
                            ed.WriteMessage("\nError while processing the file.:\n{0}\n", iex.Message);

                        }
                        catch (System.Exception ex)
                        {
                            ed.WriteMessage("\nError writinging data to file.:\n{0}\n", ex.Message);

                        }

                    }

                }
                catch (Autodesk.AutoCAD.Runtime.Exception acex)
                {
                    ed.WriteMessage("\nError occurs in AutoCAD drawing.:\n{0}\n", acex.ToString());
                }
                catch (System.Exception sys)
                {
                    ed.WriteMessage("\nError:\n{0}\n", sys.ToString());
                }
                finally
                {

                    System.Diagnostics.Process.Start(fname);
                    ed.WriteMessage("\n\t---\tDone!\t---\n");
                    System.Threading.Thread.CurrentThread.CurrentCulture = oldcult;
                }
            }
        }

6
     
   C#
   
Code: [Select]

[CommandMethod("liso")]
        public static void testLayerIsol()
        {
            Database db = HostApplicationServices.WorkingDatabase;

            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            PromptEntityOptions opt = new PromptEntityOptions( "\nSelect an entity :");

                PromptEntityResult res = ed.GetEntity(opt);

                if (res.Status != PromptStatus.OK) return;
     
                    ObjectId entId=  res.ObjectId;
                   
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Entity ent= tr.GetObject(entId, OpenMode.ForRead) as Entity;

                if (ent==null) return;

                string lname= ent.Layer;

                using (LayerTable lt = db.LayerTableId.GetObject(OpenMode.ForRead, false) as LayerTable)
                {
                 
                    db.Clayer=lt[lname];
               
                    foreach (ObjectId layId in lt)
                    {

                        if (layId != lt[lname])
                        {
                            LayerTableRecord ltr = tr.GetObject(layId, OpenMode.ForWrite, false) as LayerTableRecord;

                            if ((!ltr.IsDependent) && ((!ltr.Name.Contains("*|*")) | (!ltr.Name.Contains("X*"))))
                            {
                                ltr.IsOff = true;

                            }
                        }
                    }
       
                }
                tr.Commit();
            }
        }


   
Code: [Select]

        [CommandMethod("loff")]
        public static void testLayersOff()
           {
            Database db = HostApplicationServices.WorkingDatabase;

            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            PromptEntityOptions opt = new PromptEntityOptions( "\nSelect an entity :");

                PromptEntityResult res = ed.GetEntity(opt);

                if (res.Status != PromptStatus.OK) return;
     
                    ObjectId entId=  res.ObjectId;
                   
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Entity ent= tr.GetObject(entId, OpenMode.ForRead) as Entity;

                if (ent==null) return;

                string lname= ent.Layer;

                using (LayerTable lt = db.LayerTableId.GetObject(OpenMode.ForRead, false) as LayerTable)
                {
                   LayerTableRecord clayer = tr.GetObject(db.Clayer, OpenMode.ForRead) as LayerTableRecord;  //current layer
                   
                    if (lt[lname]==db.Clayer)
                    {
                        Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Could not turn off the current layer.");

                        return;
                    }
                    LayerTableRecord ltr = tr.GetObject(lt[lname], OpenMode.ForWrite, false) as LayerTableRecord;

                    if ((!ltr.IsDependent) && ((!ltr.Name.Contains("*|*")) | (!ltr.Name.Contains("X*"))))
                    {
                        ltr.IsOff = true;
                    }           
                }
                tr.Commit();
            }
        }


   VB.NET
   
Code: [Select]

        <CommandMethod("liso")> _
        Public Shared Sub testLayerIsol()
            Dim db As Database = HostApplicationServices.WorkingDatabase

            Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor

            Dim opt As New PromptEntityOptions(vbLf & "Select an entity :")

            Dim res As PromptEntityResult = ed.GetEntity(opt)

            If res.Status <> PromptStatus.OK Then
                Return
            End If

            Dim entId As ObjectId = res.ObjectId

            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim ent As Entity = TryCast(tr.GetObject(entId, OpenMode.ForRead), Entity)

                If ent Is Nothing Then
                    Return
                End If

                Dim lname As String = ent.Layer

                Using lt As LayerTable = TryCast(db.LayerTableId.GetObject(OpenMode.ForRead, False), LayerTable)

                    db.Clayer = lt(lname)

                    For Each layId As ObjectId In lt

                        If layId <> lt(lname) Then
                            Dim ltr As LayerTableRecord = TryCast(tr.GetObject(layId, OpenMode.ForWrite, False), LayerTableRecord)

                            If (Not ltr.IsDependent) AndAlso ((Not ltr.Name.Contains("*|*")) Or (Not ltr.Name.Contains("X*"))) Then

                                ltr.IsOff = True
                            End If
                        End If

                    Next
                End Using
                tr.Commit()
            End Using
        End Sub


   
Code: [Select]

        <CommandMethod("loff")> _
        Public Shared Sub testLayersOff()
            Dim db As Database = HostApplicationServices.WorkingDatabase

            Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor

            Dim opt As New PromptEntityOptions(vbLf & "Select an entity :")

            Dim res As PromptEntityResult = ed.GetEntity(opt)

            If res.Status <> PromptStatus.OK Then
                Return
            End If

            Dim entId As ObjectId = res.ObjectId

            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim ent As Entity = TryCast(tr.GetObject(entId, OpenMode.ForRead), Entity)

                If ent Is Nothing Then
                    Return
                End If

                Dim lname As String = ent.Layer

                Using lt As LayerTable = TryCast(db.LayerTableId.GetObject(OpenMode.ForRead, False), LayerTable)
                    Dim clayer As LayerTableRecord = TryCast(tr.GetObject(db.Clayer, OpenMode.ForRead), LayerTableRecord)
                    'current layer
                    If lt(lname) = db.Clayer Then
                        Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Could not turn off the current layer.")

                        Return
                    End If
                    Dim ltr As LayerTableRecord = TryCast(tr.GetObject(lt(lname), OpenMode.ForWrite, False), LayerTableRecord)

                    If (Not ltr.IsDependent) AndAlso ((Not ltr.Name.Contains("*|*")) Or (Not ltr.Name.Contains("X*"))) Then
                        ltr.IsOff = True
                    End If
                End Using
                tr.Commit()
            End Using
        End Sub

7
Text / Autonumbering with prefix
« on: May 30, 2013, 10:44:34 PM »
   VB.NET
Code: [Select]
#Region "AutoNumbering with prefix"

        ''' <summary>
        '''  Function to return increment string
        ''' </summary>
        ''' <param name="prefix"></param>
        ''' <param name="start"></param>
        ''' <param name="rate"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Shared Function TextInc(prefix As String, start As String, rate As Integer) As String
            Dim result As String = ""
            Dim head As String = ""
            Dim szero As Boolean = False
            Dim leg As Integer = (prefix & start).Length
            If start.StartsWith("0") Then
                szero = True
                Dim pos As Integer = start.LastIndexOf("0")

                For n As Integer = 0 To pos
                    head = head & "0"
                Next
            End If
            Dim num As Integer = Convert.ToInt32(start) + rate

            If szero Then
                result = String.Concat(prefix, head, num.ToString())
                If result.Length > leg Then
                    If head.Length > 1 Then
                        result = String.Concat(prefix, head.Remove(1, result.Length - leg), num.ToString())
                    Else
                        result = String.Concat(prefix, num.ToString())
                    End If
                End If
            Else
                result = String.Concat(prefix, num.ToString())
            End If
            Return result

        End Function

        ''' <summary>
        '''  Command for autonumbering with text with prefix
        ''' </summary>
        <CommandMethod("inm")> _
        Public Shared Sub IncrementWithFrame()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim ucs As Matrix3d = ed.CurrentUserCoordinateSystem
            ' Get or discard prefix as string entered by the user
            Dim pso As New PromptStringOptions(vbLf & vbTab & "Enter prefix or press Enter w/o it: ")
            pso.AllowSpaces = True
            pso.DefaultValue = ""
            Dim res As PromptResult
            res = ed.GetString(pso)
            If res.Status <> PromptStatus.OK Then
                Return
            End If

            Dim pfx As String = res.StringResult
            Dim pos As Integer = pfx.Length
            ed.WriteMessage(vbLf & "Prefix Entered:" & vbTab & "{0}", pfx)
            ' Get initial number as string entered by the user
            pso = New PromptStringOptions(vbLf & "Enter initial number  : ")
            pso.UseDefaultValue = True
            pso.DefaultValue = "0001"

            res = ed.GetString(pso)
            If res.Status <> PromptStatus.OK Then
                Return
            End If

            Dim strnum As String = res.StringResult
            ed.WriteMessage(vbLf & "initial number:" & vbTab & "{0}", strnum)

            Dim pio As New PromptIntegerOptions("")
            pio.Message = vbLf & "Enter an increment step: "

            ' Restrict input to positive and non-negative values
            pio.AllowZero = False
            pio.AllowNegative = False
            ' Add default value
            pio.DefaultValue = 1
            pio.AllowNone = True

            ' Get step value entered by the user
            Dim ires As PromptIntegerResult = ed.GetInteger(pio)
            If ires.Status <> PromptStatus.OK Then
                Return
            End If

            Dim rate As Integer = ires.Value

            ed.WriteMessage(vbLf & "Step entered" & vbTab & "{0}", rate)
            ' Get gap value entered by the user
            Dim pdo As New PromptDoubleOptions(vbLf & "Enter the gap size between text and frame  : ")
            pdo.AllowNone = True
            pdo.UseDefaultValue = True
            pdo.DefaultValue = db.Textsize / 2

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

            Dim gap As Double = dbres.Value

            ed.WriteMessage(vbLf & "Gap Entered" & vbTab & "{0}", gap)
            ' using a current textsize
            Dim txtheight As Double = db.Textsize

            Using tr As Transaction = db.TransactionManager.StartTransaction()

                doc.TransactionManager.EnableGraphicsFlush(True)

                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                Dim ppo As New PromptPointOptions(vbLf & vbTab & "Specify text insertion point (Enter to stop): ")
                ppo.AllowNone = True
                Dim ptres As PromptPointResult
                Dim n As Integer = 0

                Dim txt As String = ""
                ' get text points multiple
                Do
                    Dim pt As New Point3d()
                    ptres = ed.GetPoint(ppo)

                    If ptres.Status = PromptStatus.OK Then
                        pt = ptres.Value
                        Dim otext As New DBText()
                        otext.Position = pt
                        otext.VerticalMode = TextVerticalMode.TextVerticalMid
                        otext.HorizontalMode = TextHorizontalMode.TextMid
                        otext.AlignmentPoint = otext.Position
                        otext.AdjustAlignment(db)
                        If n = 0 Then

                            txt = TextInc(pfx, strnum, 0)
                        Else
                            txt = TextInc(pfx, strnum, rate)
                        End If

                        otext.TextString = txt

                        n += 1
                        strnum = txt.TrimStart(pfx.ToCharArray())

                        btr.AppendEntity(otext)
                        tr.AddNewlyCreatedDBObject(otext, True)
                        tr.TransactionManager.QueueForGraphicsFlush()
                        Dim plan As Plane = otext.GetPlane()
                        Dim ext As Extents3d = otext.GeometricExtents
                        Dim bl As Point3d = ext.MinPoint
                        Dim ur As Point3d = ext.MaxPoint
                        Dim mp As Point3d = New Point3d((bl.X + ur.X) / 2, (bl.Y + ur.Y) / 2, (bl.Z + ur.Z) / 2).TransformBy(ucs)
                        otext.Position = mp
                        otext.AlignmentPoint = otext.Position
                        otext.AdjustAlignment(db)

                        Dim br As New Point3d(ur.X, bl.Y, bl.Z)
                        Dim ul As New Point3d(bl.X, ur.Y, bl.Z)
                        bl = bl.Subtract(New Vector3d(gap, gap, 0)).TransformBy(ucs)
                        ur = ur.Subtract(New Vector3d(-gap, -gap, 0)).TransformBy(ucs)
                        br = br.Subtract(New Vector3d(-gap, gap, 0)).TransformBy(ucs)
                        ul = ul.Subtract(New Vector3d(gap, -gap, 0)).TransformBy(ucs)
                        Dim poly As New Polyline()
                        poly.AddVertexAt(0, bl.Convert2d(plan), 0, 0, 0)
                        poly.AddVertexAt(0, br.Convert2d(plan), 0, 0, 0)
                        poly.AddVertexAt(0, ur.Convert2d(plan), 0, 0, 0)
                        poly.AddVertexAt(0, ul.Convert2d(plan), 0, 0, 0)
                        poly.Closed = True
                        poly.ColorIndex = 1
                        btr.AppendEntity(poly)
                        tr.AddNewlyCreatedDBObject(poly, True)

                        tr.TransactionManager.QueueForGraphicsFlush()

                    End If
                Loop While ptres.Status = PromptStatus.OK
                doc.TransactionManager.FlushGraphics()
                tr.Commit()
            End Using

        End Sub
#End Region


   C#
Code: [Select]
        /// <summary>
          /// function to return increment string
        /// </summary>
        /// <param name="prefix"></param>
        /// <param name="start"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        private static string TextInc(string prefix, string start, int step)
        {
            string result = "";
            string head = "";
            bool szero = false;
            int leg = (prefix + start).Length;
            if (start.StartsWith("0"))
            {
                szero = true;
                int pos = start.LastIndexOf("0");

                for (int n = 0; n <= pos; n++)
                    head = head + "0";
            }
            int num = Convert.ToInt32(start) + step;

            if (szero)
            {
                result = String.Concat(prefix, head, num.ToString());
                if (result.Length > leg)
                {
                    if (head.Length > 1)
                        result = String.Concat(prefix, head.Remove(1, result.Length - leg), num.ToString());
                    else
                        result = String.Concat(prefix, num.ToString());
                }
            }
            else
            {
                result = String.Concat(prefix, num.ToString());
            }
            return result;

        }

        /// <summary>
        ///  Command for autonumbering with text with prefix
        /// </summary>
        [CommandMethod("inm")]
        public static void IncrementWithFrame()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            // Get or discard prefix as string entered by the user
            PromptStringOptions pso =
                 new PromptStringOptions("\n\tEnter prefix or press Enter w/o it: ");
            pso.AllowSpaces = true;
            pso.DefaultValue = "";
            PromptResult res;
            res = ed.GetString(pso);
            if (res.Status != PromptStatus.OK)  return;

            string pfx = res.StringResult;
            int pos = pfx.Length;
            ed.WriteMessage("\nPrefix Entered:\t{0}", pfx);
            // Get initial number as string entered by the user
            pso = new PromptStringOptions("\nEnter initial number  : ");
            pso.UseDefaultValue = true;
            pso.DefaultValue = "0001";

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

            string strnum = res.StringResult;
            ed.WriteMessage("\ninitial number:\t{0}", strnum);

            PromptIntegerOptions pio = new PromptIntegerOptions("");
            pio.Message = "\nEnter an increment step: ";

            // Restrict input to positive and non-negative values
            pio.AllowZero = false;
            pio.AllowNegative = false;
            // Add default value
            pio.DefaultValue = 1;
            pio.AllowNone = true;

            // Get step value entered by the user
            PromptIntegerResult ires = ed.GetInteger(pio);
            if (ires.Status != PromptStatus.OK) return;

            int step = ires.Value;

            ed.WriteMessage("\nStep entered\t{0}", step);
            // Get gap value entered by the user
            PromptDoubleOptions pdo =
                           new PromptDoubleOptions("\nEnter the gap size between text and frame  : ");
            pdo.AllowNone = true;
            pdo.UseDefaultValue = true;
            pdo.DefaultValue = db.Textsize / 2;

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

            double gap = dbres.Value;

            ed.WriteMessage("\nGap Entered\t{0}", gap);
            // using a current textsize
            double txtheight = db.Textsize;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {

                doc.TransactionManager.EnableGraphicsFlush(true);

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

                PromptPointOptions ppo = new PromptPointOptions("\n\tSpecify text insertion point (Enter to stop): ");
                ppo.AllowNone = true;
                PromptPointResult ptres;
                int n = 0;

                string txt = "";
                // get text points multiple
                do
                {
                    Point3d pt = new Point3d();
                    ptres = ed.GetPoint(ppo);

                    if (ptres.Status == PromptStatus.OK)
                    {
                        pt = ptres.Value;
                        DBText otext = new DBText();
                        otext.Position = pt;
                        otext.VerticalMode = TextVerticalMode.TextVerticalMid;
                        otext.HorizontalMode = TextHorizontalMode.TextMid;
                        otext.AlignmentPoint = otext.Position;
                        otext.AdjustAlignment(db);
                        if (n == 0)
                        {
                            txt = TextInc(pfx, strnum, 0);

                        }
                        else
                            txt = TextInc(pfx, strnum, step);

                        otext.TextString = txt;
                       
                        n += 1;
                        strnum = txt.TrimStart(pfx.ToCharArray());
                       
                        btr.AppendEntity(otext);
                        tr.AddNewlyCreatedDBObject(otext, true);
                        tr.TransactionManager.QueueForGraphicsFlush();
                        Plane plan = otext.GetPlane();
                        Extents3d ext = otext.GeometricExtents;
                        Point3d bl = ext.MinPoint;
                        Point3d ur = ext.MaxPoint;
                        Point3d mp = new Point3d((bl.X + ur.X) / 2, (bl.Y + ur.Y) / 2, (bl.Z + ur.Z) / 2).TransformBy(ucs);
                        otext.Position = mp;
                        otext.AlignmentPoint = otext.Position;
                        otext.AdjustAlignment(db);

                        Point3d br = new Point3d(ur.X, bl.Y, bl.Z);
                        Point3d ul = new Point3d(bl.X, ur.Y, bl.Z);
                        bl = bl.Subtract(new Vector3d(gap, gap, 0)).TransformBy(ucs);
                        ur = ur.Subtract(new Vector3d(-gap, -gap, 0)).TransformBy(ucs);
                        br = br.Subtract(new Vector3d(-gap, gap, 0)).TransformBy(ucs);
                        ul = ul.Subtract(new Vector3d(gap, -gap, 0)).TransformBy(ucs);
                        Polyline poly = new Polyline();
                        poly.AddVertexAt(0, bl.Convert2d(plan), 0, 0, 0);
                        poly.AddVertexAt(0, br.Convert2d(plan), 0, 0, 0);
                        poly.AddVertexAt(0, ur.Convert2d(plan), 0, 0, 0);
                        poly.AddVertexAt(0, ul.Convert2d(plan), 0, 0, 0);
                        poly.Closed = true;
                        poly.ColorIndex = 1;
                        btr.AppendEntity(poly);
                        tr.AddNewlyCreatedDBObject(poly, true);
                        tr.TransactionManager.QueueForGraphicsFlush();

                    }

                } while (ptres.Status == PromptStatus.OK);
                doc.TransactionManager.FlushGraphics();
                tr.Commit();
            }

        }

8
Layouts and printing / Rename layouts custom way
« on: May 19, 2013, 02:37:37 PM »
   
Code: [Select]
VB.NET
        'Public Class LayoutTools

        ' declare layout names outside of method, keep them empty:
        Private oldname As String = ""
        Private newname As String = ""
        <CommandMethod("lre")> _
        Public Sub testLayoutsRename()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim db As Database = HostApplicationServices.WorkingDatabase
            Dim ed As Editor = doc.Editor
            Dim tr As Transaction = db.TransactionManager.StartTransaction()

            Dim ltnames As New SortedList(Of String, String)()
           ' lst of pairs <old layout name,new layout name>: '
            ltnames.Add("Layout1", "General")
            ltnames.Add("Layout2", "Floor Plan 1")
            ltnames.Add("Layout3", "Floor Plan 2")
            ltnames.Add("Layout4", "Floor Plan 3")
            '   ETC ...
            Dim lm As LayoutManager = LayoutManager.Current
            Dim lyid As ObjectId = ObjectId.Null
            Try
                Using tr
                    For Each kvp As KeyValuePair(Of String, String) In ltnames
                        oldname = kvp.Key
                        newname = kvp.Value
                        lyid = lm.GetLayoutId(oldname)

                        If lm.GetLayoutId(oldname) <> ObjectId.Null Then
                            Dim lt As Layout = TryCast(tr.GetObject(lyid, OpenMode.ForWrite), Layout)

                            AddHandler lm.LayoutRenamed, AddressOf lm_LayoutRenamed
                            AddHandler lm.LayoutToBeRenamed, AddressOf lm_LayoutToBeRenamed
                            lt.LayoutName = newname
                        End If
                    Next
                    tr.Commit()
                    ed.Regen()
                End Using
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "Error Reason: {0}" & vbLf, ex.ErrorStatus)
                Return
            End Try

        End Sub

        Private Sub lm_LayoutRenamed(sender As Object, e As LayoutRenamedEventArgs)
            Dim newmame As String = ""
            Try
                newmame = e.NewName
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "Invalid layout name: {0}" & vbLf & "{1}", e.NewName, ex.ErrorStatus)
                Return
            End Try

        End Sub
        Private Sub lm_LayoutToBeRenamed(sender As Object, e As LayoutRenamedEventArgs)
            Try
                SymbolUtilityServices.ValidateSymbolName(oldname, False)
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "Invalid layout name: {0}" & vbLf & "{1}", e.NewName, ex.ErrorStatus)
                Return
            End Try

        End Sub

        ' End Class 'end of class

   C#

   
Code: [Select]
        // public class LayoutTools
        // {
        // declare layout names outside of method, keep them empty:
        string oldname = ""; string newname = "";
        [CommandMethod("lre")]
        public void testLayoutsRename()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = doc.Editor;
            Transaction tr = db.TransactionManager.StartTransaction();

            SortedList<string, string> ltnames = new SortedList<string, string>();
           // lst of pairs <old layout name,new layout name>: //
            ltnames.Add("Layout1", "General");
            ltnames.Add("Layout2", "Floor Plan 1");
            ltnames.Add("Layout3", "Floor Plan 2");
            ltnames.Add("Layout4", "Floor Plan 3");//   ETC ...
            LayoutManager lm = LayoutManager.Current;
            ObjectId lyid = ObjectId.Null;
            try
            {
                using (tr)
                {
                    foreach (KeyValuePair<string, string> kvp in ltnames)
                    {
                        oldname = kvp.Key; newname = kvp.Value;
                        lyid = lm.GetLayoutId(oldname);

                        if (lm.GetLayoutId(oldname) != ObjectId.Null)
                        {
                            Layout lt = tr.GetObject(lyid, OpenMode.ForWrite) as Layout;

                            lm.LayoutRenamed += new LayoutRenamedEventHandler(lm_LayoutRenamed);
                            lm.LayoutToBeRenamed += new LayoutRenamedEventHandler(lm_LayoutToBeRenamed);
                            lt.LayoutName = newname;
                        }
                    }
                    tr.Commit();
                    ed.Regen();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    "\nRerror Reason: {0}\n", ex.ErrorStatus);
                return;
            }

        }

        private void lm_LayoutRenamed(object sender, LayoutRenamedEventArgs e)
        {
            string newmame = "";
            try
            {
                newmame = e.NewName;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    "\nInvalid layout name: {0}\n{1}", e.NewName, ex.ErrorStatus);
                return;
            }

        }
        private void lm_LayoutToBeRenamed(object sender, LayoutRenamedEventArgs e)
        {
            try
            {
                SymbolUtilityServices.ValidateSymbolName(oldname, false);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    "\nInvalid layout name: {0}\n{1}", e.NewName, ex.ErrorStatus);
                return;
            }

        }

    //}// end of class
 

9

See for more an article written  by Fenton Webb here
http://adndevblog.typepad.com/autocad/2013/05/change-the-background-mask-property-of-acdbmtext-object-programmatically-using-objectarx.html
   VB.NET
   
Code: [Select]
        Public Shared Function fixoGetEntity(tr As Transaction, ed As Editor, rx As RXClass, msg As String, ByRef id As ObjectId) As ErrorStatus
            Dim es As ErrorStatus
            Dim ent As Entity
            id = ObjectId.Null
            Dim peo As New PromptEntityOptions(msg)
            peo.SetRejectMessage(vbLf & "You're missing, try again >>")
            peo.AddAllowedClass(GetType(Entity), False)
            Dim res As PromptEntityResult
            res = ed.GetEntity(peo)
            If res.Status <> PromptStatus.OK Then
                es = ErrorStatus.PointNotOnEntity
            End If
            id = res.ObjectId
            If id = ObjectId.Null Then
                es = ErrorStatus.NullObjectId
            End If
            ent = TryCast(tr.GetObject(id, OpenMode.ForRead, False), Entity)
            If ent.GetRXClass() <> rx Then
                ed.WriteMessage(vbLf & "{0}Must be a type of ""{0}"" only!", rx.DxfName)
                es = ErrorStatus.NotThatKindOfClass
            End If
            If ent Is Nothing Then
                es = ErrorStatus.NotAnEntity
            Else
                es = ErrorStatus.OK
            End If
            Return es
        End Function
        <CommandMethod("BM")> _
        Public Shared Sub test_setBackgroundFill_MText()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

            Dim ed As Editor = doc.Editor

            Dim db As Database = HostApplicationServices.WorkingDatabase

            Dim id As ObjectId = ObjectId.Null

            Using tr As Transaction = db.TransactionManager.StartTransaction()
                If fixoGetEntity(tr, ed, RXClass.GetClass(GetType(MText)), vbLf & "Please pick an MText entity: ", id) = ErrorStatus.OK Then

                    Dim btr As BlockTableRecord = TryCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                    ' get entity by direct cast
                    Dim ent As Entity = DirectCast(tr.GetObject(id, OpenMode.ForRead), Entity)

                    If id.ObjectClass.DxfName = "MTEXT" Then
                        Dim mtx As MText = TryCast(ent, MText)

                        mtx.UpgradeOpen()

                        Dim color As Autodesk.AutoCAD.Colors.Color

                        If mtx.BackgroundFill Then

                            mtx.UseBackgroundColor = False


                            mtx.BackgroundFill = False
                        Else

                            mtx.BackgroundFill = True

                            color = color.FromColorIndex(ColorMethod.ByAci, CInt(1))

                            mtx.BackgroundFillColor = color


                            mtx.UseBackgroundColor = False
                        End If

                        mtx.RecordGraphicsModified(True)
                    End If
                End If
                tr.Commit()
            End Using
        End Sub

   C#
   
Code: [Select]
        public static ErrorStatus fixoGetEntity(Transaction tr, Editor ed, RXClass rx, string msg, out ObjectId id)
        {
            ErrorStatus es;
            Entity ent;
            id = ObjectId.Null;
            PromptEntityOptions peo = new PromptEntityOptions(msg);
            peo.SetRejectMessage("\nYou're missing, try again >>");
            peo.AddAllowedClass(typeof(Entity), false);
            PromptEntityResult res;
            res = ed.GetEntity(peo);
            if (res.Status != PromptStatus.OK)
                es = ErrorStatus.PointNotOnEntity;
            id = res.ObjectId;
            if (id == ObjectId.Null)
                es = ErrorStatus.NullObjectId;
            ent = tr.GetObject(id, OpenMode.ForRead, false) as Entity;
            if (ent.GetRXClass() != rx)
            {
                ed.WriteMessage("\n{0}Must be a type of \"{0}\" only!", rx.DxfName);
                es = ErrorStatus.NotThatKindOfClass;
            }
            if (ent == null)
                es = ErrorStatus.NotAnEntity;
            else es = ErrorStatus.OK;
            return es;
        }
        [CommandMethod("BM")]
        static public void test_setBackgroundFill_MText()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Database db = HostApplicationServices.WorkingDatabase;

            ObjectId id = ObjectId.Null;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                if (fixoGetEntity(tr, ed, RXClass.GetClass(typeof(MText)), "\nPlease pick an MText entity: ", out id) == ErrorStatus.OK)
                {

                    BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                   // get entity by direct cast
                    Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);

                    if (id.ObjectClass.DxfName == "MTEXT")
                    {
                        MText mtx = ent as MText;

                        mtx.UpgradeOpen();

                        Autodesk.AutoCAD.Colors.Color color;

                        if (mtx.BackgroundFill )
                        {

                            mtx.UseBackgroundColor= false;

                            mtx.BackgroundFill=false;

                        }

                        else
                        {

                            mtx.BackgroundFill=true;

                            color = Color.FromColorIndex(ColorMethod.ByAci, (int)1);

                            mtx.BackgroundFillColor = color;
                           
                            mtx.UseBackgroundColor=false;

                        }

                        mtx.RecordGraphicsModified(true);

                    }
                }
                tr.Commit();
            }
        }

10
Layers / Create new layer by selecting a single object
« on: May 12, 2013, 09:03:47 PM »
      This code example about how to create a new layer that has same properties as the layer that already exist in a drawing,
      by select single entity on existing this layer and then copy properties from

       
Code: [Select]

       [CommandMethod("CopyLayerFromObject")]

        public void testCopyLayer()
        {

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

            Database db = doc.Database;

            Editor ed = doc.Editor;

            PromptStringOptions sopts = new PromptStringOptions("\nEnter new layer name :");

            sopts.AllowSpaces = true;

            PromptResult stres = ed.GetString(sopts);

            if (stres.Status != PromptStatus.OK) return;
            // get new layer name
            string layerName = stres.StringResult;

            PromptSelectionOptions opts = new PromptSelectionOptions();

            opts.MessageForRemoval = "Wrong selection, try again.";

            opts.MessageForAdding = "Select single object to copy layer from: ";

            opts.SingleOnly = true;

            opts.SinglePickInSpace = true;
            // select single object
            PromptSelectionResult selRes = ed.GetSelection(opts);

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

            ObjectId entId = selRes.Value.GetObjectIds()[0];

            // open transaction

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                LayerTable ltb = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
                // get entity
                Entity ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);
                // get entity layer
                string oldname = ent.Layer;
                // get LayerTableRecord by name
                LayerTableRecord oldLtr = (LayerTableRecord)tr.GetObject(ltb[oldname], OpenMode.ForRead);
                // check if layer exists
                if (!ltb.Has(layerName))
                {
                    ltb.UpgradeOpen();

                    //create new layer
                    LayerTableRecord ltr = new LayerTableRecord();
                    // copy properties from entity layer
                    ltr.CopyFrom(oldLtr);
                    // add new layer name
                    ltr.Name = layerName;
                    // here you can to add other properties to a layer: linetype, color etc
                    //
                    // add layer to LayerTable
                    ltb.Add(ltr);
                    // confirm transaction
                    tr.AddNewlyCreatedDBObject(ltr, true);

                }
                // end command if layer exist
                else
                {
                    return;
                }

                tr.Commit();

            }//end using transaction

        }

   VB.NET
Code: [Select]
        <CommandMethod("CopyLayerFromObject")> _
        Public Sub testCopyLayer()

            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

            Dim db As Database = doc.Database

            Dim ed As Editor = doc.Editor

            Dim sopts As New PromptStringOptions(vbLf & "Enter new layer name :")

            sopts.AllowSpaces = True

            Dim stres As PromptResult = ed.GetString(sopts)

            If stres.Status <> PromptStatus.OK Then
                Return
            End If
            ' get new layer name
            Dim layerName As String = stres.StringResult

            Dim opts As New PromptSelectionOptions()

            opts.MessageForRemoval = "Wrong selection, try again."

            opts.MessageForAdding = "Select single object to copy layer from: "

            opts.SingleOnly = True

            opts.SinglePickInSpace = True
            ' select single object
            Dim selRes As PromptSelectionResult = ed.GetSelection(opts)

            If selRes.Status <> PromptStatus.OK Then
                Return
            End If

            Dim entId As ObjectId = selRes.Value.GetObjectIds()(0)

            ' open transaction

            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim ltb As LayerTable = DirectCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable)
                ' get entity
                Dim ent As Entity = DirectCast(tr.GetObject(entId, OpenMode.ForRead), Entity)
                ' get entity layer
                Dim oldname As String = ent.Layer
                ' get LayerTableRecord by name
                Dim oldLtr As LayerTableRecord = DirectCast(tr.GetObject(ltb(oldname), OpenMode.ForRead), LayerTableRecord)
                ' check if layer exists
                If Not ltb.Has(layerName) Then
                    ltb.UpgradeOpen()

                    'create new layer
                    Dim ltr As New LayerTableRecord()
                    ' copy properties from entity layer
                    ltr.CopyFrom(oldLtr)
                    ' add new layer name
                    ltr.Name = layerName
                    ' here you can to add other properties to a layer: linetype, color etc
                    '
                    ' add layer to LayerTable
                    ltb.Add(ltr)
                    ' confirm transaction

                    tr.AddNewlyCreatedDBObject(ltr, True)
                Else
                    ' end command if layer exist
                    Return
                End If

                tr.Commit()
            End Using
            'end using transaction
        End Sub

11
Selection sets / Count total length using LINQ
« on: May 04, 2013, 08:44:36 PM »
   C#       
   
Code: [Select]
        //using System.Linq;
        [CommandMethod("TotalLengthCS")]
        public void testTotalLengthCS()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("\tTotal Length:\n------------------------------------");
            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    //------------------------------------------------------------------
                    // Create filter object, this filter can have any types to select, i.e. curves
                    SelectionFilter filter = new SelectionFilter(new TypedValue[]
                    {
                         new TypedValue(0, "LINE,ARC,SPLINE,CIRCLE,ELLIPSE,*POLYLINE") /*, new TypedValue(410, "~Model"),//<-- paper space only//*/
                    }
                    );
                    // Select objects on screen
                    PromptSelectionResult psr = ed.GetSelection(filter);
                    // Check if selection is succeed
                    if (psr.Status != PromptStatus.OK) return;
                    // See here for more: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b        101 LINQ Samples Csharp
// Grouping objects by name with sum of lengths
                       var data =
                            from e in psr.Value.GetObjectIds()
                            let ln= e.GetObject(OpenMode.ForRead) as Curve
                            group ln by ln.GetRXClass().DxfName into g
                            select new { ObjectName = g.Key, Subtotal = g.Sum(x => Math.Abs(x.GetDistanceAtParameter(x.EndParam - x.StartParam))) };

                    foreach (var n in data)
                    {
                        sb.AppendLine(string.Format("{0}\t{1:f6}", n.ObjectName, n.Subtotal));
                    }
                    System.Windows.Forms.MessageBox.Show(sb.ToString());
                }
            }
            catch (System.Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());

            }
        }

   VB.NET
Code: [Select]
        ''Imports System.Linq
        <CommandMethod("TotalLengthVB")> _
        Public Sub testTotalLengthVB()
            Dim db As Database = HostApplicationServices.WorkingDatabase
            Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
            Dim sb As New StringBuilder
            sb.AppendLine(vbTab + "Total Length:" + vbTab + "------------------------------------")
            Using tr As Transaction = db.TransactionManager.StartTransaction
                Dim tv() As TypedValue = {New TypedValue(0, "LINE,ARC,SPLINE,CIRCLE,ELLIPSE,*POLYLINE")}
                Dim sf As New SelectionFilter(tv)
                Dim psr As PromptSelectionResult = ed.GetSelection(sf)
                If psr.Status <> PromptStatus.OK Then Return

                ''  See here for more: http://msdn.microsoft.com/en-us/vstudio/bb688088.aspx        101 LINQ Samples VB.NET
                ''  Grouping objects by name with sum of lengths
                Dim subtotals = From id In psr.Value.GetObjectIds _
             Let curve = CType(tr.GetObject(id, OpenMode.ForRead), Curve) _
             Group curve By curve.GetRXClass().DxfName Into grp = Group _
             Select ObjectName = grp.First, Subtotal = grp.Sum(Function(x) Math.Abs(x.GetDistanceAtParameter(x.EndParam - x.StartParam)))

                For Each n In subtotals
                    sb.AppendLine(String.Format("{0}" + vbTab + "{1:f6}", n.ObjectName, n.Subtotal))
                Next

                System.Windows.Forms.MessageBox.Show(sb.ToString())
            End Using
        End Sub

12
Polylines / Creates a rectangle from the mid points of opposing sides
« on: April 27, 2013, 11:40:46 AM »
Creates a rectangle from the mid points of opposing sides and then specify the length of the sides
inspired by  David Bethel
as posted at http://www.cadtutor.net/forum/showthread.php?63494-Lisp-for-rectangle

   C#
Code: [Select]
       
[CommandMethod("P2Sides")]
        public void testDrawRectangleBySides()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            PromptPointOptions ppo = new PromptPointOptions("\nCenter of the first side: ");
            PromptPointResult ppr = ed.GetPoint(ppo);
            if (ppr.Status != PromptStatus.OK) return;
            Point3d p1 = ppr.Value;
            ppo = new PromptPointOptions("\nCenter of the seconf side: ");
            ppo.UseBasePoint = true;
            ppo.BasePoint = p1;
            ppo.UseDashedLine = true;
            ppr = ed.GetPoint(ppo);
            if (ppr.Status != PromptStatus.OK) return;

            Point3d p2 = ppr.Value;
            if (p1.X == p2.X || p1.Y == p2.Y)
            {
                ed.WriteMessage("\nInvalid coordinate specification");
                return;
            }
            ed.DrawVector(p1, p2, 1, true);
            PromptDistanceOptions pdo = new PromptDistanceOptions("\nOpposite width: ");
            pdo.BasePoint = p2;
            pdo.DefaultValue = 100;
            pdo.UseDefaultValue = true;
            PromptDoubleResult pdr = ed.GetDistance(pdo);
            if (pdr.Status != PromptStatus.OK) return;
            double leg = p1.DistanceTo(p2);
            double wid = pdr.Value;
            ed.WriteMessage("\n\tLength:\t{0:f3}\tWidth:{1:f3}\n", leg, wid);
            Plane plan = new Plane(Point3d.Origin, Vector3d.ZAxis);
            double ang = p1.GetVectorTo(p2).AngleOnPlane(plan);
            Point3dCollection pts = new Point3dCollection();
            Point3d c1 = PolarPoint(p1, ang - Math.PI / 2, wid / 2);
            Point3d c4 = PolarPoint(p1, ang + Math.PI / 2, wid / 2);
            Point3d c2 = PolarPoint(c1, ang, leg);
            Point3d c3 = PolarPoint(c4, ang, leg);
            pts.Add(c1); pts.Add(c2); pts.Add(c3); pts.Add(c4);
            Polyline poly = new Polyline();
            int idx = 0;
            foreach (Point3d p in pts)
            {
                Point2d pp = new Point2d(p.X, p.Y);
                poly.AddVertexAt(idx, pp, 0, 0, 0);
                idx += 1;
            }
            poly.Closed = true;

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(poly);
                tr.AddNewlyCreatedDBObject(poly, true);
                tr.Commit();

            }//end using transaction

        }

        // 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);
        }


      VB.NET
Code: [Select]
        <CommandMethod("P2Sides")> _
        Public Sub testDrawRectangleBySides()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim ppo As New PromptPointOptions(vbLf & "Center of the first side: ")
            Dim ppr As PromptPointResult = ed.GetPoint(ppo)
            If ppr.Status <> PromptStatus.OK Then
                Return
            End If
            Dim p1 As Point3d = ppr.Value
            ppo = New PromptPointOptions(vbLf & "Center of the seconf side: ")
            ppo.UseBasePoint = True
            ppo.BasePoint = p1
            ppo.UseDashedLine = True
            ppr = ed.GetPoint(ppo)
            If ppr.Status <> PromptStatus.OK Then
                Return
            End If

            Dim p2 As Point3d = ppr.Value
            If p1.X = p2.X OrElse p1.Y = p2.Y Then
                ed.WriteMessage(vbLf & "Invalid coordinate specification")
                Return
            End If
            ed.DrawVector(p1, p2, 1, True)
            Dim pdo As New PromptDistanceOptions(vbLf & "Opposite width: ")
            pdo.BasePoint = p2
            pdo.DefaultValue = 100
            pdo.UseDefaultValue = True
            Dim pdr As PromptDoubleResult = ed.GetDistance(pdo)
            If pdr.Status <> PromptStatus.OK Then
                Return
            End If
            Dim leg As Double = p1.DistanceTo(p2)
            Dim wid As Double = pdr.Value
            ed.WriteMessage(vbLf & vbTab & "Length:" & vbTab & "{0:f3}" & vbTab & "Width:{1:f3}" & vbLf, leg, wid)
            Dim plan As New Plane(Point3d.Origin, Vector3d.ZAxis)
            Dim ang As Double = p1.GetVectorTo(p2).AngleOnPlane(plan)
            Dim pts As New Point3dCollection()
            Dim c1 As Point3d = PolarPoint(p1, ang - Math.PI / 2, wid / 2)
            Dim c4 As Point3d = PolarPoint(p1, ang + Math.PI / 2, wid / 2)
            Dim c2 As Point3d = PolarPoint(c1, ang, leg)
            Dim c3 As Point3d = PolarPoint(c4, ang, leg)
            pts.Add(c1)
            pts.Add(c2)
            pts.Add(c3)
            pts.Add(c4)
            Dim poly As New Polyline()
            Dim idx As Integer = 0
            For Each p As Point3d In pts
                Dim pp As New Point2d(p.X, p.Y)
                poly.AddVertexAt(idx, pp, 0, 0, 0)
                idx += 1
            Next
            poly.Closed = True

            Using tr As Transaction = doc.TransactionManager.StartTransaction()
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                btr.AppendEntity(poly)
                tr.AddNewlyCreatedDBObject(poly, True)

                tr.Commit()
            End Using
            'end using transaction
        End Sub

        ' 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

13
Blocks / Insert block with attributes by predefined values
« on: April 21, 2013, 04:36:56 PM »
       Insert a block with attributes by predefined values,
       done only limited testing in A2010

 C#
Code: [Select]
     private static void ApplyAttibutes(Database db, Transaction tr, BlockReference bref, List<string> listTags, List<string> listValues)
        {
            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead);

            foreach (ObjectId attId in btr)
            {
                Entity ent = (Entity)tr.GetObject(attId, OpenMode.ForRead);
                if (ent is AttributeDefinition)
                {
                    AttributeDefinition attDef = (AttributeDefinition)ent;
                    AttributeReference attRef = new AttributeReference();

                    attRef.SetAttributeFromBlock(attDef, bref.BlockTransform);
                    bref.AttributeCollection.AppendAttribute(attRef);
                    tr.AddNewlyCreatedDBObject(attRef, true);
                    if (listTags.Contains(attDef.Tag))
                    {
                        int found = listTags.BinarySearch(attDef.Tag);
                        if (found >= 0)
                        {
                            attRef.TextString = listValues[found];
                            attRef.AdjustAlignment(db);
                        }
                    }

                }
            }
        }

        [CommandMethod("iab")]
        public static void testAttributedBlockInsert()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            // change block name to your suit
            string blockName = "UserName";
            Matrix3d ucs = ed.CurrentUserCoordinateSystem;
            //get current UCS matrix
            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    // to force update drawing screen
                    doc.TransactionManager.EnableGraphicsFlush(true);
                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);

                    // if the block table doesn't already exists, exit
                    if (!bt.Has(blockName))
                    {
                        Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Block " + blockName + " does not exist.");
                        return;
                    }

                    // insert the block in the current space
                    PromptPointResult ppr = ed.GetPoint("\nSpecify insertion point: ");
                    if (ppr.Status != PromptStatus.OK)
                    {
                        return;
                    }

                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    ObjectContextCollection occ = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");

                    Point3d pt = ppr.Value;
                    BlockReference bref = new BlockReference(pt, bt[blockName]);
                    bref.TransformBy(ucs);
                    bref.AddContext(occ.CurrentContext);

                    //add blockreference to current space
                    btr.AppendEntity(bref);
                    tr.AddNewlyCreatedDBObject(bref, true);
                    // set attributes to desired values
                    ApplyAttibutes(db, tr, bref, new List<string>(new string[] {
"TAG1",
"TAG2",
"TAG3",
"TAG4"
}), new List<string>(new string[] {
"Value #1",
"Value #2",
"Value #3",
"Value #4"
}));


                    bref.RecordGraphicsModified(true);
                    // to force updating a block reference
                    tr.TransactionManager.QueueForGraphicsFlush();
                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message);
            }
            finally
            {
                // Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Pokey")
            }
        }

   VB.NET
Code: [Select]
  Private Shared Sub ApplyAttibutes(ByRef db As Database, ByRef tr As Transaction, ByVal bref As BlockReference, ByVal listTags As List(Of String), ByVal listValues As List(Of String))
            Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)

            For Each attId As ObjectId In btr
                Dim ent As Entity = DirectCast(tr.GetObject(attId, OpenMode.ForRead), Entity)
                If TypeOf ent Is AttributeDefinition Then
                    Dim attDef As AttributeDefinition = DirectCast(ent, AttributeDefinition)
                    Dim attRef As New AttributeReference()

                    attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)
                    bref.AttributeCollection.AppendAttribute(attRef)
                    tr.AddNewlyCreatedDBObject(attRef, True)
                    If listTags.Contains(attDef.Tag) Then
                        Dim found As Integer = listTags.BinarySearch(attDef.Tag)
                        If found >= 0 Then
                            attRef.TextString = listValues(found)
                            attRef.AdjustAlignment(db)
                        End If
                    End If

                End If
            Next
        End Sub

        <CommandMethod("iab")> _
        Public Shared Sub testAttributedBlockInsert()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            ' change block name to your suit
            Dim blockName As String = "UserName"
            Dim ucs As Matrix3d = ed.CurrentUserCoordinateSystem 'get current UCS matrix
            Try
                Using tr As Transaction = db.TransactionManager.StartTransaction()
                    ' to force update drawing screen
                    doc.TransactionManager.EnableGraphicsFlush(True)
                    Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForWrite), BlockTable)

                    ' if the block table doesn't already exists, exit
                    If Not bt.Has(blockName) Then
                        Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Block " & blockName & " does not exist.")
                        Return
                    End If

                    ' insert the block in the current space
                    Dim ppr As PromptPointResult = ed.GetPoint(vbLf & "Specify insertion point: ")
                    If ppr.Status <> PromptStatus.OK Then
                        Return
                    End If

                    Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
                    Dim occ As ObjectContextCollection = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES")

                    Dim pt As Point3d = ppr.Value
                    Dim bref As New BlockReference(pt, bt(blockName))
                    bref.TransformBy(ucs)
                    bref.AddContext(occ.CurrentContext)

                    'add blockreference to current space
                    btr.AppendEntity(bref)
                    tr.AddNewlyCreatedDBObject(bref, True)
                    ' set attributes to desired values
                    ApplyAttibutes(db, tr, bref, New List(Of String)(New String() {"TAG1", "TAG2", "TAG3", "TAG4"}), New List(Of String)(New String() {"Value #1", "Value #2", "Value #3", "Value #4"}))


                    bref.RecordGraphicsModified(True) ' to force updating a block reference
                    tr.TransactionManager.QueueForGraphicsFlush()
                    tr.Commit()
                End Using
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message)
            Finally
                ' Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Pokey")
            End Try
        End Sub

14
Polylines / Merge polylines using SendCommand VB.NET
« on: April 21, 2013, 01:01:59 PM »
    Here is the basic command to merge / subtract closed contours,
   tested on A2010
VB.NET
Code: [Select]
        <CommandMethod("mep", CommandFlags.Session)> _
        Public Shared Sub testUnionPlines()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            ' get argument to choose boolean operation mode
            Dim pko As New PromptKeywordOptions(vbLf & "Choose boolean operation mode " & "[Union/Subtract]: ", "Union Subtract")
            ' The default depends on our current settings
            pko.Keywords.[Default] = "Union"
            Dim pkr As PromptResult = ed.GetKeywords(pko)
            If pkr.Status <> PromptStatus.OK Then
                Return
            End If
            Dim choice As String = pkr.StringResult

            Dim doUnion As Boolean = If(choice = "Union", True, False)
            Dim regLst As New List(Of Region)()
            Dim delPline As New List(Of Polyline)()
            Using doclock As DocumentLock = doc.LockDocument()
                'start a transaction
                Using tr As Transaction = db.TransactionManager.StartTransaction()

                    Dim tvs As TypedValue() = New TypedValue(2) {New TypedValue(0, "lwpolyline"), New TypedValue(-4, "&"), New TypedValue(70, 1)}
                    Dim filter As New SelectionFilter(tvs)
                    Dim pso As New PromptSelectionOptions()
                    pso.MessageForRemoval = vbLf & "Select closed polylines only: "
                    pso.MessageForAdding = vbLf & "Select closed polylines: "
                    Dim result As PromptSelectionResult = ed.GetSelection(filter)
                    If result.Status <> PromptStatus.OK Then
                        Return
                    End If

                    Try
                        Dim sset As SelectionSet = result.Value
                        Dim ids As ObjectId() = sset.GetObjectIds()
                        Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, False), BlockTableRecord)
                        Dim objreg1 As New Region()

                        For n As Integer = 0 To ids.Count() - 1

                            Dim obj As DBObject = TryCast(tr.GetObject(ids(n), OpenMode.ForRead), DBObject)
                            Dim pline1 As Polyline = TryCast(obj, Polyline)
                            If pline1 Is Nothing Then
                                Return
                            End If
                            ' Add the polyline to the List to rerase them all at the end of execution
                            delPline.Add(pline1)
                            ' Add the polyline to the array
                            Dim objArray1 As New DBObjectCollection()
                            objArray1.Add(pline1)
                            ' create the 1 st region
                            Dim objRegions1 As New DBObjectCollection()
                            objRegions1 = Region.CreateFromCurves(objArray1)
                            objreg1 = TryCast(objRegions1(0), Region)
                            btr.AppendEntity(objreg1)

                            tr.AddNewlyCreatedDBObject(objreg1, True)

                            objreg1.ColorIndex = 1
                            'optional
                            ' add the region to the List<Region> for the future work
                            regLst.Add(objreg1)
                        Next
                        'ed.WriteMessage("\nCount regions:\t{0}\n", regLst.Count);//just for the debug

                        ' sort regions by areas
                        Dim items As Region() = regLst.ToArray()
                        Array.Sort(items, Function(x As Region, y As Region) y.Area.CompareTo(x.Area))
                        ' get the biggest region first
                        Dim mainReg As Region = items(0)
                        ' ed.WriteMessage("\nMain region area:\t{0:f3}\n", items[0].Area);//just for the debug
                        If Not mainReg.IsWriteEnabled Then
                            mainReg.UpgradeOpen()
                        End If
                        If items.Length = 2 Then

                            If Not doUnion Then
                                mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, DirectCast(items(1), Region))
                            Else
                                mainReg.BooleanOperation(BooleanOperationType.BoolUnite, DirectCast(items(1), Region))
                            End If
                        Else
                            ' starting iteration from the second region
                            Dim i As Integer = 1
                            Do
                                Dim reg1 As Region = items(i)
                                Dim reg2 As Region = items(i + 1)

                                If (reg1 Is Nothing) OrElse (reg2 Is Nothing) Then
                                    Exit Do
                                Else

                                    ' subtract region 1 from region 2
                                    If reg1.Area > reg2.Area Then
                                        ' subtract the smaller region from the larger one
                                        '
                                        reg1.BooleanOperation(BooleanOperationType.BoolUnite, reg2)
                                        If Not doUnion Then
                                            mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, reg1)
                                        Else
                                            mainReg.BooleanOperation(BooleanOperationType.BoolUnite, reg1)

                                        End If
                                    Else


                                        ' subtract the smaller region from the larger one

                                        reg2.BooleanOperation(BooleanOperationType.BoolUnite, reg1)
                                        If Not doUnion Then
                                            mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, reg2)
                                        Else
                                            mainReg.BooleanOperation(BooleanOperationType.BoolUnite, reg2)
                                        End If

                                    End If
                                End If
                                ' increase counter
                                i += 1
                            Loop While i < items.Length - 1
                        End If
                        mainReg.ColorIndex = 1
                        ' put dummy color for region
                        ' erase polylines
                        For Each poly As Polyline In delPline
                            If poly IsNot Nothing Then
                                If Not poly.IsWriteEnabled Then
                                    poly.UpgradeOpen()
                                End If
                                poly.Erase()
                                If Not poly.IsDisposed Then
                                    poly.Dispose()
                                End If
                            End If
                        Next

                        '  ---    explode region and create polyline from exploded entities   ---   //

                        Dim regexpl As New DBObjectCollection()
                        mainReg.Explode(regexpl)

                        Dim exids As New List(Of ObjectId)()

                        ' gather selected object into the List<ObjectId>
                        If regexpl.Count > 0 Then
                            For Each obj As DBObject In regexpl
                                Dim ent As Entity = TryCast(obj, Entity)
                                If ent IsNot Nothing Then
                                    Dim eid As ObjectId = btr.AppendEntity(ent)
                                    tr.AddNewlyCreatedDBObject(ent, True)
                                   
                                    exids.Add(eid)
                                End If
                            Next
                        End If
                        ' define AcadDocument as object
                        Dim ActiveDocument As Object = doc.AcadDocument
                        Dim entids As ObjectId() = New ObjectId() {}
                        Array.Resize(entids, exids.Count)
                        ' convert List<ObjectId> to array of ObjectID
                        exids.CopyTo(entids, 0)

                        ed.Regen()
                        ' create a new selection set and exploded items
                        Dim newset As SelectionSet = SelectionSet.FromObjectIds(entids)

                        ed.SetImpliedSelection(newset.GetObjectIds())

                        Dim pfres As PromptSelectionResult = ed.SelectImplied()
                        ' execute Sendcommand synchronously
                        ActiveDocument.GetType().InvokeMember("SendCommand", System.Reflection.BindingFlags.InvokeMethod, Nothing, ActiveDocument, New Object() {"select" & vbLf})
                        ' execute Sendcommand synchronously
                        Dim cmd As String = "_pedit _M _P" & " " & "" & " " & "_J" & " " & "" & " " & "" & vbLf
                        ActiveDocument.GetType().InvokeMember("SendCommand", System.Reflection.BindingFlags.InvokeMethod, Nothing, ActiveDocument, New Object() {cmd})
                        ' rerase region if this is do not erased (relative to current DELOBJ variable value)
                        If mainReg IsNot Nothing Then
                            If Not mainReg.IsWriteEnabled Then
                                mainReg.UpgradeOpen()
                            End If
                        End If
                        mainReg.Erase()
                       
                        tr.Commit()

                    Catch ex As Autodesk.AutoCAD.Runtime.Exception

                        ed.WriteMessage((vbLf & "AutoCAD exception:" & vbLf + ex.Message & vbLf) + ex.StackTrace)
                    Finally
                        'optional, might be removed
                        ed.WriteMessage(vbLf & "{0}", New Autodesk.AutoCAD.Runtime.ErrorStatus().ToString())
                    End Try
                End Using
            End Using
        End Sub

15
Polylines / Merge polylines using SendCommand C#
« on: April 21, 2013, 01:00:30 PM »
   Here is the basic command to merge / subtract closed contours,
   tested on A2010   
C#
 
Code: [Select]
    [CommandMethod("Rea", CommandFlags.Session)]
        public static void testForUnionPlines()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            // get argument to choose boolean operation mode
            PromptKeywordOptions pko = new PromptKeywordOptions("\nChoose boolean operation mode " + "[Union/Subtract]: ", "Union Subtract");
            // The default depends on our current settings
            pko.Keywords.Default = "Union";
            PromptResult pkr = ed.GetKeywords(pko);
            if (pkr.Status != PromptStatus.OK) return;
            string choice = pkr.StringResult;

            bool doUnion = choice == "Union" ? true : false;
            List<Region> regLst = new List<Region>();
            List<Polyline> delPline = new List<Polyline>();
            using (DocumentLock doclock = doc.LockDocument())
            {
                //start a transaction
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {

                    TypedValue[] tvs = new TypedValue[3]
            {new TypedValue(0, "lwpolyline"),
                new TypedValue(-4, "&"),
                new TypedValue(70, 1)
            };
                    SelectionFilter filter = new SelectionFilter(tvs);
                    PromptSelectionOptions pso = new PromptSelectionOptions();
                    pso.MessageForRemoval = "\nSelect closed polylines only: ";
                    pso.MessageForAdding = "\nSelect closed polylines: ";
                    PromptSelectionResult result = ed.GetSelection(filter);
                    if (result.Status != PromptStatus.OK) return;

                    try
                    {
                        SelectionSet sset = result.Value;
                        ObjectId[] ids = sset.GetObjectIds();
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);
                        Region objreg1 = new Region();

                        for (int n = 0; n < ids.Count(); n++)
                        {

                            DBObject obj = tr.GetObject(ids[n], OpenMode.ForRead) as DBObject;
                            Polyline pline1 = obj as Polyline;
                            if (pline1 == null) return;
                            // Add the polyline to the List to rerase them all at the end of execution
                            delPline.Add(pline1);
                            // Add the polyline to the array
                            DBObjectCollection objArray1 = new DBObjectCollection();
                            objArray1.Add(pline1);
                            // create the 1 st region
                            DBObjectCollection objRegions1 = new DBObjectCollection();
                            objRegions1 = Region.CreateFromCurves(objArray1);
                            objreg1 = objRegions1[0] as Region;
                            btr.AppendEntity(objreg1);

                            tr.AddNewlyCreatedDBObject(objreg1, true);

                            objreg1.ColorIndex = 1;//optional
                            // add the region to the List<Region> for the future work
                            regLst.Add(objreg1);
                        }
                        //ed.WriteMessage("\nCount regions:\t{0}\n", regLst.Count);//just for the debug

                        // sort regions by areas
                        Region[] items = regLst.ToArray();
                        Array.Sort(items, (Region x, Region y) => y.Area.CompareTo(x.Area));
                        // get the biggest region first
                        Region mainReg = items[0];
                       // ed.WriteMessage("\nMain region area:\t{0:f3}\n", items[0].Area);//just for the debug
                        if (!mainReg.IsWriteEnabled) mainReg.UpgradeOpen();
                        if (items.Length == 2)
                        {

                            if (!doUnion)
                            {
                                mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, (Region)items[1]);
                            }
                            else
                            {
                                mainReg.BooleanOperation(BooleanOperationType.BoolUnite, (Region)items[1]);
                            }
                        }
                        else
                        {
                            // starting iteration from the second region
                            int i = 1;
                            do
                            {
                                Region reg1 = items[i]; Region reg2 = items[i + 1];

                                if ((reg1 == null) || (reg2 == null))
                                {
                                    break;
                                }

                                else
                                {
                                    // subtract region 1 from region 2
                                    if (reg1.Area > reg2.Area)
                                    {
                                        // subtract the smaller region from the larger one
                                        //
                                        reg1.BooleanOperation(BooleanOperationType.BoolUnite, reg2);
                                        if (!doUnion)
                                        {
                                            mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, reg1);
                                        }
                                        else
                                        {
                                            mainReg.BooleanOperation(BooleanOperationType.BoolUnite, reg1);
                                        }

                                    }

                                    else
                                    {

                                        // subtract the smaller region from the larger one

                                        reg2.BooleanOperation(BooleanOperationType.BoolUnite, reg1);
                                        if (!doUnion)
                                        {
                                            mainReg.BooleanOperation(BooleanOperationType.BoolSubtract, reg2);
                                        }
                                        else
                                        {
                                            mainReg.BooleanOperation(BooleanOperationType.BoolUnite, reg2);
                                        }
                                    }

                                }
                                // increase counter
                                i++;
                            } while (i < items.Length - 1);
                        }
                        mainReg.ColorIndex = 1;// put dummy color for region

                        // erase polylines
                        foreach (Polyline poly in delPline)
                        {
                            if (poly != null)
                            {
                                if (!poly.IsWriteEnabled) poly.UpgradeOpen();
                                poly.Erase();
                                if (!poly.IsDisposed) poly.Dispose();
                            }
                        }

                        //  ---    explode region and create polyline from exploded entities   ---   //

                        DBObjectCollection regexpl = new DBObjectCollection();
                        mainReg.Explode(regexpl);

                        List<ObjectId> exids = new List<ObjectId>();

                        // gather selected object into the List<ObjectId>
                        if (regexpl.Count > 0)
                        {
                            foreach (DBObject obj in regexpl)
                            {
                                Entity ent = obj as Entity;
                                if (ent != null)
                                {
                                    ObjectId eid = btr.AppendEntity(ent);
                                    tr.AddNewlyCreatedDBObject(ent, true);
                                   
                                    exids.Add(eid);
                                }
                            }
                        }
                        // define AcadDocument as object
                        object ActiveDocument = doc.AcadDocument;
                        ObjectId[] entids = new ObjectId[] { };
                        Array.Resize(ref entids, exids.Count);
                        // convert List<ObjectId> to array of ObjectID
                        exids.CopyTo(entids, 0);

                        ed.Regen();
                        // create a new selection set and exploded items
                        SelectionSet newset = SelectionSet.FromObjectIds(entids);

                        ed.SetImpliedSelection(newset.GetObjectIds());

                        PromptSelectionResult pfres = ed.SelectImplied();
                        // execute Sendcommand synchronously
                        ActiveDocument.GetType().InvokeMember(
                            "SendCommand", System.Reflection.BindingFlags.InvokeMethod, null, ActiveDocument,
                            new object[] { "select\n" });
                        // execute Sendcommand synchronously
                        string cmd = "_pedit _M _P" + " " + "" + " " + "_J" + " " + "" + " " + "" + "\n";
                        ActiveDocument.GetType().InvokeMember(
                            "SendCommand", System.Reflection.BindingFlags.InvokeMethod, null, ActiveDocument,
                            new object[] { cmd });
                        // rerase region if this is do not erased (relative to current DELOBJ variable value)
                        if (mainReg != null)
                            if (!mainReg.IsWriteEnabled)
                                mainReg.UpgradeOpen();
                        mainReg.Erase();
                       
                        tr.Commit();
                    }

                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {

                        ed.WriteMessage("\nAutoCAD exception:\n" + ex.Message + "\n" + ex.StackTrace);
                    }
                    finally
                    {
                        ed.WriteMessage("\n{0}", new Autodesk.AutoCAD.Runtime.ErrorStatus().ToString());//optional, might be removed
                    }
                }
            }
        }


Pages: [1] 2 3 ... 8