.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Copy Entity DeepClone

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
brentburgess
3863 Views, 2 Replies

Copy Entity DeepClone

Hi All,

 

I am creating a tool that will copy entities to each vertex of a polyline. The code below worked, until I realised that I lost field links, dynamic block functionality etc.

        [CommandMethod("BRENT", "COPYALONGPOLYLINE", "COPYALONGPOLYLINE", CommandFlags.Session)]
        public static void COPYALONGPOLYLINE()
            {
            // Get the current document and database
            Document doc = AcApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            using (DocumentLock dlock = doc.LockDocument())
                {
                // Start a transaction
                using (Transaction tr = db.TransactionManager.StartTransaction())
                    {

                    PromptEntityResult per = ed.GetEntity("\nSelect Polyline");
                    if (per.Status == PromptStatus.OK)
                        {
                        DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
                        Point3dCollection pts = new Point3dCollection();
                        
                        Polyline lwp = obj as Polyline;
                        if (lwp != null)
                            {
                            lwp.Highlight();
                            int vn = lwp.NumberOfVertices;
                            for (int i = 0; i < vn; i++)
                                {
                                pts.Add(lwp.GetPoint3dAt(i));
                                }
                            }

                        BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                        BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                        PromptSelectionOptions pso = new PromptSelectionOptions();
                        pso.MessageForAdding = "\nSelect objects to add: ";
                        pso.MessageForRemoval = "\nSelect objects to remove: ";

                        PromptSelectionResult psr = ed.GetSelection(pso);
                        if (psr.Status == PromptStatus.OK)
                            {
                            SelectionSet ss = psr.Value;
                            DBObjectCollection dbEntColl = new DBObjectCollection();
                            foreach (ObjectId id in ss.GetObjectIds())
                                {
                                Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
                                dbEntColl.Add(ent);
                                }

                            for (int i = 1; i < pts.Count; i++)
                                {
                                Vector3d v3d = new Vector3d(pts[i].X - pts[0].X, pts[i].Y - pts[0].Y, pts[i].Z - pts[0].Z);
                                
                                foreach (Entity acEnt in dbEntColl)
                                    {
                                    Entity ent;
                                    ent = acEnt.Clone() as Entity;

                                    // Create a matrix and move each copied entity 15 units
                                    ent.TransformBy(Matrix3d.Displacement(v3d));

                                    // Add the cloned object
                                    btr.AppendEntity(ent);
                                    tr.AddNewlyCreatedDBObject(ent, true);
                                    }
                                }
                            }
                        if (lwp != null) lwp.Unhighlight();
                        }

                    // Save the new object to the database
                    tr.Commit();
                    }
                }
            }

 

I believe I need to use the Database.DeepClone, but I don't quite understand how to create the cloned entity. In this code below the error is AlreadyExists

 

[CommandMethod("copyEnt")]
        public void copyEnt()
            {
            Document doc = AcApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions options = new PromptEntityOptions("\nSelect entity to copy");

            PromptEntityResult acSSPrompt = ed.GetEntity(options);

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

            ObjectIdCollection collection = new ObjectIdCollection();
            collection.Add(acSSPrompt.ObjectId);

            //make model space as owner for new entity
            ObjectId ModelSpaceId = SymbolUtilityServices.GetBlockModelSpaceId(db);

            IdMapping mapping = new IdMapping();
            //db.DeepCloneObjects(collection, ModelSpaceId, mapping, false);

            //now open the new entity and change the color...
            using (Transaction Tx = db.TransactionManager.StartTransaction())
                {
                Entity oldEnt = (Entity)Tx.GetObject(acSSPrompt.ObjectId, OpenMode.ForRead);
                Entity newEnt = (Entity)oldEnt.DeepClone(oldEnt, mapping, true);


                //get the map.
                IdPair pair1 = mapping[acSSPrompt.ObjectId];

                //new object
                Entity ent = Tx.GetObject(pair1.Value, OpenMode.ForWrite) as Entity;

                
                //change the color to red
                ent.ColorIndex = 1;
                ent.Highlight();
                BlockTableRecord btr = (BlockTableRecord)Tx.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(newEnt);
                Tx.AddNewlyCreatedDBObject(newEnt, true);

                Tx.Commit();
                }

            }

 Can someone enlighten me on this?

 

Thanks,

 

Brent

2 REPLIES 2
Message 2 of 3
_gile
in reply to: brentburgess

Hi,

 

Here's an example using Database.DeepCloneObjects() method

 

        [CommandMethod("TEST")]
        public void Test()
        {
            // Get the current document and database
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // Select a polyline
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
            peo.SetRejectMessage("Only a polyline.");
            peo.AddAllowedClass(typeof(Polyline), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK)
                return;

            // Select objects to copy
            PromptSelectionOptions pso = new PromptSelectionOptions();
            pso.MessageForAdding = "\nSelect objects to add: ";
            pso.MessageForRemoval = "\nSelect objects to remove: ";
            PromptSelectionResult psr = ed.GetSelection(pso);
            if (psr.Status != PromptStatus.OK)
                return;
            ObjectIdCollection ids = new ObjectIdCollection(psr.Value.GetObjectIds());

            // Start a transaction
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                ObjectId spaceId = db.CurrentSpaceId;
                Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);

                // For each vertex of the polyline but the first one...
                for (int i = 1; i < pline.NumberOfVertices; i++)
                {
                    // ...Deep clone the selected objects and...
                    IdMapping mapping = new IdMapping();
                    db.DeepCloneObjects(ids, spaceId, mapping, false);
                    // ...move the cloned objects to the current vertex
                    Vector3d disp = pline.StartPoint.GetVectorTo(pline.GetPoint3dAt(i));
                    Matrix3d mat = Matrix3d.Displacement(disp);
                    foreach (ObjectId id in ids)
                    {
                        if (mapping[id].IsCloned)
                        {
                            Entity ent = (Entity)tr.GetObject(mapping[id].Value, OpenMode.ForWrite);
                            ent.TransformBy(mat);
                        }
                    }
                }
                tr.Commit();
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 3
brentburgess
in reply to: _gile

Thanks Giles!!!! Worked a treat

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost