TheSwamp

Code Red => .NET => Topic started by: latour_g on July 08, 2013, 05:07:36 PM

Title: Layout name of a block reference
Post by: latour_g on July 08, 2013, 05:07:36 PM
Hi,
I would like to know on which layout my blockreference is.  Is there a way to know it ? Either on my objectId or BlockReference
Code: [Select]
using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
{
      foreach (ObjectId objId in blkSelIds)
     {                                       
           BlockReference br = (BlockReference)tr.GetObject(objId, OpenMode.ForWrite);
           ....
     }
}
Title: Re: Layout name of a block reference
Post by: BlackBox on July 08, 2013, 06:01:56 PM
Consider the BlockName, or BlockId Properties of your BlockReference Object.
Title: Re: Layout name of a block reference
Post by: BlackBox on July 08, 2013, 06:06:02 PM
Also worthy of note, to avoid an Exception, you might try casting each DBObject opened using the 'as' operator and then test for if != null.

Additionally, three no no need to open each DBObject ForWrite; simply open ForRead, and the. UpgradeOpen() the few Object you actually need.
Title: Re: Layout name of a block reference
Post by: WILL HATCH on July 08, 2013, 06:45:58 PM
I'd grab the owner id off the block reference.  It'll be the id of the block table record owning it, open that and you can access it's name property
Title: Re: Layout name of a block reference
Post by: Kerry on July 08, 2013, 09:08:24 PM

Perhaps we should have a recipe page for this sort of stuff ...  :|

or we should encourage Kean or Fenton to add one to the docs  ^-^
Title: Re: Layout name of a block reference
Post by: BlackBox on July 08, 2013, 09:11:27 PM
Consider the BlockName, or BlockId Properties of your BlockReference Object.

I'd grab the owner id off the block reference.  It'll be the id of the block table record owning it, open that and you can access it's name property

Out of curiosity... Why wouldn't you use the BlockName Property to query the name only, or BlockId to open via GetObject()?
Title: Re: Layout name of a block reference
Post by: WILL HATCH on July 09, 2013, 01:02:14 AM
Out of curiosity... Why wouldn't you use the BlockName Property to query the name only, or BlockId to open via GetObject()?
Because I haven't had the opportunity of somebody as awesome as you pointing those properties out to me yet   :| it makes me curious if the 'get' function for the BlockName property opens the owner and grabs the name property.

Thanks!
Title: Re: Layout name of a block reference
Post by: latour_g on July 09, 2013, 09:01:16 AM
Well I haven't found the layout yet (either ID or name, doesn't matter)

BlockReference br = (BlockReference)tr.GetObject(objId, OpenMode.ForRead);

br.BlockName return me either Model_Space or Paper_Space --> it doesn't tell me the exact layout name
br.BlockId --> it doesn't return me the same ID as my current layout ID
Title: Re: Layout name of a block reference
Post by: BlackBox on July 09, 2013, 09:23:25 AM
Out of curiosity... Why wouldn't you use the BlockName Property to query the name only, or BlockId to open via GetObject()?

Because I haven't had the opportunity of somebody as awesome as you pointing those properties out to me yet...

There's no place for that level of sarcasm here  :-P

... makes me curious if the 'get' function for the BlockName property opens the owner and grabs the name property.

Since string BlockName is a Property inherited from Entity : DBObject, I'd (perhaps incorrectly) presume that this is written into the entity data itself (DXF 410)... So no need for Transaction at runtime to retrieve the string. *speculation*
Title: Re: Layout name of a block reference
Post by: n.yuan on July 09, 2013, 09:37:18 AM
Well I haven't found the layout yet (either ID or name, doesn't matter)
...
br.BlockId --> it doesn't return me the same ID as my current layout ID

Of course br.BlockId is not the same as the current Layout ID.

Model/PaperSpace (BlockTableRecord) is not Layout. Layout is a record in LayoutDictionary associated with a BlockTableRecord (Model/PaperSpace). For each "space" BlockTableRecord, its "IsLayout" property is True, and its "LayoutId" property has a valid ObjectId value, which is the corresponding Layout's Id. That is, you can get a Layout name through this route:

Entity->Entity.BlockId/OwnerId->"space" BlockTableRecord->BlockTableRecord.LayoutId->Layout->Layout.LayoutName
Title: Re: Layout name of a block reference
Post by: BlackBox on July 09, 2013, 09:38:55 AM
Well I haven't found the layout yet (either ID or name, doesn't matter)

Firstly, a Layout is actually two separate Objects... The Layout, and the Block:

Quote from: ActiveX Online Documentation, Layout Object

Layout Object (http://entercad.ru/acadauto.en/index.html?page=idh_layout_object.htm)

The representation of a layout is slightly different in ActiveX from that of the AutoCAD user interface. In ActiveX, the content of a standard AutoCAD layout is broken out into two separate objects: Layout object and Block object. The Layout object contains the plot settings and the visual properties of the layout as it appears in the AutoCAD user interface. The Block object contains the geometry for the layout.

Each Layout object is associated with one Block object. To access the Block object associated with a given layout, use the Block property. Conversely, each Block object is associated with one Layout object. To access the Layout object associated with a given Block, use the Layout property for that block.

In ActiveX, in addition to the paper space layouts, model space is considered a layout.



BlockReference br = (BlockReference)tr.GetObject(objId, OpenMode.ForRead);

br.BlockName return me either Model_Space or Paper_Space --> it doesn't tell me the exact layout name
br.BlockId --> it doesn't return me the same ID as my current layout ID

My misunderstanding... What you actually want to do then, to get Layout.LayoutName, is to first open the Entity.BlockId (BlockTableRecord) ForRead, then open the BlockTableRecord.LayoutId (Layout) ForRead to access the LayoutName Property.

[Edit] - Looks like n.yuan beat me to it. *kicks dirt*
Title: Re: Layout name of a block reference
Post by: BlackBox on July 09, 2013, 09:48:53 AM
Here's a quick Extension Method (no exception handling):

Code - C#: [Select]
  1. namespace Autodesk.AutoCAD.DatabaseServices
  2. {
  3.     public static class EntityExtensions
  4.     {
  5.         public static string LayoutName(this Entity ent, Transaction tr)
  6.         {
  7.             BlockTableRecord blockTableRecord =
  8.                 (BlockTableRecord)tr.GetObject(ent.BlockId, OpenMode.ForRead);
  9.  
  10.             Layout layout =
  11.                 (Layout)tr.GetObject(blockTableRecord.LayoutId, OpenMode.ForRead);
  12.  
  13.             return layout.LayoutName;
  14.         }
  15.     }
  16. }
  17.  

... Example:
Code - C#: [Select]
  1. // start transaction
  2.  
  3.     // get dbobject
  4.  
  5.     BlockReference br = (BlockReference)obj;
  6.  
  7.     string layoutName = br.LayoutName(tr);
  8.  
  9.     // commit()
  10.  



[Edit] - Changed BlockReference to Entity.
[Edit] - Removed duplicate using statement from extension method.
Title: Re: Layout name of a block reference
Post by: latour_g on July 09, 2013, 04:56:38 PM
Thank you all very much ! I appreciate your help.