.NET

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

DeepCloneObjects between two databases

960 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 (959 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 (959 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 (472 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 (455 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).

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community