Modify Selection Filter

Anonymous

Modify Selection Filter

Anonymous
Not applicable

Hi all,

Wondering if i can get any help.

 

The following crashes after rotation.

 

If my selection of blocks has a image then it crashes during insertion of selection when prompted for rotation

 

 

 

public static void Prod(string CMDID)
        {
            acServices.Document doc = acServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            var tvs = new List<TypedValue>();
            tvs.Add(new TypedValue((int)DxfCode.Operator, "<not"));
            tvs.Add(new TypedValue((int)DxfCode.Operator, "<OR"));
            tvs.Add(new TypedValue((int)DxfCode.Start, "ACAD_TABLE"));
            tvs.Add(new TypedValue((int)DxfCode.Operator, "<and"));
            tvs.Add(new TypedValue((int)DxfCode.Start, "INSERT"));
            tvs.Add(new TypedValue((int)DxfCode.Operator, "<or"));
            foreach (var tbn in Program.Config.TitleBlockNames)
            {
                tvs.Add(new TypedValue((int)DxfCode.BlockName, tbn));
            }
            tvs.Add(new TypedValue((int)DxfCode.Operator, "or>"));
            tvs.Add(new TypedValue((int)DxfCode.Operator, "and>"));
            tvs.Add(new TypedValue((int)DxfCode.Operator, "OR>"));
            tvs.Add(new TypedValue((int)DxfCode.Operator, "not>"));

            var sf = new SelectionFilter(tvs.ToArray());

            var psr = ed.GetSelection(sf);
            if (psr.Status == PromptStatus.Cancel || psr.Value == null) return;

            SelectionSet selectionSet = psr.Value;
            if (selectionSet.Count == 0) return;

            var ptDest = ed.GetPoint("\nEnter the insertion point:");
            if (ptDest.Status != PromptStatus.OK)
                return;

            var promptOptions = new PromptAngleOptions("\nEnter rotation angle:");
            promptOptions.BasePoint = ptDest.Value;
            promptOptions.DefaultValue = 0;
            promptOptions.UseBasePoint = true;
            var fAngle = ed.GetAngle(promptOptions);
            if (fAngle.Status != PromptStatus.OK)
                return;

            //var ndb = new Database(true, true);
            var ndb = doc.Database;
            ObjectIdCollection objids = new ObjectIdCollection(selectionSet.GetObjectIds());
            var idmap = new IdMapping();
            using (Transaction tr = ndb.TransactionManager.StartTransaction())
            using (BlockTable bt = tr.GetObject(ndb.BlockTableId, OpenMode.ForRead) as BlockTable)
            using (BlockTableRecord ibase = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord)
            {
                doc.Database.DeepCloneObjects(objids, ibase.ObjectId, idmap, false);

                var ents = new List<Entity>();
                foreach (SelectedObject so in selectionSet)
                {
                    IdPair p = idmap.Lookup(so.ObjectId);
                    var ent = tr.GetObject(p.Value, OpenMode.ForWrite) as Entity;
                    ents.Add(ent);
                }

                bool didExplode = true;
                while (didExplode)
                {
                    didExplode = false;
                    var newents = new List<Entity>();
                    foreach (Entity ent in ents)
                    {
                        if (!(ent is BlockReference))
                        {
                            newents.Add(ent);
                            continue;
                        }

                        var bref = ent as BlockReference;
                        var eobjs = new DBObjectCollection();
                        bref.Explode(eobjs);
                        foreach (var dbo in eobjs)
                        {
                            Entity nent = dbo as Entity;
                            if (nent == null) continue;

                            ibase.AppendEntity(nent);
                            tr.AddNewlyCreatedDBObject(nent, true);
                            newents.Add(nent);
                        }
                        bref.Erase();
                        didExplode = true;
                    }
                    ents.Clear();
                    ents = newents;
                }

                Extents3d newEntitiesExtents = new Extents3d();
                for (int nEnt = ents.Count - 1; nEnt >= 0; nEnt--)
                {
                    if (Program.Config.LaserCMDLayers[CMDID].Contains(ents[nEnt].Layer))
                    {
                        newEntitiesExtents.AddExtents(ents[nEnt].GeometricExtents);
                        continue;
                    }
                    ents[nEnt].Erase();
                    ents.RemoveAt(nEnt);
                }

                var mtx = Matrix3d.Displacement(ptDest.Value - newEntitiesExtents.MinPoint);
                mtx = Matrix3d.Rotation(fAngle.Value, Vector3d.ZAxis, ptDest.Value) * mtx;
                foreach (var ent in ents)
                {
                    ent.TransformBy(mtx);
                }

                tr.Commit();
            }
        }

 

Possible solution i thought is to remove objects from a selection set using ObjectidCollection.

 

 

 

 

 

0 Likes
Reply
295 Views
1 Reply
Reply (1)

ActivistInvestor
Advisor
Advisor

It's not uncommon for AutoCAD to crash when there's no exception handling in managed code.

 

Try putting the entire method's body in a try{} block, and put a catch{} block following that which traps and displays any exception raised.