.NET

.NET

Reply
Valued Contributor
edweberg
Posts: 96
Registered: ‎01-29-2007
Message 1 of 10 (357 Views)
Accepted Solution

How to determine if entity is a block?

357 Views, 9 Replies
04-15-2014 01:46 PM

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

 

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

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();
}
}

 

Distinguished Mentor
gasty1001
Posts: 582
Registered: ‎04-11-2010
Message 2 of 10 (334 Views)

Re: How to determine if entity is a block?

04-15-2014 09:05 PM in reply to: edweberg

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

Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 3 of 10 (316 Views)

Re: How to determine if entity is a block?

04-16-2014 12:54 AM in reply to: edweberg
you can also try like below:

If Typeof myEnt is BlockReference

'do as you need

EndIf
Valued Contributor
architectOfIdeas
Posts: 75
Registered: ‎08-10-2007
Message 4 of 10 (298 Views)

Re: How to determine if entity is a block?

04-16-2014 08:30 AM in reply to: edweberg

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!

*Expert Elite*
dgorsman
Posts: 5,698
Registered: ‎10-12-2006
Message 5 of 10 (294 Views)

Re: How to determine if entity is a block?

04-16-2014 08:58 AM in reply to: gasty1001

Do selection sets still work when the document isn't active e.g. using a side database?

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
Adopt. Adapt. Overcome. Or be overcome.
A good question will be halfway to a good answer.


*Expert Elite*
_gile
Posts: 2,132
Registered: ‎04-29-2006
Message 6 of 10 (277 Views)

Re: How to determine if entity is a block?

04-16-2014 12:45 PM in reply to: dgorsman

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();
            }
        }

 

Gilles Chanteau
Valued Contributor
edweberg
Posts: 96
Registered: ‎01-29-2007
Message 7 of 10 (268 Views)

Re: How to determine if entity is a block?

04-16-2014 01:14 PM in reply to: _gile

Thank you for all the replies.  I got the solution I needed and much more.

 

Erik

New Member
ThomasLongnecker
Posts: 2
Registered: ‎11-13-2006
Message 8 of 10 (89 Views)

Re: How to determine if entity is a block?

11-07-2014 08:01 AM in reply to: edweberg

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

 

 

 

 

 

Valued Mentor
KerryBrown
Posts: 278
Registered: ‎11-29-2008
Message 9 of 10 (68 Views)

Re: How to determine if entity is a block?

11-08-2014 02:39 PM in reply to: ThomasLongnecker

Thomas,

I think you'll find the  RXClass comparison ( as demonstrated by gile) more efficient.

 

//-------------------------------------------------------

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

New Member
ThomasLongnecker
Posts: 2
Registered: ‎11-13-2006
Message 10 of 10 (41 Views)

Re: How to determine if entity is a block?

11-10-2014 06:18 AM in reply to: KerryBrown

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

 

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.