Modify Selection Filter
Not applicable
09-26-2017
01:44 PM
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.
Link copied