Message 1 of 7
Updating blocks in open non-current drawing
Not applicable
05-05-2010
02:08 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm having two issues. The blocks get updated with the new definitions, but the new versions of the blocks are not being represented ( a regen fixes the problem ), and the new attributes are not showing in the correct location ( a move fixes the problem ).
I thought that if you made the database the working database then the attributes would be updated correctly? This does not seem to be the case when a drawing is opened but not current. How can I fix this?
I have used the draw method on the block references, and they update nicely in the current open drawing, but not in a non-current drawing. I have tried to use the QueueForGraphicsFlush method of the TransactionManager, but that doesn't work unless it is the current document, at least that was the error I got. I tried the Regen method of the Editor, but that only regened the current document. Does anyone have any other suggestions?
Its for Acad '09, and .Net 2.0
Let me know if I didn't provide enough information. Thanks in advance.
{code}
public void Main () {
DocumentCollection DocCol = AcadApp.DocumentManager;
Document Doc = DocCol.MdiActiveDocument;
Database cDb = Doc.Database;
Editor Ed = Doc.Editor;
using ( DocumentLock DocLock = Doc.LockDocument() ) {
using ( CopyBlockDefinitions Dia = new CopyBlockDefinitions() ) {
if ( AcadApp.ShowModalDialog( Dia ) != DialogResult.OK ) return;
foreach ( KeyValuePair> kvp in FinalMappingDict ) {
Database reDb;
Document reOpenDoc = null;
DocumentLock reDocLock = null;
if ( kvp.Value.Count == 0 ) continue;
reOpenDoc = MyUtility.GetDocumentFrom( DocCol, kvp.Key );
if ( reOpenDoc == null ) {
reDb = new Database( false, true );
reDb.ReadDwgFile( kvp.Key, FileShare.ReadWrite, true, null );
}
else {
reDocLock = reOpenDoc.LockDocument();
reDb = reOpenDoc.Database;
}
HostApplicationServices.WorkingDatabase = reDb;
using ( Transaction reTrans = reDb.TransactionManager.StartTransaction() ) {
foreach ( RedefiningBlock rb in kvp.Value ) {
Database deDb;
Document deOpenDoc = null;
DocumentLock deDocLock = null;
ObjectId reObjId = MyUtility.GetNonErasedTableRecordId( reDb.BlockTableId, rb.Name );
if ( reObjId.IsNull ) continue;
deOpenDoc = MyUtility.GetDocumentFrom( DocCol, rb.RedefiningDrawingPath );
if ( deOpenDoc == null ) {
deDb = new Database( false, true );
deDb.ReadDwgFile( rb.RedefiningDrawingPath, FileShare.ReadWrite, true, null );
}
else {
deDocLock = deOpenDoc.LockDocument();
deDb = deOpenDoc.Database;
}
ObjectId deObjId = MyUtility.GetNonErasedTableRecordId( deDb.BlockTableId, rb.RedefiningName );
if ( deObjId.IsNull ) continue;
BlockTableRecord reBlkTblRec = reTrans.GetObject( reObjId, OpenMode.ForWrite ) as BlockTableRecord;
foreach ( ObjectId id in reBlkTblRec ) {
if ( id.IsErased ) continue;
reTrans.GetObject( id, OpenMode.ForWrite ).Erase();
}
using ( Transaction deTrans = deDb.TransactionManager.StartTransaction() ) {
ObjectIdCollection ObjIdCol = new ObjectIdCollection();
BlockTableRecord deBlkTblRec = deTrans.GetObject( deObjId, OpenMode.ForRead ) as BlockTableRecord;
foreach ( ObjectId id in deBlkTblRec ) {
if ( id.IsErased ) continue;
ObjIdCol.Add( id );
}
deDb.WblockCloneObjects( ObjIdCol, reBlkTblRec.ObjectId, new IdMapping(), DuplicateRecordCloning.Ignore, false );
}
reBlkTblRec.DowngradeOpen();
if ( deOpenDoc == null )
deDb.Dispose();
else
deDocLock.Dispose();
MapAttributes( reBlkTblRec.ObjectId, rb.AttributeMapping );
}
reTrans.Commit();
}
HostApplicationServices.WorkingDatabase = cDb;
if ( reOpenDoc == null ) {
reDb.RetainOriginalThumbnailBitmap = true;
reDb.SaveAs( kvp.Key, DwgVersion.Current );
Ed.WriteMessage( "{0} Saved file: {1}", System.Environment.NewLine, reDb.Filename );
reDb.Dispose();
}
else
reDocLock.Dispose();
}
}
}
}
{code}
{code}
void MapAttributes ( ObjectId id, Dictionary mappingDict )
{
using ( Transaction Trans = id.Database.TransactionManager.StartTransaction() ) {
BlockTableRecord BlkTblRec = Trans.GetObject( id, OpenMode.ForRead ) as BlockTableRecord;
foreach ( ObjectId objId in BlkTblRec.GetBlockReferenceIds( true, true ) ) {
if ( objId.IsErased ) continue;
Dictionary Dict = new Dictionary();
BlockReference BlkRef = Trans.GetObject( objId, OpenMode.ForWrite ) as BlockReference;
foreach ( ObjectId attId in BlkRef.AttributeCollection as AttributeCollection ) {
if ( attId.IsErased ) continue;
AttributeReference AttRef = Trans.GetObject( attId, OpenMode.ForWrite ) as AttributeReference;
if ( mappingDict.ContainsKey( AttRef.Tag ) )
Dict.Add( mappingDict[ AttRef.Tag ], AttRef.TextString );
AttRef.Erase();
}
if ( BlkTblRec.HasAttributeDefinitions ) {
foreach ( ObjectId attId in BlkTblRec ) {
if ( attId.IsErased ) continue;
AttributeDefinition AttDef = Trans.GetObject( attId, OpenMode.ForRead ) as AttributeDefinition;
if ( AttDef != null ) {
AttributeReference AttRef = new AttributeReference();
AttRef.SetPropertiesFrom( AttDef );
AttRef.SetAttributeFromBlock( AttDef, BlkRef.BlockTransform );
BlkRef.AttributeCollection.AppendAttribute( AttRef );
if ( Dict.ContainsKey( AttRef.Tag ) )
AttRef.TextString = Dict[ AttRef.Tag ];
Trans.AddNewlyCreatedDBObject( AttRef, true );
}
}
}
BlkRef.DowngradeOpen();
BlkRef.Draw();
}
Trans.Commit();
}
}
{code}
I thought that if you made the database the working database then the attributes would be updated correctly? This does not seem to be the case when a drawing is opened but not current. How can I fix this?
I have used the draw method on the block references, and they update nicely in the current open drawing, but not in a non-current drawing. I have tried to use the QueueForGraphicsFlush method of the TransactionManager, but that doesn't work unless it is the current document, at least that was the error I got. I tried the Regen method of the Editor, but that only regened the current document. Does anyone have any other suggestions?
Its for Acad '09, and .Net 2.0
Let me know if I didn't provide enough information. Thanks in advance.
{code}
public void Main () {
DocumentCollection DocCol = AcadApp.DocumentManager;
Document Doc = DocCol.MdiActiveDocument;
Database cDb = Doc.Database;
Editor Ed = Doc.Editor;
using ( DocumentLock DocLock = Doc.LockDocument() ) {
using ( CopyBlockDefinitions Dia = new CopyBlockDefinitions() ) {
if ( AcadApp.ShowModalDialog( Dia ) != DialogResult.OK ) return;
foreach ( KeyValuePair
Database reDb;
Document reOpenDoc = null;
DocumentLock reDocLock = null;
if ( kvp.Value.Count == 0 ) continue;
reOpenDoc = MyUtility.GetDocumentFrom( DocCol, kvp.Key );
if ( reOpenDoc == null ) {
reDb = new Database( false, true );
reDb.ReadDwgFile( kvp.Key, FileShare.ReadWrite, true, null );
}
else {
reDocLock = reOpenDoc.LockDocument();
reDb = reOpenDoc.Database;
}
HostApplicationServices.WorkingDatabase = reDb;
using ( Transaction reTrans = reDb.TransactionManager.StartTransaction() ) {
foreach ( RedefiningBlock rb in kvp.Value ) {
Database deDb;
Document deOpenDoc = null;
DocumentLock deDocLock = null;
ObjectId reObjId = MyUtility.GetNonErasedTableRecordId( reDb.BlockTableId, rb.Name );
if ( reObjId.IsNull ) continue;
deOpenDoc = MyUtility.GetDocumentFrom( DocCol, rb.RedefiningDrawingPath );
if ( deOpenDoc == null ) {
deDb = new Database( false, true );
deDb.ReadDwgFile( rb.RedefiningDrawingPath, FileShare.ReadWrite, true, null );
}
else {
deDocLock = deOpenDoc.LockDocument();
deDb = deOpenDoc.Database;
}
ObjectId deObjId = MyUtility.GetNonErasedTableRecordId( deDb.BlockTableId, rb.RedefiningName );
if ( deObjId.IsNull ) continue;
BlockTableRecord reBlkTblRec = reTrans.GetObject( reObjId, OpenMode.ForWrite ) as BlockTableRecord;
foreach ( ObjectId id in reBlkTblRec ) {
if ( id.IsErased ) continue;
reTrans.GetObject( id, OpenMode.ForWrite ).Erase();
}
using ( Transaction deTrans = deDb.TransactionManager.StartTransaction() ) {
ObjectIdCollection ObjIdCol = new ObjectIdCollection();
BlockTableRecord deBlkTblRec = deTrans.GetObject( deObjId, OpenMode.ForRead ) as BlockTableRecord;
foreach ( ObjectId id in deBlkTblRec ) {
if ( id.IsErased ) continue;
ObjIdCol.Add( id );
}
deDb.WblockCloneObjects( ObjIdCol, reBlkTblRec.ObjectId, new IdMapping(), DuplicateRecordCloning.Ignore, false );
}
reBlkTblRec.DowngradeOpen();
if ( deOpenDoc == null )
deDb.Dispose();
else
deDocLock.Dispose();
MapAttributes( reBlkTblRec.ObjectId, rb.AttributeMapping );
}
reTrans.Commit();
}
HostApplicationServices.WorkingDatabase = cDb;
if ( reOpenDoc == null ) {
reDb.RetainOriginalThumbnailBitmap = true;
reDb.SaveAs( kvp.Key, DwgVersion.Current );
Ed.WriteMessage( "{0} Saved file: {1}", System.Environment.NewLine, reDb.Filename );
reDb.Dispose();
}
else
reDocLock.Dispose();
}
}
}
}
{code}
{code}
void MapAttributes ( ObjectId id, Dictionary
{
using ( Transaction Trans = id.Database.TransactionManager.StartTransaction() ) {
BlockTableRecord BlkTblRec = Trans.GetObject( id, OpenMode.ForRead ) as BlockTableRecord;
foreach ( ObjectId objId in BlkTblRec.GetBlockReferenceIds( true, true ) ) {
if ( objId.IsErased ) continue;
Dictionary
BlockReference BlkRef = Trans.GetObject( objId, OpenMode.ForWrite ) as BlockReference;
foreach ( ObjectId attId in BlkRef.AttributeCollection as AttributeCollection ) {
if ( attId.IsErased ) continue;
AttributeReference AttRef = Trans.GetObject( attId, OpenMode.ForWrite ) as AttributeReference;
if ( mappingDict.ContainsKey( AttRef.Tag ) )
Dict.Add( mappingDict[ AttRef.Tag ], AttRef.TextString );
AttRef.Erase();
}
if ( BlkTblRec.HasAttributeDefinitions ) {
foreach ( ObjectId attId in BlkTblRec ) {
if ( attId.IsErased ) continue;
AttributeDefinition AttDef = Trans.GetObject( attId, OpenMode.ForRead ) as AttributeDefinition;
if ( AttDef != null ) {
AttributeReference AttRef = new AttributeReference();
AttRef.SetPropertiesFrom( AttDef );
AttRef.SetAttributeFromBlock( AttDef, BlkRef.BlockTransform );
BlkRef.AttributeCollection.AppendAttribute( AttRef );
if ( Dict.ContainsKey( AttRef.Tag ) )
AttRef.TextString = Dict[ AttRef.Tag ];
Trans.AddNewlyCreatedDBObject( AttRef, true );
}
}
}
BlkRef.DowngradeOpen();
BlkRef.Draw();
}
Trans.Commit();
}
}
{code}