Author Topic: "Cleanest" Method For Selecting All Blocks in PaperSpace  (Read 6126 times)

0 Members and 1 Guest are viewing this topic.

wannabe

  • Guest
"Cleanest" Method For Selecting All Blocks in PaperSpace
« on: July 04, 2009, 02:41:53 PM »
Hi Everyone,

I'm trying to access blocks from other drawings for manipulation purposes, but I only want those that reside in paper space. Initially I looked at the DXFCodes, but I couldn't see one that was applicable for a typedValue filter. I then checked out PromptSelectionOptions() which only allows me to get all blocks from the active space. If the drawing isn't actually open, would paper space be the active space (I'm copying drawings into Database references via the ReadDWG() method to make global changes)?

Are there any DXF codes that can do this to save me from checking each selected block against the ObjectId for Model Space, which seems a "dirty" way of operating. The layoutName doesn't seem robust enough.

EDIT: Actually, I think the LayoutName DXF Code will be fine. I'll post up if I get any reported problems.


As always, comments are appreciated.
« Last Edit: July 04, 2009, 02:46:30 PM by wannabe »

wannabe

  • Guest
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #1 on: July 04, 2009, 04:00:25 PM »
When I tried it on the host drawing it worked. When I copied a selection of drawings into a Database reference it failed to recognise any blocks not in paper space with the filtering criteria in the post above.

Any suggestions?

gile

  • Water Moccasin
  • Posts: 2172
  • Marseille, France
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #2 on: July 04, 2009, 04:09:52 PM »
Hi,

Did you try (67, 1) ?

Another way should be iterating through each layout, and in each layout block table reference, through each object looking for a block references.
Speaking English as a French Frog

wannabe

  • Guest
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #3 on: July 04, 2009, 04:18:02 PM »
Yeah, I just realised that using a selection filter won't work when the Editor object is only going to work on open drawings.

So now it's a case of scanning each layout as you suggest. Not a problem, but could be cleaner.

gile

  • Water Moccasin
  • Posts: 2172
  • Marseille, France
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #4 on: July 04, 2009, 04:49:52 PM »
Here's a quick and dirty.
Let me know if there's a cleaner way (I'm newby and learning...)

Code: [Select]
public ArrayList GetBlockRefInLayouts()
{
    Database db = Application.DocumentManager.MdiActiveDocument.Database;
    ArrayList result = new ArrayList();
    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        DBDictionary NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
        DBDictionary layouts = (DBDictionary)tr.GetObject(NOD.GetAt("ACAD_LAYOUT"), OpenMode.ForRead);
        foreach (DBDictionaryEntry entry in layouts)
        {
            if (entry.Key != "Model")
            {
                Layout lay = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
                BlockTableRecord layoutBtr = (BlockTableRecord)tr.GetObject(lay.BlockTableRecordId, OpenMode.ForRead);
                foreach (ObjectId id in layoutBtr)
                {
                    BlockReference blk = tr.GetObject(id, OpenMode.ForRead) as BlockReference;
                    if (blk != null)
                        result.Add(blk);
                }
            }
        }
        tr.Commit();
    }
    return result;
}
Speaking English as a French Frog

wannabe

  • Guest
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #5 on: July 04, 2009, 05:07:14 PM »
Thats basically what I did, with slight differences that provide the same result.

Cheers for posting.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11653
  • class keyThumper<T>:ILazy<T>
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #6 on: July 04, 2009, 11:50:16 PM »
gile,
thats essentially how I'd do it as well.

except there is no necessity to tr.Commit() because you are not revising the database , so there is nothing to commit.
... at least that's my understanding

:)

/// kdub
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

sinc

  • Guest
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #7 on: July 05, 2009, 12:01:11 AM »
If you don't commit, then the transaction aborts, and a commit has less overhead than an abort.  At least, according to some of Kean's blog posts.  It might be an interesting thing to test.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11653
  • class keyThumper<T>:ILazy<T>
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #8 on: July 05, 2009, 12:18:36 AM »
Richard, yes, appears I was incorrect ..

I found that reference
http://through-the-interface.typepad.com/through_the_interface/2007/04/iterating_throu.html


Quote
There's a DevNote on the ADN site covering this topic:

http://adn.autodesk.com/adn/servlet/devnote?siteID=4814862&id=5546971&linkID=4900509

Here's an excerpt:

>>>
... there is a huge performance difference between Commit() and Abort(). So, when opening objects for read, you definitely want to explicitly call Commit() even though you didn't really change anything. As evidenced by a few test functions, Abort() should only be used under "duress" because of the performance hit.
<<<

A read-only transaction (even one that opens objects for write, but doesn't modify them) will not set the database modified flag (DBMOD) when committed. It's the individual "set" methods that call assertWriteEnabled(), forcing DBMOD to non-zero.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

gile

  • Water Moccasin
  • Posts: 2172
  • Marseille, France
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #9 on: July 05, 2009, 03:05:23 AM »
Thanks all,

I was lucky if the 'commit' way is the right way.
The commit/dispose/abort stuff keeps difficult to undersand for me.
Speaking English as a French Frog

T.Willey

  • Needs a day job
  • Posts: 5211
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #10 on: July 06, 2009, 11:20:58 AM »
I thought I was told by Tony T. that you didn't want to return an object, but rather an ObjectId.  I'm talking about this section of gile's code

Code: [Select]
                foreach (ObjectId id in layoutBtr)
                {
                    BlockReference blk = tr.GetObject(id, OpenMode.ForRead) as BlockReference;
                    if (blk != null)
                        result.Add(blk);
                }

I would even think that one would want to return the handle, as the ObjectId is created upon opening the database ( drawing ), and would not be the same the next time you open the drawing, but the handle always would be, so the handle and the drawing name would be the best way to go.

That was my understanding at least.  If I'm wrong, carry on.   :-)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

sinc

  • Guest
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #11 on: July 06, 2009, 12:34:05 PM »
I thought I was told by Tony T. that you didn't want to return an object, but rather an ObjectId.  I'm talking about this section of gile's code

Yeah, good catch.  That piece of code is creating a transaction and getting objects, then trying to return the objects after closing the transaction.  That's the no-no.

You can return objects in a method, but the transaction should still be active when you do so.

I'm not sure why you would want the handle...  It depends on your code, and what it does.  But for most purposes, the ObjectId is preferable.

Spike Wilbury

  • Guest
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #12 on: July 06, 2009, 01:15:40 PM »
and also, it will be much easier to return an ObjectIdCollection, since you can just call:

result layoutBtr.GetBlockReferenceIds();


maybe?

T.Willey

  • Needs a day job
  • Posts: 5211
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #13 on: July 06, 2009, 02:02:19 PM »
Thanks for the confirmation Sinc.

Luis,

That would just get all the inserts of that specific block definition, not all the blocks that are inserted ( nested ) within the definition.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

gile

  • Water Moccasin
  • Posts: 2172
  • Marseille, France
Re: "Cleanest" Method For Selecting All Blocks in PaperSpace
« Reply #14 on: July 06, 2009, 02:45:30 PM »
So, if I understand, it should have been :
Code: [Select]
foreach (ObjectId id in layoutBtr)
                {
                    BlockReference blk = tr.GetObject(id, OpenMode.ForRead) as BlockReference;
                    if (blk != null)
                        result.Add(id); // or result.Add(id.Handle);
                }

Or is there another way to evaluate if the object is a BlockReference ?
Speaking English as a French Frog