.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ReadDwgFile for layer purge restore Xref layer settings

11 REPLIES 11
Reply
Message 1 of 12
Ajilal.Vijayan
820 Views, 11 Replies

ReadDwgFile for layer purge restore Xref layer settings

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.

  1. From the attached zip file open Master.dwg.
  2. There is an xref called Xref.dwg attached to Master.dwg
  3. Change the Xref layer color in the Master.dwg.
  4. Save and close the Master.dwg
  5. From any other drawing run the command LAYER-PURGE-TEST and select Master.dwg to purge.
  6. Open Master.dwg to check whether the xref layer color has changed.

 

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

 

 

11 REPLIES 11
Message 2 of 12
Balaji_Ram
in reply to: Ajilal.Vijayan

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

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 3 of 12
Ajilal.Vijayan
in reply to: Balaji_Ram

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.

 

Message 4 of 12

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.

Capture.JPG

 

Message 5 of 12

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)

 

 




______________
Yes, I'm Satoshi.
Message 6 of 12

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.

 

Message 7 of 12
Balaji_Ram
in reply to: Ajilal.Vijayan

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

 



Balaji
Developer Technical Services
Autodesk Developer Network

Message 8 of 12
Balaji_Ram
in reply to: Ajilal.Vijayan

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



Balaji
Developer Technical Services
Autodesk Developer Network

Message 9 of 12
Ajilal.Vijayan
in reply to: Balaji_Ram

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.

Message 10 of 12
Balaji_Ram
in reply to: Ajilal.Vijayan

Yes, all my tests were in AutoCAD 2015.

 

Regards,

Balaji



Balaji
Developer Technical Services
Autodesk Developer Network

Message 11 of 12
artc2
in reply to: Balaji_Ram

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.

Message 12 of 12
Ajilal.Vijayan
in reply to: artc2

Hi artc2,

 

Yes, the xrefs are resolved in the host database.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost