Author Topic: JoinEntity from Selectionset  (Read 4313 times)

0 Members and 1 Guest are viewing this topic.

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
JoinEntity from Selectionset
« on: January 22, 2016, 12:00:12 PM »
Code: [Select]
public void start()
        {
            Document acadDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database acadDb = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            int i = 1, z = 1;

            using (Transaction tr = acadDoc.TransactionManager.StartTransaction())
            {
                try
                {
                    ObjectIdCollection coll = clsSelection.Sset3dPolyline();

                    foreach (ObjectId id in coll)
                    {
                        //ed.WriteMessage("\n" + i++ + " Entiy: " + id.ObjectClass.DxfName + " Typ: " + id.ObjectClass.Name);
                        Polyline3d pol = id.GetObject(OpenMode.ForRead) as Polyline3d;
                        ObjectId oId = pol.ObjectId;
                        Point3d sPt = pol.StartPoint;
                        Point3d ePt = pol.EndPoint;

                        foreach (ObjectId id2 in coll)
                        {
                            Polyline3d pol2 = id2.GetObject(OpenMode.ForRead) as Polyline3d;
                            Point3d sPt2 = pol.StartPoint;
                            Point3d ePt2 = pol.EndPoint;
                            bool test1 = id != id2;
                            bool test2 = sPt.Equals(sPt2);
                            bool test3 = sPt2.Equals(ePt);
                            bool test4 = ePt2.Equals(sPt);


                            //if (test1 && test2 || test3 || test4)
                            //{
                            //pol.JoinEntity(pol2);

Hello guys!
I want to try join Polylines with JoinEntity() metod. My Idea is to collect all 3dPolylines in a Selectionset and than should function look for entites (3dPolylines) which are founding in start- or/and endPoint of diffrent 3dPolyline. What have I think about, in Lisp it haves ability to select via ssget-function diffrent object across selected Objects. I did not know that, how to do in .net?! So maybe itīs possible to found right 3dPolyline to join them ?!

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: JoinEntity from Selectionset
« Reply #1 on: January 22, 2016, 02:15:57 PM »
Hi,

Maybe you can get some inspiration from the PolylineSegmentCollection.Join() method in GeometryExtensions.
Speaking English as a French Frog

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: JoinEntity from Selectionset
« Reply #2 on: January 23, 2016, 04:46:52 AM »
Hi Gile!
Thank you.
I did not found references GeometryExtensions in C:\Windows\Microsoft.NET\Framework. Where I have to look for them ?!

Sorry blind :)
« Last Edit: January 23, 2016, 05:07:14 AM by cadplayer »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: JoinEntity from Selectionset
« Reply #3 on: January 23, 2016, 04:50:50 AM »
Click on the link in my reply.
Speaking English as a French Frog

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: JoinEntity from Selectionset
« Reply #4 on: January 23, 2016, 05:17:16 AM »
Great job Gile, I have to read that - it works perfect for 2d-drawingObject - I tried your function "mjoin" with GeometryExtensions :idea:
« Last Edit: January 23, 2016, 05:20:41 AM by cadplayer »

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: JoinEntity from Selectionset
« Reply #5 on: January 23, 2016, 06:41:26 AM »
Hi Gile!
1...Which reason it haves why not use JoinEntity in: Autodesk.AutoCAD.DatabaseServices.Entity.JoinEntity(Autodesk.AutoCAD.DatabaseServices.Entity)

2... Quite difficult to understand for me (with some months experince in Acad API) all metods in class GeometryExtensions, can you please explain me, how you join for example Polylines (in your case 2d)

3... which Properties I have to collect if I would try setup a PolylineSegmentCollection for Polyline3d

Iīm not sure how comes new joined Polylines in command "mjoin" in AcadDB, are you deleting and building a new Polyline2d ?!
Sorry for bad questions, I  am very newbie

A first trial
Code: [Select]
public PolylineSegmentCollection(Polyline3d pline)
        {
            ObjectId[] vertices = pline.Cast<ObjectId>().ToArray();
            //PolylineVertex3d[] vertices = pline.Cast<ObjectId>().ToArray();
            int n = vertices.Length - 1;
            for (int i = 0; i < n; i++)
            {
                using (Transaction tr = AcAp.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
                {
                    PolylineVertex3d vertex = tr.GetObject(vertices[i], OpenMode.ForRead) as PolylineVertex3d;
                    _contents.Add(new PolylineSegment(

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: JoinEntity from Selectionset
« Reply #6 on: January 23, 2016, 09:38:12 AM »
Hi,

1... When i wrote this library I thaught it was a better way to explicitly import (using) the namesapace.

2... I tried to explain the methods in the library documentation. To join Polylines (or others planar curve entities), you have to first convert each entity into a  PolylineSegmentCollection(or a  PolylineSegment) and AddRange it (or Addit) to the main  PolylineSegmentCollection, then call the Join() method over the main  PolylineSegmentCollection.

3... If you just want to join contiguous 3d polylines, you do not need to create a Polyline3dSegment and Polyline3dSegementCollection classes. Just implement the algorithm used in the PolylineSegmentCollection.Join() method using the Polylines Startpoint and EndPoint properties:
- input = the list of polyline 3d you want to join.
- ouput = a new empty list of Polyline 3d
- add the first poly of input in output, call it currentPoly, remove it from output.
- while input is not empty compare the startpoint and the end point of the currentPoly polyline with all start points and end points of polylines in input
- if one matches, join this polyline to currentPoly, remove it from input and loop with the modified currentPoly
- if none matches, add the first polyline of input to output, make it the currentPoly, remove it from input and loop...

The simplest way for joining two polylines is to AppendVertex() the vertices of one polyline to the other and delete the first one.
Speaking English as a French Frog

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: JoinEntity from Selectionset
« Reply #7 on: January 25, 2016, 05:12:52 AM »
Hello again!
My try to create a new 3dPolyline doesnīt create 3dPolyline in Drawing. allPoint3d-collection is true, not Exception callback ... whatīs wrong?!
Code: [Select]
        public static Point3dCollection GetVertex(PromptEntityResult res)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            Point3dCollection coll = new Point3dCollection();

            using (Transaction tr = doc.TransactionManager.StartTransaction())
            {
                Polyline3d pl3d = tr.GetObject(res.ObjectId, OpenMode.ForRead) as Polyline3d;
                ObjectId[] verts = pl3d.Cast<ObjectId>().ToArray();
                ed.WriteMessage("\nNumber of vertexes: {0}", verts.Length);
                for (int i = 0; i < verts.Length; i++)
                {
                    PolylineVertex3d vt = tr.GetObject(verts[i], OpenMode.ForRead) as PolylineVertex3d;
                    coll.Add(new Point3d(vt.Position[0], vt.Position[1], vt.Position[2]));
                }
                tr.Commit();
            }
            return coll;
        }

        [CommandMethod("xx")]
        static public void Append3dPolylines()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            Point3dCollection collPoint3d = null;
            Point3dCollection allPoint3d = null;

            PromptEntityOptions peo1 = new PromptEntityOptions("\nSelect source polyline : ");
            peo1.SetRejectMessage("\nInvalid selection...");
            peo1.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline3d), true);

            PromptEntityResult res = ed.GetEntity(peo1);
            if (PromptStatus.OK != res.Status)
                return;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                                               BlockTable BlkTbl = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                                BlockTableRecord BlkTblRec = trans.GetObject(BlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                                Polyline3d newPoly = new Polyline3d();
                                BlkTblRec.AppendEntity(newPoly);
                                trans.AddNewlyCreatedDBObject(newPoly, true);


                try
                {
                    collPoint3d = GetVertex(res);
                    allPoint3d = new Point3dCollection();
                    foreach (Point3d pt in collPoint3d)
                    {
                        allPoint3d.Add(pt);
                    }


                    while (true)
                    {
                        PromptEntityOptions peo2 = new PromptEntityOptions("\nSelect polyline to join : ");
                        peo2.SetRejectMessage("\nInvalid selection...");
                        peo2.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline3d), true);

                        res = ed.GetEntity(peo2);

                        switch (res.Status)
                        {
                            case PromptStatus.OK:
                                collPoint3d = GetVertex(res);

                                foreach (Point3d pt in collPoint3d)
                                {
                                    allPoint3d.Add(pt);
                                }
                                break;
                            case PromptStatus.Cancel:

                                foreach (Point3d pt in allPoint3d)
                                {
                                    PolylineVertex3d vertex = new PolylineVertex3d(pt);
                                    newPoly.AppendVertex(vertex);
                                    trans.AddNewlyCreatedDBObject(vertex, true);
                                }
                                ed.WriteMessage("\nNew 3dPolyline created!");
                                return;
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    ed.WriteMessage(ex.Message);
                }

                trans.Commit();
            }

        }

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: JoinEntity from Selectionset
« Reply #8 on: January 25, 2016, 05:31:05 AM »
Maybe this trial should also work in a Selectionset. Select 3dPolyline simple and it doesnīt matter if select 3dPolyline after start or endpoint
Please test it, maybe you have an idea how it can work in Selectionset. There it have to check 3dPolylines in start or endpoint
Code: [Select]
        [CommandMethod("join3d")]
        static public void join3d()
        {
            Document document = Application.DocumentManager.MdiActiveDocument;
            Editor ed = document.Editor;
            Database db = document.Database;

            PromptEntityOptions peo1 = new PromptEntityOptions("\nSelect source polyline : ");
            peo1.SetRejectMessage("\nInvalid selection...");
            peo1.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline), true);
            peo1.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline2d), true);
            peo1.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline3d), true);

            PromptEntityResult res = ed.GetEntity(peo1);
            if (PromptStatus.OK != res.Status)
                return;

            ObjectId srcId = res.ObjectId;

            while (true)
            {
                PromptEntityOptions peo2 = new PromptEntityOptions("\nSelect polyline to join : ");
                peo2.SetRejectMessage("\nInvalid selection...");
                peo2.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline), true);
                peo2.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline2d), true);
                peo2.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline3d), true);

                res = ed.GetEntity(peo2);
                switch (res.Status)
                {
                    case PromptStatus.OK:
                        ObjectId joinId = res.ObjectId;
                        try
                        {
                            using (Transaction trans = db.TransactionManager.StartTransaction())
                            {
                                Entity srcPLine = trans.GetObject(srcId, OpenMode.ForRead) as Entity;
                                Entity addPLine = trans.GetObject(joinId, OpenMode.ForRead) as Entity;

                                srcPLine.UpgradeOpen();
                                srcPLine.JoinEntity(addPLine);

                                addPLine.UpgradeOpen();
                                addPLine.Erase();

                                trans.Commit();
                            }
                        }
                        catch (System.Exception ex)
                        {
                            ed.WriteMessage(ex.Message);
                        }
                        break;
                    case PromptStatus.Cancel:
                        ed.WriteMessage("\nFinished!");
                        return;
                }
            }
        }

cadplayer

  • Bull Frog
  • Posts: 390
  • Autocad Civil3d, OpenDCL.Runtime, LISP, .NET (C#)
Re: JoinEntity from Selectionset
« Reply #9 on: February 01, 2016, 11:54:57 AM »
ErrorStatus = AlreadyInDB

I get this Exception and did not understand. Somebody understand and can solv this ?!
In poly.AppendVertex(vex3d); is not going right.

Code: [Select]
using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    try
                    {
                        Polyline3d poly = new Polyline3d();
                        btr.AppendEntity(poly);
                        tr.AddNewlyCreatedDBObject(poly, true);

                        foreach (Polyline3DPoints segs in psc)
                        {
                            Entity pline = (Entity)tr.GetObject(segs.ObjectID, OpenMode.ForWrite);
                            foreach (ObjectId vId in (Polyline3d)pline)
                            {
                                PolylineVertex3d vex3d = (PolylineVertex3d)tr.GetObject(vId, OpenMode.ForRead);
                                poly.AppendVertex(vex3d);
                                tr.AddNewlyCreatedDBObject(vex3d, true);
                            }
                        }
                    }
                    catch (System.Exception ex)
                    { }
                    tr.Commit();

VVeli

  • Newt
  • Posts: 27
Re: JoinEntity from Selectionset
« Reply #10 on: May 03, 2016, 05:59:46 AM »
Hi,
you have to create new polylinevertex3d for the new Polyline3d (poly). Now you are trying to set different polylines (psc, pline) vertexes (vId) to new one.
I donīt know what you have in that psc collection but I expect there is collection of Polyline3dīs.
-Veli