Author Topic: SwapIdWith unstability with currently open drawing  (Read 1724 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
SwapIdWith unstability with currently open drawing
« on: June 10, 2015, 11:34:26 PM »
I am writing a program to update blocks between two drawings.  One that will work with dynamic blocks, and it is progressing nicely except when the drawing to be updated is open within the AutoCAD session.  The block table record gets updated correctly, and the block references are updating also, meaning they show the correct geometry (no code yet for attributes).  And, if you try and insert a new block reference of the new block table record, it will crash aCAD.  If I do not erase the old block table record, then aCAD will not crash.

The issue: when the drawing is open the block references do not get re-referenced to the new block table record, meaning that if you use the method GetBlockReferenceIds it will return an empty collection, even though it looks like (and they do) reference the new block table record.  If you save and close the drawing and open it up again, the block references are referenced within the block table record.  I have not been able to find any type of solution within the help docs.

This program is just to keep my brain working over the summer, so I can post the code if it is needed.

Thanks in advance.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: SwapIdWith unstability with currently open drawing
« Reply #1 on: June 11, 2015, 04:14:15 PM »
I am writing a program to update blocks between two drawings.
I am guessing your using SwapIdWith, but you mentioned between two drawing and are blocks in the same database when they are swapped?

Quote
This function swaps objectIds and handles between the object specified by otherId and the object invoking this function. Both objects must currently be database-resident and must reside in the same database. If swapXdata == Adesk::kTrue, then the objects swap extended entity data as well. If swapExtDict == Adesk::kTrue, then the objects swap extension dictionaries also.

If the object specified by otherId or the object invoking this function are not database-resident, then Acad::eNoDatabase is returned. If both objects involved are not in the same database, then Acad::eWrongDatabase is returned.


T.Willey

  • Needs a day job
  • Posts: 5251
Re: SwapIdWith unstability with currently open drawing
« Reply #2 on: June 11, 2015, 04:22:52 PM »
I am writing a program to update blocks between two drawings.
I am guessing your using SwapIdWith, but you mentioned between two drawing and are blocks in the same database when they are swapped?

Yes.  I use db.Insert to insert the new block table record into the drawing ( only way I could find to transfer dynamic blocks with their properties ), and once the new record is within the drawing I call SwapIdWith between the old record and the new record.

I see their is a SwapReferences, which sounds like it might work, but it doesn't work for me in this instance.

Thanks.

Edit: Added code, as of this point.  If the sub-functions are need, I can add those also.
Code - C: [Select]
  1. public bool copyBlock ( Database aCallingDb, string aFromPath, string aFromName, string aToPath, string aToName ) {
  2.     Document fromDoc;
  3.     DocumentLock fromLock = null;
  4.     ObjectId fromId;
  5.    
  6.     Document toDoc;
  7.     DocumentLock toLock = null;
  8.     ObjectId toId;
  9.    
  10.     string tName = "a";
  11.     string oldName = "b";
  12.     ObjectId tId;
  13.     BlockTableRecord btr;
  14.    
  15.     Database fromDb = GetDatabaseAtPath( aFromPath, aCallingDb, FileShare.ReadWrite, FindFileHint.XRefDrawing, out fromDoc );
  16.     if ( fromDoc != null && fromDoc.LockMode() == DocumentLockMode.NotLocked ) fromLock = fromDoc.LockDocument();
  17.     fromId = GetNonErasedTableRecordId( fromDb.BlockTableId, aFromName );
  18.     if ( fromId.IsNull ) return false;
  19.    
  20.     Database toDb = GetDatabaseAtPath( aToPath, aCallingDb, FileShare.ReadWrite, FindFileHint.XRefDrawing, out toDoc );
  21.     if ( toDoc != null && toDoc.LockMode() == DocumentLockMode.NotLocked ) toLock = toDoc.LockDocument();
  22.     toId = GetNonErasedTableRecordId( toDb.BlockTableId, aToName );
  23.     if ( toId.IsNull ) return false;
  24.    
  25.     using ( Database tDb = new Database( true, true ) ) {
  26.         tDb.Insert( "randomAssTempNameYes3344882", fromDb, true );
  27.         if ( fromDoc == null ) fromDb.Dispose();
  28.         else if ( fromLock != null ) fromLock.Dispose();
  29.         eraseAllRecordsExcept( tDb.BlockTableId, aFromName );
  30.         while ( !( tId = GetNonErasedTableRecordId( toDb.BlockTableId, tName ) ).IsNull ) tName += tName;
  31.         while ( !( tId = GetNonErasedTableRecordId( toDb.BlockTableId, oldName ) ).IsNull ) oldName += oldName;
  32.         using ( Transaction toTrans = toDb.TransactionManager.StartTransaction() ) {
  33.             btr = toTrans.GetObject( toId, OpenMode.ForWrite, false, true ) as BlockTableRecord;
  34.             btr.Name = oldName;
  35.             btr.DowngradeOpen();
  36.             tId = toDb.Insert( tName, tDb, true );
  37.             if ( tId.IsNull ) return false;
  38.             btr = toTrans.GetObject( tId, OpenMode.ForWrite, false, true ) as BlockTableRecord;
  39.             btr.Erase();
  40.             btr.DowngradeOpen();
  41.             fromId = GetNonErasedTableRecordId( toDb.BlockTableId, aFromName );
  42.             if ( fromId.IsNull ) return false;
  43.             btr = toTrans.GetObject( fromId, OpenMode.ForWrite, false, true ) as BlockTableRecord;
  44.             btr.SwapIdWith( toId, false, false );
  45.             if ( string.Equals( btr.Name, aToName, StringComparison.OrdinalIgnoreCase ) ) {
  46.                 btr.Name = aToName;
  47.                 updateXData( btr.XData, 1001, "AcDbBynamicBlockTrueName", new TypedValue( 1000, aFromName ), new TypedValue( 1000, aToName ) );
  48.             }
  49.             btr.DowngradeOpen();
  50.             btr = toTrans.GetObject( fromId, OpenMode.ForWrite, false, true ) as BlockTableRecord;
  51.             btr.Erase();
  52.             btr.DowngradeOpen();
  53.             toTrans.Commit();
  54.             if ( toDoc == null ) toDb.SaveAs( aToPath, false, DwgVersion.Current, toDb.SecurityParameters );
  55.         }
  56.     }
  57.     if ( toDoc == null ) toDb.Dispose();
  58.     else if ( toLock != null ) toLock.Dispose();
  59.     return true;
  60. }
  61.  
« Last Edit: June 11, 2015, 04:39:11 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.