.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Selection Set Selects Circles and Blocks, How to Tell Them Apart

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
mgorecki
1542 Views, 10 Replies

Selection Set Selects Circles and Blocks, How to Tell Them Apart

Hi, ok I know this is a newbie question, but I've looked through this site and other sources before just plain asking the people who would know.

I have a selection set filter set to get only circles and blocks (INSERT).  Then it gets to a part of the code that says for each object in my group of objects... do something. 

The first few lines of the "do something" are:

For Each bgaObjID In bgaObjIDs

Dim myBlockRef As DatabaseServices.BlockReference

myBlockRef = bgaObjID.GetObject(DatabaseServices.OpenMode.ForRead)

 

If it's a block, then it's just fine.  If it's a circle, it crashes.  Obviously circles aren't blocks and that's why it crashes.  I'm trying to set up an If..Then statement so that blocks use one set of statements and circles use another.  I've looked at the values for the objectID, but cannot tell how to determine if it's a block ref or a circle.

If it's a circle, I would use:

Dim tempCir As Circle = TryCast(bgaObjID.GetObject(DatabaseServices.OpenMode.ForRead), Circle)

 

Can someone help me out on this?

Thanks,

Mark

 

 

10 REPLIES 10
Message 2 of 11
Jeffrey_H
in reply to: mgorecki

If you want to use TryCast then if it fails it has to be a block reference

 

            Dim objIdColl As New ObjectIdCollection
 
            For Each objId As ObjectId In objIdColl
 
                ''If performance is a issue this is faster
                ''''''''''''''''''''''''''''''''''''''''''''''
                If objId.ObjectClass.Name = "AcDbCircle" Then
                ElseIf objId.ObjectClass.Name = "AcDbBlockReference" Then
                End If
                ''''''''''''''''''''''''''''''''''''''''''''''
 
 
                ''If performance is a issue this is faster
                ''''''''''''''''''''''''''''''''''''''''''''''
                If objId.ObjectClass.DxfName = "CIRCLE" Then
                ElseIf objId.ObjectClass.DxfName = "INSERT" Then
                End If
                ''''''''''''''''''''''''''''''''''''''''''''''
 
 
 
                ''''''''''''''''''''''''''''''''''''''''''''''
                Dim ent As Entity = objId.GetObject(OpenMode.ForRead)
                If TypeOf ent Is Circle Then
                ElseIf TypeOf ent Is BlockReference Then
                End If
                ''''''''''''''''''''''''''''''''''''''''''''''
 
 
 
                ''''''''''''''''''''''''''''''''''''''''''''''
                Dim cir As Circle = TryCast(objId.GetObject(OpenMode.ForRead), Circle)
                If cir IsNot Nothing Then
                Else
                    ''If you onle have circles and blockreferences and it is not a circle then is a blockreference
                End If
                ''''''''''''''''''''''''''''''''''''''''''''''
 
 
 
            Next
You can also find your answers @ TheSwamp
Message 3 of 11
chiefbraincloud
in reply to: mgorecki

This way is better, because you are not using a runtime exception as a test.

 

For Each bgaObjID In bgaObjIDs

    If bgaObjID.ObjectClass.Name = "AcDbBlockReference" then

        .....

    Elseif bgaObjID.ObjectClass.Name = "AcDbCircle" then

        .....

    end if

next

Sorry Jeffrey, I kind of blasted over your post quickly, and only saw the TryCast.  Didn't catch that you had included the ObjectClass property at the beginning.

Dave O.                                                                  Sig-Logos32.png
Message 4 of 11
mgorecki
in reply to: chiefbraincloud

Hello and thanks for the replys.

Here is what I have dimmed:

Dim myDWG As ApplicationServices.Document
Dim myEd As EditorInput.Editor
Dim myPSR As EditorInput.PromptSelectionResult
Dim bgaSelectionSet As EditorInput.SelectionSet
Dim myTransMan As DatabaseServices.TransactionManager
Dim myTrans As DatabaseServices.Transaction
Dim myBT As DatabaseServices.BlockTable
Dim myBTR As DatabaseServices.BlockTableRecord
Dim bgaObjIDs As New ObjectIdCollection
Dim bgaObjID As DatabaseServices.ObjectId

myDWG = ApplicationServices.Application.DocumentManager.MdiActiveDocument
myEd = myDWG.Editor

myPSR = myEd.SelectWindow(ssWindowPnt1, ssWindowPnt2, bgaSSFilter)

If Not IsNothing(myPSR.Value) Then
  myTransMan = myDWG.TransactionManager
  myTrans = myTransMan.StartTransaction
  bgaSelectionSet = myPSR.Value
  bgaObjIDs = New DatabaseServices.ObjectIdCollection(bgaSelectionSet.GetObjectIds)
  For Each bgaObjID As ObjectId In bgaObjIDs
    If bgaObjID.ObjectClass.Name = "AcDbBlockReference" Then
      Dim myBlockRef As DatabaseServices.BlockReference
      myBlockRef = bgaObjID.GetObject(DatabaseServices.OpenMode.ForRead)
      ballCenter = myBlockRef.Position
    End If
:
:

I get an error saying "ObjectClass is not a member of 'Autodesk.AutoCAD.DatabaseServises.ObjectId'."

Any advice?

 

Thanks,

Mark

 

Message 5 of 11
chiefbraincloud
in reply to: mgorecki

I use the ObjectClass property lots of times in my code, and it has been there as long as I can remember.  What version of AutoCAD are you using?

 

For what it is worth, the reason I use the ObjectClass property a lot is that it allows you to type-test the object without having to open it in a transaction.  Let's say you are looping the contents of a BlockTableRecord looking for AttributeDefinitions.  That allows you to skip over the objects that are not AttributeDefinitions without having to open them.

 

That said, you are looping a selection which has been filtered, and apparently opening every BlockReference and every Circle that you have in your selection.  Since you know that everything in your selection is a BlockReference or a Circle, the Third approach suggested by Jeffrey has (almost) no overhead cost associated with it.

 

dim ent as Entity = myTrans.GetObject(bgaObjID, OpenMode.For(Read or Write))

If TypeOf ent is BlockReference then

     dim bref as BlockReference = ent

     .....

else  'you could say ElseIf TypeOf ent is Circle, but it would be redundant because there are only two possibilities

     dim circ as Circle = ent

     ......

End If

 

 

Dave O.                                                                  Sig-Logos32.png
Message 6 of 11
Jeffrey_H
in reply to: chiefbraincloud

So your code is kinda like me repeating what Chief just said,

as in it is testing if it is a circle or blockreference so you can then test if it is a circle or blockreference.

 

 

Remember that after a little time you will figure out how use the docs and MGDDbg to find what you after but most important pay attention to post made by guys like ChiefBrainCloud where you pick up good coding and software design.

 

You can also find your answers @ TheSwamp
Message 7 of 11
chiefbraincloud
in reply to: Jeffrey_H

Don't give me too much credit, It'll go to my head!  I was not educated as a programmer, I am an engineer.  But I have been tinkering with Basic and later visual Basic for a very (very) long time.  My first Basic program was written for the Atari 800 back in ~1984, when I used to have to store my work on a cassette tape, before even 5 1/4" Low Density floppy disks.

 

I have only carried the Title of Programmer (now Software Developer) since 2005.

 

As far as the .NET framework Do's and Don'ts, I'll happily credit Kean Walmsley's blog for bringing me out of the VB6 dark ages.

Dave O.                                                                  Sig-Logos32.png
Message 8 of 11
mgorecki
in reply to: mgorecki

Thank you both for all of the information.  I'm using AutoCad 2008.  I bought a book on VB.Net for AutoCad a while ago and have used it quite a bit.  I also read these forums and try to learn from what other people go through.  I really appreciate that you take time out to help me.

 

Mark

Message 9 of 11
mgorecki
in reply to: mgorecki

I did some reading on "ObjectClass" and I wanted to try using it in just some test code, but I still get the error message:  "'ObjectClass' is not a member of 'Autodesk.AutoCAD.DatabaseServices.ObjectId'."

I'm using AutoCad 2008 with Visual Studio 2005.  Could there be something wrong with my setuip?  Is there something I should look for in particular?

 

Thanks,

Mark

Message 10 of 11
Jeff_M
in reply to: mgorecki

I just checked the ObjectArx2008 docs and the ObjectClass was not an available property in the 2008 managed API. So, no, there's nothing wrong with your setup.

Jeff_M, also a frequent Swamper
EESignature
Message 11 of 11
mgorecki
in reply to: Jeff_M

Hi Jeff,

Thanks for checking that.  Being fairly new, I was sure it was something I did.  I did use the code that you and the Chief showed me.  It worked great. 

 

Again, thank you both for all your help, not just for the code, but for explaining the "why's" involved with using certain methods.

Mark

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost