Author Topic: Importing a Layout from a Template  (Read 12806 times)

0 Members and 1 Guest are viewing this topic.

zoltan

  • Newt
  • Posts: 188
Re: Importing a Layout from a Template
« Reply #15 on: January 16, 2012, 08:23:55 PM »
I've actually been having the same issues.  After I import a layout from a template, I cannot get any of the viewports with the Layout.GetViewports method until I make the layout active.

fixo

  • Guest
Re: Importing a Layout from a Template
« Reply #16 on: January 17, 2012, 04:44:14 AM »
Wouldn't help addind this lineat the end?
Code: [Select]
ed.UpdateTiledViewPortsFromDataBase();

zoltan

  • Newt
  • Posts: 188
Re: Importing a Layout from a Template
« Reply #17 on: January 17, 2012, 08:32:35 AM »
When I use UpdateTiledViewPortsFromDatabase() or UpdateTiledViewPortsInDatabase(), it gives me eNotApplicable.

The documentation gives a lot of help on how to use these methods!  :roll:

Jeff H

  • Needs a day job
  • Posts: 6103
Re: Importing a Layout from a Template
« Reply #18 on: January 17, 2012, 04:51:25 PM »
Layouts have an Initialize method, that should take care of some of the issues with making a new Layout.

The documentation does not specify, but when you use LayoutManager to create a layout it asscioates it with a BlockTableRecord.
There is Layout.AddToLayoutDictionary, but have not messed with it. I guess you would have to create a new Btr yourself?

Are you calling Layout.Initialize?

Jeff H

  • Needs a day job
  • Posts: 6103
Re: Importing a Layout from a Template
« Reply #19 on: January 17, 2012, 05:50:21 PM »
the newly added layout acts as if it has not been initialized.  Once I switch to a different layout, back to the newly created layout and run a zoom extents on the layout, everything looks correct.


I think this is what you are after,
updating the code posted a while back I forgot to dispose the database(thanks kaefer for pointing it out) but the main change is this

Code: [Select]
                    newLayout.Initialize();
                    PlotSettingsValidator psv = PlotSettingsValidator.Current;
                    psv.SetZoomToPaperOnUpdate(newLayout, true);

Even for being just a simple quickly thrown together example it really needs to be  restructured, but the previous code with 2 changes mentioned
 
Code: [Select]
        [CommandMethod("CopyLayout")]
        public void CopyLayout()
        {
            string layoutName = "Test";
            string fileName = @"C:\Testing\LayoutTest.dwt";

            using (Database templateDb = new Database(false, true) as Database)
            {
                templateDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, true, "");
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database db = doc.Database;
                LayoutManager layoutManager = LayoutManager.Current;
                using (Transaction trx = db.TransactionManager.StartTransaction())
                using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction())
                {
                    DBDictionary layoutDictionary = trx.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;

                    if (layoutDictionary.Contains(layoutName))
                    {
                        ed.WriteMessage("\nThis Layout is already in drawing.");
                        return;
                    }
                    DBDictionary templateLayoutDictionary = templateTrx.GetObject(templateDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                    if (!(templateLayoutDictionary.Contains(layoutName)))
                    {
                        ed.WriteMessage("\nTemplate does not contain a Layout with that name.");
                        return;
                    }
                    ObjectId newLayoutId = layoutManager.CreateLayout(layoutName);
                    Layout newLayout = trx.GetObject(newLayoutId, OpenMode.ForWrite) as Layout;
                    Layout templateLayout = templateLayoutDictionary.GetAt(layoutName).GetObject(OpenMode.ForWrite) as Layout;
                    newLayout.CopyFrom(templateLayout);
                    BlockTableRecord templateLayoutBtr = templateTrx.GetObject(templateLayout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
                    ObjectIdCollection objIdColl = new ObjectIdCollection();
                    foreach (ObjectId id in templateLayoutBtr)
                    {
                        objIdColl.Add(id);
                    }
                    BlockTable extBt = templateDb.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
                    IdMapping map = new IdMapping();
                    db.WblockCloneObjects(objIdColl, newLayout.BlockTableRecordId, map, DuplicateRecordCloning.Replace, false);
                    newLayout.Initialize();
                    PlotSettingsValidator psv = PlotSettingsValidator.Current;
                    psv.SetZoomToPaperOnUpdate(newLayout, true);
                 
                    templateTrx.Commit();
                    trx.Commit();
                }
                layoutManager.CurrentLayout = layoutName;
            }
           
        }

Bryco

  • Water Moccasin
  • Posts: 1855
Re: Importing a Layout from a Template
« Reply #20 on: January 17, 2012, 08:37:46 PM »
Are the viewports on?(vp.On = true;)  I think when you copy a vp manually it's default is off.

dull_blades

  • Guest
Re: Importing a Layout from a Template
« Reply #21 on: January 19, 2012, 11:58:43 AM »
Uggg... still stumped.

Jeff, I grabbed your update code and updated mine with the same updates you posted here and still have the same issue with your code and my code.  Everything works great in a brand new drawing file, but fails to "initialize" the imported layout in certain existing drawings.

Attached are a couple of files someone can test (time permitting).  The "Layout_Template.dwt" file contains a layout named "Template" that I am importing in both cases.  The "ImportLayoutTest.dwg" is the file that is having issues.  This was a file that had a lot of content in it.  I deleted everything in the file and purged it to see if I could narrow it down to a drawing object, but even after cleaning up the drawing, the issue still occurs.

Here are the steps to see it work properly:

-Start AutoCAD with a new drawing file.
-Run the CopyLayout command importing the "Template" layout from the attached "Layout_Template.dwt" file.
-Everything works as expected (Except for that strange viewport that pops in around the outside of the paper layout).

Here are the steps to see it fail:

-Open the "ImportLayoutTest.dwg" file.
-Run the CopyLayout command importing the "Template" layout from the attached "Layout_Template.dwt" file.
-You end up with a Paper space layout with nothing on it.  The "paper" is displayed properly, but nothing else appears to have imported.  If you do a zoom extents, then the "paper" goes away and the objects from the template are displayed.  If you switch to another layout then switch back to the newly imported layout and do another zoom extents, everything shows up and displays as expected.

I don't understand what the difference between the existing file and a new file are that casue this behaviour.

Any ideas?


dull_blades

  • Guest
Re: Importing a Layout from a Template
« Reply #22 on: January 19, 2012, 12:01:03 PM »
By the way...

I even deleted the viewports out of the template to see if they were part of the issue, but after deleting them, the issue persists.

Jeff H

  • Needs a day job
  • Posts: 6103
Re: Importing a Layout from a Template
« Reply #23 on: January 19, 2012, 01:04:02 PM »
What happens if you do the CopyLayout() command from paperspace?
 
 

dull_blades

  • Guest
Re: Importing a Layout from a Template
« Reply #24 on: January 19, 2012, 01:41:47 PM »
Well what do you know!  It works great from PaperSpace!

I thought I tried that yesterday and got a fatal error, but it seems to be working now!   So why would it work from ModelSpace from a new drawing, but not from ModelSpace of an existing drawing?


GVDB

  • Guest
Re: Importing a Layout from a Template
« Reply #25 on: January 24, 2012, 09:41:54 AM »
Hi Guys,

great thread here.
I try to use your code but get stuck on it.

What I want is: from an empty new drawing clone an Inventor dwg with WBlockCloneObjects.
When I open the inventor dwg in autocad it is just a layout but with Inventor objects in it.

With your code I get the ObjectIdCollection (count = 23 in my case)
Create a new layout with the size and name of the inventor layout name, but I can't get the inventor objects to clone in my new autocad layout.

Do you have a clue?

Code: (for cloning autocad dwg it works fine)

    public static Database WblockCloneFromExternalDWGfile(string filename, bool isinventorfile)
    {
        using (DocumentLock targetDocumentLock = Active.Document.LockDocument())
        {
            Database targetDatabase = Active.WorkingDatabase;
            Database sourchDatabase = new Database(false, true);
            sourchDatabase.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, true, "");
           
            using (Transaction sourchTransaction = sourchDatabase.TransactionManager.StartTransaction())
            {
                BlockTable sourchBlockTable = (BlockTable)sourchDatabase.BlockTableId.GetObject(OpenMode.ForRead);
                BlockTableRecord sourchSpace;
                if (isinventorfile) { sourchSpace = (BlockTableRecord)sourchBlockTable[BlockTableRecord.PaperSpace].GetObject(OpenMode.ForRead); }
                else { sourchSpace = (BlockTableRecord)sourchBlockTable[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForRead); }

                ObjectIdCollection objectIDCollection = new ObjectIdCollection();

                foreach (ObjectId objectID in sourchSpace) { objectIDCollection.Add(objectID); }

                using (Transaction targetTransaction = targetDatabase.TransactionManager.StartTransaction())
                {
                    BlockTable targetBlockTable = (BlockTable)targetDatabase.BlockTableId.GetObject(OpenMode.ForWrite);
                    BlockTableRecord targetSpace;
                    IdMapping idMapping = new IdMapping();

                    if (isinventorfile)
                    {
                        //DBDictionary sourchLayoutDirectory = (DBDictionary) sourchDatabase.LayoutDictionaryId.GetObject(OpenMode.ForRead);
                        //Layout sourchLayout = (Layout) sourchLayoutDirectory.GetAt("Blad").GetObject(OpenMode.ForRead);
                        //ObjectId newLayoutId = LayoutManager.Current.CreateLayout(sourchLayout.LayoutName);
                        //Layout targetLayout = (Layout)newLayoutId.GetObject(OpenMode.ForWrite);
                        //LayoutManager.Current.CurrentLayout = targetLayout.LayoutName;
                        ////Layout targetLayout = new Layout();
                        ////targetLayout.LayoutName = sourchLayout.LayoutName;
                        //targetLayout.CopyFrom(sourchLayout);
                        //BlockTableRecord targetBlockTableRecord = new BlockTableRecord();
                        //targetBlockTableRecord.Name = sourchLayout.LayoutName;
                        //targetBlockTable.Add(targetBlockTableRecord);
                        //targetTransaction.AddNewlyCreatedDBObject(targetBlockTableRecord, true);
                        //sourchDatabase.WblockCloneObjects(objectIDCollection, targetBlockTableRecord.ObjectId, idMapping, DuplicateRecordCloning.Replace, false);
                        //targetLayout.AddToLayoutDictionary(targetDatabase, targetBlockTableRecord.ObjectId);
                        ////targetTransaction.AddNewlyCreatedDBObject(targetLayout, true);

                         DBDictionary sourchLayoutDirectory = (DBDictionary)sourchDatabase.LayoutDictionaryId.GetObject(OpenMode.ForRead);
                        Layout sourchLayout = (Layout)sourchLayoutDirectory.GetAt("Blad").GetObject(OpenMode.ForRead);

                        ObjectId targetLayoutId = LayoutManager.Current.CreateLayout(sourchLayout.LayoutName);
                        Layout targetLayout = (Layout)targetLayoutId.GetObject(OpenMode.ForWrite);
                        targetLayout.LayoutName = sourchLayout.LayoutName;
                        targetLayout.CopyFrom(sourchLayout);

                        targetDatabase.WblockCloneObjects(objectIDCollection, targetLayout.BlockTableRecordId, idMapping, DuplicateRecordCloning.Replace, false);

                        targetLayout.Initialize();
                        LayoutManager.Current.CurrentLayout = targetLayout.LayoutName;
                    }
                    else
                    {
                        targetSpace = (BlockTableRecord)targetBlockTable[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite);
                        targetDatabase.WblockCloneObjects(objectIDCollection, targetSpace.ObjectId, idMapping, DuplicateRecordCloning.Replace, false);
                    }

                    targetTransaction.Commit();
                }
            }
            return targetDatabase;
        }
    }
« Last Edit: January 27, 2012, 09:17:27 AM by GVDB »

Eycki

  • Guest
Re: Importing a Layout from a Template
« Reply #26 on: January 25, 2012, 08:34:02 AM »
Unfortunatly I can't get this working in my VB.NET program.  I used an online translator C# to VB.NET

Errors like:
Initialize is not a member of 'mymodulename'
BlockTableRecordId is not a member of 'mymodulename'
Value of type 'mymodulename' cannot be converted to 'Autodesk.AutoCAD.DatabaseServices.PlotSettings'
Value of type 'Autodesk.AutoCAD.DatabaseServices.DBObject' cannot be converted to 'mymodulename'

Anybody knows what I did wrong?

Edit: Of course I could always kill some puppies (use the SendStringToExecute command)  :evil:


the newly added layout acts as if it has not been initialized.  Once I switch to a different layout, back to the newly created layout and run a zoom extents on the layout, everything looks correct.


I think this is what you are after,
updating the code posted a while back I forgot to dispose the database(thanks kaefer for pointing it out) but the main change is this

Code: [Select]
                    newLayout.Initialize();
                    PlotSettingsValidator psv = PlotSettingsValidator.Current;
                    psv.SetZoomToPaperOnUpdate(newLayout, true);

Even for being just a simple quickly thrown together example it really needs to be  restructured, but the previous code with 2 changes mentioned
 
Code: [Select]
        [CommandMethod("CopyLayout")]
        public void CopyLayout()
        {
            string layoutName = "Test";
            string fileName = @"C:\Testing\LayoutTest.dwt";

            using (Database templateDb = new Database(false, true) as Database)
            {
                templateDb.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, true, "");
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                Database db = doc.Database;
                LayoutManager layoutManager = LayoutManager.Current;
                using (Transaction trx = db.TransactionManager.StartTransaction())
                using (Transaction templateTrx = templateDb.TransactionManager.StartTransaction())
                {
                    DBDictionary layoutDictionary = trx.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;

                    if (layoutDictionary.Contains(layoutName))
                    {
                        ed.WriteMessage("\nThis Layout is already in drawing.");
                        return;
                    }
                    DBDictionary templateLayoutDictionary = templateTrx.GetObject(templateDb.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                    if (!(templateLayoutDictionary.Contains(layoutName)))
                    {
                        ed.WriteMessage("\nTemplate does not contain a Layout with that name.");
                        return;
                    }
                    ObjectId newLayoutId = layoutManager.CreateLayout(layoutName);
                    Layout newLayout = trx.GetObject(newLayoutId, OpenMode.ForWrite) as Layout;
                    Layout templateLayout = templateLayoutDictionary.GetAt(layoutName).GetObject(OpenMode.ForWrite) as Layout;
                    newLayout.CopyFrom(templateLayout);
                    BlockTableRecord templateLayoutBtr = templateTrx.GetObject(templateLayout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
                    ObjectIdCollection objIdColl = new ObjectIdCollection();
                    foreach (ObjectId id in templateLayoutBtr)
                    {
                        objIdColl.Add(id);
                    }
                    BlockTable extBt = templateDb.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
                    IdMapping map = new IdMapping();
                    db.WblockCloneObjects(objIdColl, newLayout.BlockTableRecordId, map, DuplicateRecordCloning.Replace, false);
                    newLayout.Initialize();
                    PlotSettingsValidator psv = PlotSettingsValidator.Current;
                    psv.SetZoomToPaperOnUpdate(newLayout, true);
                 
                    templateTrx.Commit();
                    trx.Commit();
                }
                layoutManager.CurrentLayout = layoutName;
            }
           
        }
« Last Edit: January 25, 2012, 12:22:25 PM by Eycki »

bargool

  • Guest
Re: Importing a Layout from a Template
« Reply #27 on: February 15, 2013, 07:49:22 AM »
I've actually been having the same issues.  After I import a layout from a template, I cannot get any of the viewports with the Layout.GetViewports method until I make the layout active.
I had this trouble and another one: I made PlotType to Layout and StdScaleType to StdScale1To1, but when I went away from created Layout and return, PlotType changed to Extents and StdScaleType to Fit.
Heh! I Just placed LayoutManager.Current.CurrentLayout at the and of this sequence of commands (Like Jeff made), and everything is fine!  :ugly: