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

Highlight block within Xref

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
elliottpd11
2440 Views, 14 Replies

Highlight block within Xref

I'm searching for sample code for highlighting blocks within Xrefs.  I've written a "Find Block" program that works well for regular blocks within a drawing, but I'm having trouble modifiying to include blocks within Xrefs.  I've found code for nested blocks, but that doesn't seems to work for Xrefs.  Can you provide an example for Xrefs?  Thanks very much.  Pete Elliott

14 REPLIES 14
Message 2 of 15
Keith.Brown
in reply to: elliottpd11

Finding an item in an xref should be exactly the same as finding a nested item in a block.  Basically an xref is a block in your current drawing.  You need to dig down into that block and find the items that you want.  Below is a code snippet that I use to display custom tooltips.  It will find a tooltip in the main drawing or in an xref.  It uses the point monitor callback method to determine the object under the aperature and then return its objectID.  The code will continually dig into a block reference until it stops finding block references and instead finds one of the objects that I am searching for.

 

 

        public static void PointMonitor(object sender, PointMonitorEventArgs e)
        {
            toolTipObjectId = ObjectId.Null;

            if (Application.GetSystemVariable("RollOverTips").ToString() != "1" || !SuperToolTipSettings.EnableSuperToolTips)
                return;

            if ((e.Context.History & PointHistoryBits.FromKeyboard) == PointHistoryBits.FromKeyboard)
                return;

            FullSubentityPath[] paths = e.Context.GetPickedEntities();

            if (paths == null || paths.Length == 0)
                return;

            ObjectId[] ids = paths[0].GetObjectIds();

            if (ids == null || ids.Length == 0)
                return;

            var i = 0;

            if (!ids[i].IsValid)
                return;
            GetClass(ids, i)
            ;

        }

        private static void GetClass(ObjectId[] ids, int i)
        {   
// Here you would check the ObjectID and see if it is an object you are interested in.
// If so then return the objectID, if not check to see if it is a block reference and then
// Dig into that block reference and start again. if ((ids[i].ObjectClass.Name == "AecbDbDuct" && SuperToolTipSettings.DisplayDuct)) { toolTipObjectId = ids[i]; } if (ids[i].ObjectClass.Name == "AcDbBlockReference") { GetClass(ids, i + 1); } }

 

 

 

Message 3 of 15
elliottpd11
in reply to: Keith.Brown

In my application, there is no direct user selection, other than to select a block name from a list.  So I am assembling the id path using the xref id and the block reference id.  But this is not working.  Can you suggest what I may be doing wrong?

 

''' <summary>

''' Highlights or unhighlights an xref-nested block

''' </summary>

''' <param name="myTrans">Transaction object</param>

''' <param name="myBT">BlockTable object for main drawing</param>

''' <param name="myID">ObjectID for the block reference within xref</param>

''' <param name="BlockName">Block name of the block reference</param>

''' <param name="IsHighlighted">True to highlight, False to unhighlight</param>

''' <version>v12.1.1.0 09/02/14 PDE: Initial program</version>

SubHighlightXrefBlock(ByRef myTrans As Transaction, ByRef myBT As BlockTable, ByVal myID As ObjectId,

                               ByVal BlockName As String, ByVal IsHighlighted As Boolean)

    If BlockName.Contains("|") Then

        Dim XrefName As String = BlockName.Substring(0, BlockName.IndexOf("|"))

           If XrefName <> String.Empty Then

            If myBT.Has(XrefName) Then

                 Dim myXrefBTR As BlockTableRecord = CType(myTrans.GetObject(myBT(XrefName), OpenMode.ForRead), BlockTableRecord)

                 Dim xrefInstances As ObjectIdCollection = myXrefBTR.GetBlockReferenceIds(True, False)

                        If xrefInstances.Count > 0 Then

                      Dimpathids(1) As ObjectId

                      pathids(0) = xrefInstances(0)

                               pathids(1) = myID

                      Dim subEntID As SubentityId = New SubentityId(SubentityType.Null, IntPtr.Zero)

                               Dim SubEntPath As FullSubentityPath = New FullSubentityPath(pathids, subEntID)

                               Dim xrefblock As Entity = CType(myTrans.GetObject(xrefInstances(0), OpenMode.ForRead, False, True), Entity)

                               If IsHighlighted Then

                           xrefblock.Highlight(SubEntPath, False)

                               Else

                           xrefblock.Unhighlight(SubEntPath, False)

                               EndIf

                 EndIf

            EndIf

        EndIf

    EndIf

EndSub

Message 4 of 15
Keith.Brown
in reply to: elliottpd11

Well there are some things that you left out that you need to think about.  How deep are you going to go with finding the block?  What if the block is nested in a block that is nested in a block that is inside of an xref?

 

To find ALL of the blocks you should take the approach that I showed.  Get the block name from the user.  Then get all blocks and cycle through them getting nested entities until you find the blockname that you want.  Then get the object ID of the block reference and then highlight it.  That is the approach that I would take.  I believe that it is the only way to get ALL of the blocks in one operation without picking.  If you only care about one level deep or two levels deep or .....  then you can take a different approach.

 

Again there is no need to specifically look for an xref.  The xref is just a block reference in your current drawing so just look for the block name inside of nested entities.  Keep going until you find your block reference or there are no more block references.  Recursion works great in this instance.  Just keep a running total of all objectids that equal your block name.

Message 5 of 15
elliottpd11
in reply to: Keith.Brown

How to get FullSubentityPath from blockreference objectid?

Message 6 of 15

I have only briefly looked at the code in this thread, but I'm wondering, are you SURE it's not finding the blocks, or is it just not highlighting them?

 

I have a bit of Lisp code I wrote a very long time ago, the display the grips of object(s) nested in xref(s), by user selection.  this was intended to be able to better see the object in question when working in 3d and looking at things from the side, or front, trying to figure out if there are collisions.  I still find the routine to be useful to this day, but it always had a problem, it would highlight and display grips for objects in the current drawing, but the nested objects would only display grips, they would not show the highlight. 

Dave O.                                                                  Sig-Logos32.png
Message 7 of 15

I have no problem finding the block, in fact when my subroutine is called, I pass in the ObjectID for the block. It's the highlighting that is the problem for me.
Message 8 of 15
moogalm
in reply to: elliottpd11

Hi

 

I believe "myID" is the bref Object Id , you can get Bref entity and use

refblock.Highlight(); for highlighting. Is this not working at your end ?

 

Message 9 of 15
elliottpd11
in reply to: moogalm

Yes, "myID" is the ObjectID for the block, nested within the Xref block, but simply calling the highlight method for the BlockReference does nothing.
Message 10 of 15
moogalm
in reply to: elliottpd11

Hi

 

Is it possible for your share your project , I will research at my end. I don't have readymade sample to work out.

 

Message 11 of 15
moogalm
in reply to: moogalm

Hi ,

 

Sorry , I couldn't offer a better solution at the moment ,besides this

 

Thanks,

Message 12 of 15
elliottpd11
in reply to: moogalm

So then, would it be correct to say that there is no way to highlight blocks contained within an Xref, using the .net API? - Pete Elliott

Message 13 of 15
moogalm
in reply to: elliottpd11

Hi Pete ,

 

There is way as I discussed with you in my earlier comments using overrule ,besides that I don't have better solution , may be others can provide.

 

Thanks

Madhu.

Message 14 of 15
elliottpd11
in reply to: moogalm

I've been playing with transient graphics, and am not very knowledgable in this area.  This code will highlight a block nested within an Xref.  But I'm wondering, does this code leave anything behind in memory that can cause issues later?

[The variable myBR is a BlockReference opened for read within a transaction.]  Regen seems to remove the highlight.

Dim thisDrawable As GraphicsInterface.Drawable = myBR

Dim col As New IntegerCollection

GraphicsInterface.TransientManager.CurrentTransientManager.AddTransient(thisDrawable,

   GraphicsInterface.TransientDrawingMode.Highlight, 128, col)

Thanks, Pete Elliott

Message 15 of 15
moogalm
in reply to: elliottpd11

Hi Pete ,

 

That's a good idea to solve your case !

 

But clone your Bref and add as transient and make sure you remove transient using erase transient api.

Benefit of cloning is to avoid unexpected memory chaos :), clone is not a DBR object ,so you can play as you wish.

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