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
Solved! Go to Solution.
Solved by _gile. Go to Solution.
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(); } }