Author Topic: Polar increment of objects  (Read 1032 times)

0 Members and 1 Guest are viewing this topic.

Offline fixo

  • Full Member
  • ***
  • Posts: 135
  • Karma: +4/-0
  • Gender: Male
    • prefered language: C
    • Prog expertise: Good
    • View Profile
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);
                }
            }
        }