Hi all,
I am running below code to purge the layers from drawing by opening the file in ReadDwgFile method.
After running the code, when I open the file all the xref's layer settings is reloaded from the reference drawing.
I checked VISRETAIN variable and it is set to 1 only.
This is the steps I followed.
For me after running this command the xref layer settings are always changing.
Xref layer settings are restored to reference drawing and the VISRETAIN value is 1 only.
Also another issue is drawing preview is blank/nothing even I set retainthumbnail to True.
Side_dbase.RetainOriginalThumbnailBitmap = True
Here's the code
Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Runtime Public Class Class1 <CommandMethod("LAYER-PURGE-TEST")> _ Public Sub Layer_Purge() Dim f_opts As PromptOpenFileOptions = New PromptOpenFileOptions("Open") f_opts.Filter = "Drawing (*.dwg)|*.dwg" Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor Dim rslt As PromptFileNameResult = ed.GetFileNameForOpen(f_opts) If rslt.Status = PromptStatus.OK Then Dim Side_dbase As Database = New Database(False, False) Try Side_dbase.ReadDwgFile(rslt.StringResult, FileOpenMode.OpenForReadAndWriteNoShare, True, "") Side_dbase.RetainOriginalThumbnailBitmap = True Side_dbase.CloseInput(True) Purge_Layers(Side_dbase) Side_dbase.SaveAs(rslt.StringResult, False, DwgVersion.Current, Side_dbase.SecurityParameters) Side_dbase.Dispose() Catch ex As Exception End Try End If ed.WriteMessage(vbCrLf + " Purge Finished") End Sub 'This is the function using to Purge the Layers.
'---------------------------------------------------------------------------------------------------- Public Shared Function Purge_Layers(ByVal db As Database) As String Dim count As String = "0" Dim tm1 As Autodesk.AutoCAD.DatabaseServices.TransactionManager = db.TransactionManager Dim prmtr As ProgressMeter = New ProgressMeter Using TR3 As Transaction = tm1.StartTransaction Dim Id_to_Purge = New ObjectIdCollection() Dim Layer_Table As LayerTable = TR3.GetObject(db.LayerTableId, OpenMode.ForRead) For Each obid As ObjectId In Layer_Table If obid.IsValid Then Id_to_Purge.Add(obid) End If Next db.Purge(Id_to_Purge) count = Id_to_Purge.Count.ToString prmtr.Start("Deleting Layers : ") prmtr.SetLimit(Id_to_Purge.Count) For Each obid_del As ObjectId In Id_to_Purge Dim obj As DBObject = TR3.GetObject(obid_del, OpenMode.ForWrite) obj.Erase() prmtr.MeterProgress() Next prmtr.Stop() TR3.Commit() End Using Return count End Function End Class
Hi Ajilal,
Thanks for letting us know about the behaviour. I could reproduce it using the files that you provided.
I am working on it and will update you. As explained in the documentation the purge should not be modifiying the database in any way.
I have seen previous reports such as these when the purge did modify the database when using side databases but those were not in recent versions of AutoCAD. The workaround was to save the state that was being modified and set them back after the purge method call.
I am doing some more tests on this behavior and will keep you updated.
Regards,
Balaji
Hi Balaji,
Thank you so much for looking at this behaviour.
To support my first post, this test I tried on both 2012 and 2014 version and this behaviour still exists.
Balaji,
Just want to inform you that one workaround that I am using right now is checking Not lay.IsDependent on layers before calling obj.erase().
For Each obid_del As ObjectId In Id_to_Purge Dim obj As DBObject = TR3.GetObject(obid_del, OpenMode.ForWrite) Dim lay As LayerTableRecord = TryCast(obj, LayerTableRecord)
ed.WriteMessage(vbCrLf + lay.Name) If Not lay.IsDependent Then obj.Erase() End If prmtr.MeterProgress() Next
ed.WriteMessage(vbCrLf + lay.Name) displays that these layers are avaialble to purge.
Hi Ajilal, I think my original problem was similar to yours. I had Xref layers turning off after the purging even though VISRETAIN was set. I though it may have been related to:
undefinedLayerStatePolicy
// changed from 0 to 1
// think this is problem, xref layers think they are new so are restored off
My workaround was to save a LayerState, do the work, and then restore LayerState.
http://forums.autodesk.com/t5/net/layer-state-save-amp-set-error/m-p/5255379/highlight/false#M42100
Hope this helps,
Dale (upstairs)
Dale,
Thanks for the suggestion.
Like I mentioned in my last post, adding a 'If Not lay.IsDependent' check seems to be an another workaround.
Because while using the side database, db.Purge collecting the objectid's of all the xref layers are available to purge.
So without checking whether the layers are dependant, the code will delete the xref layers and later when you open the drawing the xref layers are restored from its reference drawing.
But I wonder how db.Purge can collect the xref layers objectid ?
Edit:-
Also the app which I published on Appstore is using the above code to purge the layers.
So the app will be unpublish soon to avoid unexpeceted result to the users.
Hi
It seems the purge is identifying those layers as purgeable since it is not directly being referenced by any entity in the modelspace.
For example, when we have an xref A.dwg in main.dwg, the Xref layers A|Layer1, A|Layer2 are only referenced by entities inside the BlockTableRecord named A. The modelspace only has a block reference to A.
Even the following method, identifies those layers as purgeable because they arent used.
Dim Layer_Table As LayerTable = TR.GetObject(db.LayerTableId, OpenMode.ForRead) Layer_Table.GenerateUsageData() For Each obid As ObjectId In Layer_Table Dim ltr As LayerTableRecord = TR.GetObject(obid, OpenMode.ForRead) If ltr.IsUsed = False Then End If Next
I would suggest iterating the entities in other block table records to see if any of those entities are referencing the layers.
Only layers that aren't used can be added for the purge test.
Regards,
Balaji
Just wanted to add to my previous reply.
I do not think this is the right behavior. So, I will log this behavior with our engineering team for them to analyze it.
When we have a regular block whose entities reference the layers, the layers are not identified as purgeable - As we would expect.
But in case of a block table record that is generated for Xref, when the entities in that BTR reference the layers, the layers are identified as not used and purgeable, which should not be case, I think.
Regards,
Balaji
Thanks Balaji,
Also did you check this behaviour with 2015 series ?
I dont have 2015 to check this.
So I will use 'If Not lay.IsDependent' check on layer before erasing the layer, as this seems to be working.
Yes, all my tests were in AutoCAD 2015.
Regards,
Balaji
If only entities in the xref are referencing the layer, and the xref is not currently resolved in the host drawing, then the behavior being described is correct because there are no objects in the host drawing that reference the layer.
If the xrefs are resolved in the host database before checking, then the layers should not be considered purgeable.