Greetings,
I'm writing an app in VB.NET. In a small part of the code I'm working on, I need to examine each entity in a drawing and determine whether it is a block, and if it is not a block, erase it from the drawing.
Here's a snip from the part of the code in question. I can't find an example of how to determine if an entity is a block or not. Can anyone help me get started filling in the green part below. Thank you for any suggestions.
Erik
Dim myEd As Editor = DocumentManager.MdiActiveDocument.Editor
Dim myPSR As PromptSelectionResult = myEd.SelectAll
If myPSR.Status = PromptStatus.OK Then
Dim mySS As SelectionSet= myPSR.Value
ForEach mySelObj As SelectedObject In mySS
Dim myEnt As Entity = mySelObj.ObjectId.GetObject(OpenMode.ForWrite)
'If my Entity is not a block or nested within a block, erase it...
Next
EndIf
Solved! Go to Solution.
Solved by _gile. Go to Solution.
Solved by hgasty1001. Go to Solution.
Hi,
Instead to test each entity, a better aproach could be to select all entities that do not acomplish the criteria, in this case all entities that are not block references (Block Inserts), this is as easy as using a filter with the "not" operator:
Public Sub DeleteNoBlocksReferences() Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = acDoc.Database Dim ret As SelectionSet Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() Dim acTypValAr(2) As TypedValue acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<not"), 0) acTypValAr.SetValue(New TypedValue(DxfCode.Start, "INSERT"), 1) acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "not>"), 2) Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr) Dim acSSPrompt As PromptSelectionResult Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor acSSPrompt = ed.SelectAll(acSelFtr) If acSSPrompt.Status = PromptStatus.OK Then ret = acSSPrompt.Value Dim objids() As ObjectId objids = ret.GetObjectIds For Each objid As ObjectId In objids Dim obj As DBObject = acTrans.GetObject(objid, OpenMode.ForWrite) obj.Erase() Next End If acTrans.Commit() End Using End Sub <CommandMethod("ENOBLK")> _ Public Sub enoblk() DeleteNoBlocksReferences() End Sub
Gaston Nunez
I support the method of filtering the selection that Gaston has suggested. It's a bit more authoring (and it might take a bit to understand how the .Operators work) but it is an explicit approach that can be easily modified to include specific properties later. Although, it might make more sense when dealing with a large file or when including more function than just erasing the block reference.
If Not TypeOf acObject is BlockReference does what you need though, go for it!
Do selection sets still work when the document isn't active e.g. using a side database?
hi,
No, you can only use selection sets if the document is opened in the editor (all selection set methods are instance methods of the Editor class).
Using a side database, you'd have to iterate the model (and/or paper) space BlockTableRecord and filter the contained entity.
private void EraseAllButBlocks(Database db) { RXClass blockClass = RXClass.GetClass(typeof(BlockReference)); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); foreach (ObjectId id in modelSpace) { if (id.ObjectClass != blockClass) { Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite); try { ent.Erase(); } catch { } } } tr.Commit(); } }
Just in case someone is looking for the answer to the original question. I found two ways (there maybe more) of determining if an entity is a block reference or not.
Given the code in the original post the following two technique should work
If MySelObj.ObjectId.ObjectClass.DxfName = "INSERT" Then
If MyEnt.GetType.Namespace = "Reference" Then
Thomas
Thomas,
I think you'll find the RXClass comparison ( as demonstrated by gile) more efficient.
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
Sometimes the question is more important than the answer.
class keyThumper<T> : Lazy<T>; another Swamper
Kerry,
I am pretty new to programming AutoCAD with .NET and would appricate the opertunity to learn from you.
Can you give a brief explanaiton what would make the RXClass comparison "more efficiate" then the original and later posted VB comparison?
Thanks,
Thomas
Can't find what you're looking for? Ask the community or share your knowledge.