.NET

.NET

Reply
Active Contributor
varadan01
Posts: 47
Registered: ‎03-16-2012
Message 1 of 8 (540 Views)
Accepted Solution

How to create objIds collectns of specified xref layer entity into new drawing?

540 Views, 7 Replies
10-14-2012 10:51 PM

                RTA_ApplicationData.Db = new Database(false, true);

                RTA_ApplicationData.Db.ReadDwgFile(@"C:\Users\varadarajan.g\Desktop\Export\rac_basic_sample_project-Sheet-A105-Unnamed.dwg", FileOpenMode.OpenForReadAndWriteNoShare, false, "");         

               //RTA_ApplicationData.Db = RTA_ApplicationData.Doc.Database;   
               Transaction tr = RTA_ApplicationData.Db.TransactionManager.StartTransaction();
               BlockTable bt = (BlockTable)tr.GetObject(RTA_ApplicationData.Db.BlockTableId, OpenMode.ForRead, false);
               ObjectIdCollection idsCollecton = new ObjectIdCollection();
               foreach (ObjectId item in bt)
               {
                   BlockTableRecord btr = (BlockTableRecord)tr.GetObject(item, OpenMode.ForRead);                   
                   if (btr.IsFromExternalReference)
                   {
                       foreach (ObjectId obj in btr)
                       {
                           Entity solEntity = (Entity)tr.GetObject(obj, OpenMode.ForWrite);
                           string strLayer = solEntity.Layer;
                           if (strLayer.Contains("S-GRID"))
                           {
                               idsCollecton.Add(solEntity.ObjectId);
                           }                           
                    
                       }
                   }
               }

tr.Commit();

}
               How to create idsCollecton into new drawing file.if i create this object collection into new database drawing by using WblockCloneObjects its shows eWrongdatabase.plz any one provide working sample code

With Regards,
GVaradarajan

Hi Varadarajan,

 

Here is a blog post that should help :

http://through-the-interface.typepad.com/through_the_interface/2009/05/importing-autocad-layers-from-xrefs-using-net.html

 

Also try this sample code which I have modified based on the code that you shared :

 

[CommandMethod("FXRef")]
public void FilterLayerEntities()
{
Document document = Application.DocumentManager.MdiActiveDocument;
Editor ed = document.Editor;
Database destDb = Application.DocumentManager.MdiActiveDocument.Database;
using (Database srcDb = new Database(false, false))
{
ObjectIdCollection idsCollecton = new ObjectIdCollection();
srcDb.ReadDwgFile(@"C:\Temp\Test1.dwg", FileOpenMode.OpenForReadAndWriteNoShare, false, "");
srcDb.ResolveXrefs(true, false);
using (Transaction tr = srcDb.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(srcDb.BlockTableId, OpenMode.ForRead, false) as BlockTable;
foreach (ObjectId id in bt)
{
BlockTableRecord btr = tr.GetObject(id, OpenMode.ForWrite) as BlockTableRecord;
String BlockName = btr.Name;
if (btr.IsFromExternalReference && btr.IsResolved)
{
idsCollecton.Clear();
//using (Database xrefDb = btr.GetXrefDatabase(false))
using (Database xrefDb = new Database(false, false))
{
xrefDb.ReadDwgFile(btr.GetXrefDatabase(false).Filename, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
xrefDb.ResolveXrefs(true, false);
using (Transaction tr1 = xrefDb.TransactionManager.StartTransaction())
{
BlockTableRecord xrefModelSpaceBTR = tr1.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(xrefDb), OpenMode.ForRead, false) as BlockTableRecord;
foreach (ObjectId entId in xrefModelSpaceBTR)
{
Entity solEntity = tr1.GetObject(entId, OpenMode.ForWrite) as Entity;
idsCollecton.Add(solEntity.ObjectId);
}
tr1.Commit();
}
IdMapping mapping = new IdMapping();
xrefDb.WblockCloneObjects(idsCollecton,
SymbolUtilityServices.GetBlockModelSpaceId(destDb),
mapping,
DuplicateRecordCloning.Replace,
false
);
}
}
}
tr.Commit();
}
}
}

 To try this :

 

1) Copy the attached drawings to c:\temp

2) Start AutoCAD 2012 / 2013

3) Netload the dll

4) run the "fxref" command

 

This command should wblockclone all the entities (with layer info) from Test2.dwg which is xrefed in Test1.dwg and add it to the current database.

 

 Hope this helps.

ADN Support Specialist
Balaji_Ram
Posts: 749
Registered: ‎03-21-2011
Message 2 of 8 (504 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

10-19-2012 07:23 AM in reply to: varadan01

Hi Varadarajan,

 

I dont have a ready sample that exactly does what you want, but the reason for the "eWrongDatabase" is due to mix-up that you have in your code.

 

The transaction that you have opened is for the database created using ReadDwgFile and objectId using which the entity is being retrieved belongs to a xref database.

 

You may want to access the right database by traversing the Xref  graph.

Following code might help you :

 

db.ResolveXrefs(false, false);
XrefGraph xg = db.GetHostDwgXrefGraph(true);

for (int i = 0; i < xg.NumNodes; i++)
{
    XrefGraphNode xgn = xg.GetXrefNode(i);

    switch (xgn.XrefStatus)
    {
        case XrefStatus.Resolved:
            {
                Database xdb = xgn.Database;
                if (xdb != null)
                {
                               
                }
            }
            break;
    }
}

 

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Active Contributor
varadan01
Posts: 47
Registered: ‎03-16-2012
Message 3 of 8 (468 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

10-21-2012 11:16 PM in reply to: Balaji_Ram

 private void CloneObjectIds(ObjectIdCollection idsObjEntity, String strFileName)
        {
            try
            {
                Database dbNew = new Database(true, false);
                Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = dbNew.TransactionManager;
                ObjectId idModelSpace;
                using (Transaction mTy = tm.StartTransaction())
                {
                    BlockTable bt = (BlockTable)tm.GetObject(dbNew.BlockTableId, OpenMode.ForRead, false);
                    BlockTableRecord Btr = (BlockTableRecord)tm.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead, false);
                    //idModelSpace = bt[BlockTableRecord.ModelSpace];
                    idModelSpace = Btr.Id;
                }
                IdMapping Mappin = new IdMapping();
                RTA_ApplicationData.Db.WblockCloneObjects(idsObjEntity, idModelSpace, Mappin, DuplicateRecordCloning.Ignore, false);
                

                String strFolderName = strFileName;
                strFileName = strFileName + ".dwg";
                String strPathName;
                String pathName = Assembly.GetExecutingAssembly().Location;
                pathName = pathName.Replace("LayerFilter.dll", "Drawing");
                DirectoryInfo dirInfo = Directory.CreateDirectory(pathName + "\\" + strFolderName);
                if (System.IO.File.Exists(pathName + "\\" + strFolderName))
                {
                    return;
                }
                dbNew.SaveAs(pathName + "\\" + strFolderName + "\\" + strFileName, DwgVersion.Newest);

}
}
}

idsObjEntity-is Collection of Xref Entities . From this Object Collection Xref i want to create new dwg file. This method is correct or have any other method.

With Regards,
GVaradarajan
ADN Support Specialist
Balaji_Ram
Posts: 749
Registered: ‎03-21-2011
Message 4 of 8 (426 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

10-30-2012 10:21 AM in reply to: varadan01

Hello Varadarajan,

 

It is a little hard to say what exactly might be causing that error.

 

Based on the code snippet that you shared, it could be due to the ObjectIds in "idsObjEntity" not belonging to the "RTA_ApplicationData.Db".

 

Since you say that the "idsObjEntity" contains Xref entities, they might not belong to the database using which the WblockCloneObjects method is being called.

 

You may try having multiple calls to the WBlockCloneObjects and each time ensuring that the ids in the collection belong to the database with which you are calling the WBlockCloneObjects method.

 

If that does not help, can please share a simplified buildable sample project and a drawing along with the steps to reproduce the error ?

 



Balaji
Developer Technical Services
Autodesk Developer Network

Active Contributor
varadan01
Posts: 47
Registered: ‎03-16-2012
Message 5 of 8 (407 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

11-01-2012 12:15 AM in reply to: Balaji_Ram

Hi Balaji Sir!

 Here I attached the Doc for your reference. Thanks for ur effort.

 

With Regards,
GVaradarajan
ADN Support Specialist
Balaji_Ram
Posts: 749
Registered: ‎03-21-2011
Message 6 of 8 (349 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

11-06-2012 11:11 PM in reply to: varadan01

Hi Varadarajan,

 

Sorry for the delay in getting back to you.

 

Here is a sample code that works ok.

 

[CommandMethod("FXRef")]
public void FilterLayerEntities()
{
	Document document = Application.DocumentManager.MdiActiveDocument;
	Editor ed = document.Editor;
	Database destDb = Application.DocumentManager.MdiActiveDocument.Database;

	using (Database srcDb = new Database(false, false))
	{
		ObjectIdCollection idsCollecton = new ObjectIdCollection();

		srcDb.ReadDwgFile(@"C:\Temp\Test2.dwg", FileOpenMode.OpenForReadAndWriteNoShare, false, "");
		srcDb.ResolveXrefs(true, false);

		using (Transaction tr = srcDb.TransactionManager.StartTransaction())
		{
			BlockTable bt = tr.GetObject(srcDb.BlockTableId, OpenMode.ForRead, false) as BlockTable;
			foreach (ObjectId id in bt)
			{
				BlockTableRecord btr = tr.GetObject(id, OpenMode.ForWrite) as BlockTableRecord;
				String BlockName = btr.Name;
				if (btr.IsFromExternalReference && btr.IsResolved)
				{
					foreach (ObjectId entId in btr)
					{
						Entity solEntity = tr.GetObject(entId, OpenMode.ForWrite) as Entity;
						if (solEntity.Layer.Contains("S-GRID"))
						{
							idsCollecton.Add(solEntity.ObjectId);
						}
					}
				}
			}
			tr.Commit();
		}

		IdMapping mapping2 = new IdMapping();
		srcDb.WblockCloneObjects(idsCollecton,
									SymbolUtilityServices.GetBlockModelSpaceId(destDb),
									mapping2,
									DuplicateRecordCloning.Replace,
									false
								);
	}
}

In the code that you shared there are a few issues which you should correct :

1) Always dispose the in-memory database after you are done with it.

2) Dont store the entities in a collection. You should only store the ObjectId and use it to open the entity when required.



Balaji
Developer Technical Services
Autodesk Developer Network

Active Contributor
varadan01
Posts: 47
Registered: ‎03-16-2012
Message 7 of 8 (340 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

11-07-2012 01:10 AM in reply to: Balaji_Ram

Hi Balaji!
I know that your busy in Autodesk developer day.

 

whether this code run successfull in your system. In my system error occured.:smileysad:

i attached below.

With Regards,
GVaradarajan
ADN Support Specialist
Balaji_Ram
Posts: 749
Registered: ‎03-21-2011
Message 8 of 8 (334 Views)

Re: How to create objIds collectns of specified xref layer entity into new drawi

11-07-2012 03:19 AM in reply to: varadan01

Hi Varadarajan,

 

Here is a blog post that should help :

http://through-the-interface.typepad.com/through_the_interface/2009/05/importing-autocad-layers-from...

 

Also try this sample code which I have modified based on the code that you shared :

 

[CommandMethod("FXRef")]
public void FilterLayerEntities()
{
    Document document = Application.DocumentManager.MdiActiveDocument;
    Editor ed = document.Editor;
    Database destDb = Application.DocumentManager.MdiActiveDocument.Database;

    using (Database srcDb = new Database(false, false))
    {
        ObjectIdCollection idsCollecton = new ObjectIdCollection();

        srcDb.ReadDwgFile(@"C:\Temp\Test1.dwg", FileOpenMode.OpenForReadAndWriteNoShare, false, "");
        srcDb.ResolveXrefs(true, false);

        using (Transaction tr = srcDb.TransactionManager.StartTransaction())
        {
            BlockTable bt = tr.GetObject(srcDb.BlockTableId, OpenMode.ForRead, false) as BlockTable;
            foreach (ObjectId id in bt)
            {
                BlockTableRecord btr = tr.GetObject(id, OpenMode.ForWrite) as BlockTableRecord;
                String BlockName = btr.Name;
                if (btr.IsFromExternalReference && btr.IsResolved)
                {
                    idsCollecton.Clear();

                    //using (Database xrefDb = btr.GetXrefDatabase(false))
                    using (Database xrefDb = new Database(false, false))
                    {
                        xrefDb.ReadDwgFile(btr.GetXrefDatabase(false).Filename, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
                        xrefDb.ResolveXrefs(true, false);

                        using (Transaction tr1 = xrefDb.TransactionManager.StartTransaction())
                        {
                            BlockTableRecord xrefModelSpaceBTR = tr1.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(xrefDb), OpenMode.ForRead, false) as BlockTableRecord;
                            foreach (ObjectId entId in xrefModelSpaceBTR)
                            {
                                Entity solEntity = tr1.GetObject(entId, OpenMode.ForWrite) as Entity;
                                idsCollecton.Add(solEntity.ObjectId);
                            }
                            tr1.Commit();
                        }

                        IdMapping mapping = new IdMapping();
                        xrefDb.WblockCloneObjects(idsCollecton,
                                                SymbolUtilityServices.GetBlockModelSpaceId(destDb),
                                                mapping,
                                                DuplicateRecordCloning.Replace,
                                                false
                                                );
                    }
                }
            }
            tr.Commit();
        }
    }
}

 To try this :

 

1) Copy the attached drawings to c:\temp

2) Start AutoCAD 2012 / 2013

3) Netload the dll

4) run the "fxref" command

 

This command should wblockclone all the entities (with layer info) from Test2.dwg which is xrefed in Test1.dwg and add it to the current database.

 

 Hope this helps.



Balaji
Developer Technical Services
Autodesk Developer Network

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.