.NET

Reply
Contributor
jfboyer
Posts: 22
Registered: ‎02-27-2007
Message 1 of 5 (1,055 Views)

DeepCloneObjects between two databases

1055 Views, 4 Replies
06-11-2009 08:29 AM
The command is 5rep:

docA is the target database, it is where 5rep is entered
docB is the source database, and it's opened by 5rep

5rep is meant to copy objects from docB to docA
It requires a complex selection filter, that's why I need to open docB to get an Editor.

The following simplified code works when deep cloning objects within the same database, i.e docB
It fails when deep cloning objects from docB to docA (see commented portion)

Thanks for any help

Jf

{code}
[CommandMethod("5REP", CommandFlags.Session)]
public void SynchREP()
{
DocumentCollection docs = Application.DocumentManager;

Document docA = docs.MdiActiveDocument;
Database dbA = docA.Database;

Document docB = docs.Open("docB.dwg");
Database dbB = docB.Database;

DocumentLock dlockA = docA.LockDocument();
Transaction trA = dbA.TransactionManager.StartTransaction();
using (trA)
{
BlockTable btA = (BlockTable)trA.GetObject(
dbA.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord msA = (BlockTableRecord)trA.GetObject(
btA[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);

DocumentLock dlockB = docB.LockDocument();
Transaction trB = dbB.TransactionManager.StartTransaction();
using (trB)
{
BlockTable btB = (BlockTable)trB.GetObject(
dbB.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord msB = (BlockTableRecord)trB.GetObject(
btB[BlockTableRecord.ModelSpace],
OpenMode.ForRead
);

Editor edB = docB.Editor;
TypedValue[] tvsB = new TypedValue[]
{
new TypedValue( 67, "0" ),
new TypedValue( (int)DxfCode.Start, "INSERT" )
};
SelectionFilter sfB = new SelectionFilter(tvsB);
PromptSelectionResult psrB = edB.SelectAll(sfB);
SelectionSet ssetB = psrB.Value;
ObjectId[] ena = ssetB.GetObjectIds();
ObjectIdCollection oicB = new ObjectIdCollection(ena);

dbB.DeepCloneObjects(
oicB,
msB.Id, /* <-- targets the same database */
new IdMapping(), /* ...and it works */
false);

/*
dbB.DeepCloneObjects(
oicB,
msA.Id, <-- targets another database
new IdMapping(), ...and fails
false);

It raises an exception:
Autodesk.AutoCAD.Runtime.Exception: eWrongDatabase
in Autodesk.AutoCAD.DatabaseServices.Database.DeepCloneObjects */

trB.Commit();
}
trB.Dispose();
dlockB.Dispose();
}
trA.Dispose();
dlockA.Dispose();
}
{code}
*Art Cooney
Message 2 of 5 (1,054 Views)

Re: DeepCloneObjects between two databases

06-11-2009 10:37 AM in reply to: jfboyer

DeepClone (and deepCloneObjects) is only for
within the same database.  For cloning between databases, you must use the
wblockClone mechanism (in your case the wblockCloneObjects()
function).


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
The
command is 5rep: docA is the target database, it is where 5rep is entered docB
is the source database, and it's opened by 5rep 5rep is meant to copy objects
from docB to docA It requires a complex selection filter, that's why I need to
open docB to get an Editor. The following simplified code works when deep
cloning objects within the same database, i.e docB It fails when deep cloning
objects from docB to docA (see commented portion) Thanks for any help Jf
{code} [CommandMethod("5REP", CommandFlags.Session)] public void SynchREP() {
DocumentCollection docs = Application.DocumentManager; Document docA =
docs.MdiActiveDocument; Database dbA = docA.Database; Document docB =
docs.Open("docB.dwg"); Database dbB = docB.Database; DocumentLock dlockA =
docA.LockDocument(); Transaction trA =
dbA.TransactionManager.StartTransaction(); using (trA) { BlockTable btA =
(BlockTable)trA.GetObject( dbA.BlockTableId, OpenMode.ForRead );
BlockTableRecord msA = (BlockTableRecord)trA.GetObject(
btA[BlockTableRecord.ModelSpace], OpenMode.ForWrite ); DocumentLock dlockB =
docB.LockDocument(); Transaction trB =
dbB.TransactionManager.StartTransaction(); using (trB) { BlockTable btB =
(BlockTable)trB.GetObject( dbB.BlockTableId, OpenMode.ForRead );
BlockTableRecord msB = (BlockTableRecord)trB.GetObject(
btB[BlockTableRecord.ModelSpace], OpenMode.ForRead ); Editor edB =
docB.Editor; TypedValue[] tvsB = new TypedValue[] { new TypedValue( 67, "0" ),
new TypedValue( (int)DxfCode.Start, "INSERT" ) }; SelectionFilter sfB = new
SelectionFilter(tvsB); PromptSelectionResult psrB = edB.SelectAll(sfB);
SelectionSet ssetB = psrB.Value; ObjectId[] ena = ssetB.GetObjectIds();
ObjectIdCollection oicB = new ObjectIdCollection(ena); dbB.DeepCloneObjects(
oicB, msB.Id, /* <-- targets the same database */ new IdMapping(), /*
...and it works */ false); /* dbB.DeepCloneObjects( oicB, msA.Id, <--
targets another database new IdMapping(), ...and fails false); It raises an
exception: Autodesk.AutoCAD.Runtime.Exception: eWrongDatabase in
Autodesk.AutoCAD.DatabaseServices.Database.DeepCloneObjects */ trB.Commit(); }
trB.Dispose(); dlockB.Dispose(); } trA.Dispose(); dlockA.Dispose(); }
{code}
Contributor
jfboyer
Posts: 22
Registered: ‎02-27-2007
Message 3 of 5 (1,054 Views)

Re: DeepCloneObjects between two databases

06-12-2009 01:52 AM in reply to: jfboyer
Thank you Art, it works:

{code}
dbB.WblockCloneObjects(
oicB,
msA.Id,
new IdMapping(),
DuplicateRecordCloning.Replace,
false);
{code}

AutoCAD NET C# copy from a drawing to another: use WblockClone

*edit*: the clone objects don't show up immediately in the target drawing window, although they are actually copied. I'm looking into QueueForGraphicsFlush to update the screen, not sure yet if this is the right way to do it.

Jf Edited by: jfboyer on Jun 12, 2009 12:54 PM
Active Contributor
varadan01
Posts: 47
Registered: ‎03-16-2012
Message 4 of 5 (567 Views)

Re: DeepCloneObjects between two databases

10-12-2012 06:35 AM in reply to: jfboyer


                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);
                strPathName = pathName + "\\Temp\\" + strFileName;                           
            }

}

 

 

 

here i take the objectid collection as xref filter by its layer name.i tried to clone the object in new dwg its shows eWrongdatabase.

 

With Regards,
GVaradarajan
Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 5 of 5 (550 Views)

Re: DeepCloneObjects between two databases

10-12-2012 11:16 AM in reply to: jfboyer

If the document you are deep-cloning the objects into is not the Active document the graphics will not be correctly generated.

 

You can either make the destination document active, or don't open it in the editor (use Database.ReadDwgFile() to open it).

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.