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

Propagate a block through multiple layouts

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
Anonymous
538 Views, 7 Replies

Propagate a block through multiple layouts

Hello,

 

I'm trying to import a a custom titleblock into each existing layout from a dwg. So far, i've been successful in importing this block into the first layout but can't seem to figure how to bring it into the remaining. I have a command that runs before this one that allows the user to define how many layouts should exist, so for instance, if a user opts to create 7 layouts, once they import this titleblock, i'd like it to appear in all 7 layouts. So far this is what i've got. It seems like a silly fix but i can't figure it out. Any help would be excellent.

 

namespace CHTitleBlockImportMetricH
{

public class CHTBMETRICH
{
// This is the name of my command
[Autodesk.AutoCAD.Runtime.CommandMethod("CHTBMETRICH")]

public void CHTBMetricCommand()
{
string comp = "C:\\ACADSTUFF\\tbmetric.dwg";
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Transaction tr = doc.TransactionManager.StartTransaction();

// Lock the new document
using (DocumentLock acLckDoc = doc.LockDocument())

try
{
string dwgName = HostApplicationServices.Current.FindFile(comp, acadApp.DocumentManager.MdiActiveDocument.Database, FindFileHint.Default);

Database db = new Database(false, false);

db.ReadDwgFile(dwgName, System.IO.FileShare.Read, true, "");

ObjectId BlkId;

BlkId = doc.Database.Insert(dwgName, db, false);

BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead, true);

BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForWrite);

BlockReference bref = new BlockReference(new Autodesk.AutoCAD.Geometry.Point3d(0, 0, 0), BlkId);

btr.AppendEntity(bref);

tr.AddNewlyCreatedDBObject(bref, true);

bref.ExplodeToOwnerSpace();

bref.Erase();

tr.Commit();
}
finally
{
tr.Dispose();
}
}
}
}

7 REPLIES 7
Message 2 of 8
chiefbraincloud
in reply to: Anonymous

BlockTableRecord.PaperSpace will only return the most recently activated layout's ObjectId. 


Option 1: You need to loop through the BlockTable checking each record's IsLayout property (Then possibly checking the name of the layout to see if it is one you are supposed to modify).

 

Option 2:  (preferred)  I think you should back up a step, to your previous post where you are creating the multiple layouts.  Create the first layout, and then add the Titleblock to it.  Then to create the remaining layouts, use LayoutManager.CopyLayout("Oldname", "Newname"), instead of using LayoutManager.CreateLayout("Name").

 

That would save you a few steps.

Dave O.                                                                  Sig-Logos32.png
Message 3 of 8
Anonymous
in reply to: chiefbraincloud

Hey,

 

Thanks for the suggestions. Shouldn't the BlockTableRecord.PaperSpace technically return all of my Layouts as they were just created seconds (or milliseconds) before in the command previous to this one? Sorry, this stuff is just a bit confusing at the moment.

Message 4 of 8
chiefbraincloud
in reply to: Anonymous

No, Each Layout is part of a separate PaperSpace BlockTableRecord, and the BlockTableRecord.PaperSpace property only returns the NAME (not ObjectId, as I had said before) of the most recently active one. 

 

There is another way to get the ObjectId directly which is to use SymbolUtilityServices.GetBlockPaperSpaceId(database), but it has the same limitation, as it only returns an ObjectId, not a ObjectIdCollection, so it returns the ObjectId of the most recently active Layout's BlockTableRecord.

Dave O.                                                                  Sig-Logos32.png
Message 5 of 8
Anonymous
in reply to: chiefbraincloud

Ok gotcha, makes sense. I'll have a go at it with the previous suggestions. Thanks very much.

Message 6 of 8
Anonymous
in reply to: Anonymous

I've been trying to get the LayoutManager.CopyLayout syntax right but i'm stuck. So far what i've got is this:

 


using (Transaction trx = db.TransactionManager.StartTransaction())// Start Transaction
{
LayoutManager lm = LayoutManager.Current;
for (int i = 3; i <= numLayouts; i++)
{
Layout layout = (Layout)trx.GetObject(lm.CopyLayout("Layout 1" , "Layout 2" + i.ToString()), OpenMode.ForWrite);
layout.Initialize();
}



trx.Commit();
ed.Regen();
}
}

 

A few of the errors I get are "Argument 1: cannot convert from 'void' to AutoDesk.AutoCAD.DatabaseServices. ObjectID'

 

and

 

The best overloaded method match for 'Autodesk.Autocad.DatabaseServices.Transaction.GetObject (Autodesk.AutoCAD.DatabaseServices.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode)' has some invalid arguments.

 

 

I'm essentially trying to copy "Layout 1" (as it now has my titleblock in it) "x" amount of times. I know this is probably simple, and i'd really appreciate a small push in the right direction.

 

Thanks again

Message 7 of 8
chiefbraincloud
in reply to: Anonymous

CopyLayout is a sub, it has no return value.

 

You need to do the CopyLayout on a line of code by itself, then if you have a need to open the Layout for further modification, you get the ObjectId of the new layout using LayoutManager.GetLayoutId(Layout name as string)

 

so inside your for loop

 

lm.CopyLayout("Layout 1" , "Layout 2" + i.ToString())

Layout layout = (Layout)trx.GetObject(lm.GetLayoutId("Layout 2" + i.ToString()), OpenMode.ForWrite);

 


 

Dave O.                                                                  Sig-Logos32.png
Message 8 of 8
Anonymous
in reply to: chiefbraincloud

Thanks a million, that worked perfect!

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