Quantcast
Channel: Autodesk AutoCAD forums
Viewing all articles
Browse latest Browse all 14319

Can't select entities after clone and rotation

$
0
0

Hi,

i coded a utility to help with entities rotation. This is a part of a bigger project so i just cutted and pasted together the part of code that have this problem.

Basically i get the selection, i clone it (because this is a copy and rotate) and through a draw jig class i rotate all the entities. This works well but just sometimes when the command ends it happend this weird thing, the entities appeares  in the draw but they can't be selected. And all get back to the normally after saving, closing and reopening the draw.

This is the utility.

 

public void Run(object param)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            List<Entity> toRotate = new List<Entity>();
            PromptSelectionOptions pso = new PromptSelectionOptions();
            pso.MessageForAdding = "\nSelect objects";
            pso.AllowDuplicates = false;
            pso.AllowSubSelections = false;
            PromptSelectionResult psr = ed.GetSelection(pso);
            if (psr.Status != PromptStatus.OK)
                return;


            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                foreach (SelectedObject so in psr.Value)
                    toRotate.Add(trans.GetObject(so.ObjectId, OpenMode.ForRead) as Entity);
                trans.Commit();
            }

            PromptPointOptions ppo = new PromptPointOptions("\nSelect base point of the rotation");
            PromptPointResult ppr = ed.GetPoint(ppo);
            if (ppr.Status != PromptStatus.OK)
                return;
            Point3d center = ppr.Value;

            JigReferenceRotator jig = new JigReferenceRotator(center);
            ed.Drag(jig);
            jig.Axis = false;
            PromptResult pr;
            List<Entity> reference;

            while (true)
            {
                reference = toRotate;
                toRotate = EntityListClone(toRotate);

                jig.toRotate = toRotate;
                pr = ed.Drag(jig);

                if (pr.Status != PromptStatus.OK)
                {
                    using (DocumentLock dl = doc.LockDocument())
                    {
                        using (Transaction trans = db.TransactionManager.StartTransaction())
                        {
                            foreach (Entity ent in toRotate)
                                trans.GetObject(ent.ObjectId, OpenMode.ForWrite).Erase();
                            trans.Commit();
                        }
                    }
                    ed.Regen();
                    break;
                }

                ed.Regen();
            }
}

 These are the function that clone entities.

public List<Entity> EntityListClone(List<Entity> toClone)
        {
            List<Entity> toReturn = new List<Entity>();
            ObjectIdCollection clone = new ObjectIdCollection();

            foreach (Entity ent in toClone)
                clone.Add(ent.ObjectId);

            clone = ObjectIdCollectionClone(clone);

            using (Transaction trans = Application.DocumentManager.MdiActiveDocument.Database.
                TransactionManager.StartTransaction())
            {
                foreach (ObjectId obj in clone)
                    toReturn.Add(trans.GetObject(obj, OpenMode.ForRead) as Entity);
                trans.Commit();
            }

            return toReturn;
        }

        private ObjectIdCollection ObjectIdCollectionClone(ObjectIdCollection toClone)
        {
            ObjectIdCollection dest = new ObjectIdCollection();
            Database db = Application.DocumentManager.MdiActiveDocument.Database;

            IdMapping map = new IdMapping();

            db.DeepCloneObjects(toClone, db.CurrentSpaceId, map, false);

            foreach (ObjectId obj in toClone)
                dest.Add(map[obj].Value);

            return dest;
        }

 And this is the draw jig class

public class JigReferenceRotator : DrawJig
    {
        Point3d center;
        Ray axis;
        double oldAngle, firstAngle;

        public JigReferenceRotator(Point3d center)
        {
            Axis = true;
            this.center = center;

            axis = new Ray();
            axis.BasePoint = center;
            axis.SecondPoint = Point3d.Origin;
        }

        public bool Axis
        { get; set; }

        public List<Entity> toRotate
        { get; set; }

        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            if (Axis)
            {
                Point3d p = prompts.AcquirePoint("\nFirst Reference").Value;
                if (p.DistanceTo(axis.SecondPoint) < 0.001 || axis.BasePoint.DistanceTo(p) < 0.001)
                    return SamplerStatus.NoChange;
                axis.SecondPoint = p;
                firstAngle = new Line(axis.BasePoint, axis.SecondPoint).Angle;
            }
            else
            {
                Point3d p = prompts.AcquirePoint("\nSecond Reference").Value;
                if (p.DistanceTo(axis.SecondPoint) < 0.001 || axis.BasePoint.DistanceTo(p) < 0.001)
                {
                    Application.DocumentManager.MdiActiveDocument.Editor.Regen();
                    return SamplerStatus.NoChange;
                }
                axis.SecondPoint = p;
            }
            return SamplerStatus.OK;
        }

        protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
        {
            if (Axis)
                draw.Geometry.Draw(axis);
            else
            {
                draw.Geometry.Draw(axis);
                double angle = firstAngle - new Line(axis.BasePoint, axis.SecondPoint).Angle;

                using (Transaction trans = Application.DocumentManager.MdiActiveDocument.Database.
                    TransactionManager.StartTransaction())
                {
                    foreach (Entity ent in toRotate)
                    {
                        (trans.GetObject(ent.ObjectId, OpenMode.ForWrite) as Entity).TransformBy(
                            Matrix3d.Rotation(oldAngle - angle, Vector3d.ZAxis, center));
                        draw.Geometry.Draw(ent);
                    }
                    trans.Commit();
                }
                oldAngle = angle;
            }
            return true;
        }
    }

 I also record a video in order to show you what happen. 

This is the link

https://www.dropbox.com/s/bhjl3bj9g158e64/error.wmv


Viewing all articles
Browse latest Browse all 14319

Trending Articles