.NET

Reply
Valued Mentor
fieldguy
Posts: 372
Registered: ‎03-31-2005
Message 1 of 7 (2,171 Views)
Accepted Solution

Purge Linetypes

2171 Views, 6 Replies
01-31-2011 08:05 AM

How can I purge linetypes?  We get data from outside sources and my goal is to load our linetypes.  I have a list of layers and store the previous layer linetypes.  I reset them all to "Continuous".  Now I have to purge the old linetype definitions but I can't make them go away.  I need to purge DASHED and HIDDEN so far.  If I open the file and click on the linetype in layer manager, I still see the old DASHED and HIDDEN definitions.  I have tried db.purge(linetypeobjectid) but they don't go away.

 

Do I need to go through the symboltablerecord to find the correct linetypetablerecord and remove it?  Will that remove the linetype from the list shown in layer manager?  That is what I need to do - make sure DASHED and HIDDEN *have* to be re-loaded from our linetypes.

Database.Purge() is a bit of a misnomer, in my opinion.  That function doesn't purge items, it just tells you whether or not they are safe to erase -- you do have to erase them yourself.  You can erase them without using Database.Purge(), but you can easily corrupt your drawing that way.

 

Something like the following should do the trick.  Note that it doesn't guarantee that linetypes other than continuous are unreferenced; your drawings could have entities that reference those linetypes directly.  You may want to script a call to the 'setbylayer' command prior to running your purge command, or scan all the BlockTableRecords yourself, or rename any linetypes that remain after calling your purge command, or otherwise deal with that possibility.

 

 

[CommandMethod("purgelts")]
public void purgelinetypes()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
ObjectIdCollection ltypeIds = new ObjectIdCollection();
using (Transaction t = db.TransactionManager.StartTransaction())
{
LinetypeTable ltt = t.GetObject(db.LinetypeTableId, OpenMode.ForRead)
as LinetypeTable;
foreach (ObjectId ltypeId in ltt)
{
if (ltypeId == SymbolUtilityServices.GetLinetypeByBlockId(db)) continue;
if (ltypeId == SymbolUtilityServices.GetLinetypeByLayerId(db)) continue;
if (ltypeId == SymbolUtilityServices.GetLinetypeContinuousId(db)) continue;
ltypeIds.Add(ltypeId);
}
LayerTable lt = t.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
foreach (ObjectId ltrId in lt)
{
if (ltrId.IsErased) continue;
LayerTableRecord ltr = t.GetObject(ltrId, OpenMode.ForWrite) as LayerTableRecord;
ltr.LinetypeObjectId = db.ContinuousLinetype;
}
t.Commit();
}
ed.WriteMessage("Checking whether {0} linetypes can be purged.\n", ltypeIds.Count);
db.Purge(ltypeIds);
ed.WriteMessage("{0} linetypes can be purged.\n", ltypeIds.Count);
using (Transaction t = db.TransactionManager.StartTransaction())
{
foreach (ObjectId ltypeId in ltypeIds)
{
DBObject ltype = t.GetObject(ltypeId, OpenMode.ForWrite);
ltype.Erase();
}
t.Commit();
}
db.ReclaimMemoryFromErasedObjects(ltypeIds);
}

 

 

Active Contributor
dan.glassman
Posts: 43
Registered: ‎09-23-2008
Message 2 of 7 (2,161 Views)

Re: Purge Linetypes

01-31-2011 09:17 AM in reply to: fieldguy

Database.Purge() is a bit of a misnomer, in my opinion.  That function doesn't purge items, it just tells you whether or not they are safe to erase -- you do have to erase them yourself.  You can erase them without using Database.Purge(), but you can easily corrupt your drawing that way.

 

Something like the following should do the trick.  Note that it doesn't guarantee that linetypes other than continuous are unreferenced; your drawings could have entities that reference those linetypes directly.  You may want to script a call to the 'setbylayer' command prior to running your purge command, or scan all the BlockTableRecords yourself, or rename any linetypes that remain after calling your purge command, or otherwise deal with that possibility.

 

 

[CommandMethod("purgelts")]
public void purgelinetypes()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;
    Database db = doc.Database;

    ObjectIdCollection ltypeIds = new ObjectIdCollection();
    using (Transaction t = db.TransactionManager.StartTransaction())
    {
        LinetypeTable ltt = t.GetObject(db.LinetypeTableId, OpenMode.ForRead)
            as LinetypeTable;
        foreach (ObjectId ltypeId in ltt)
        {
            if (ltypeId == SymbolUtilityServices.GetLinetypeByBlockId(db)) continue;
            if (ltypeId == SymbolUtilityServices.GetLinetypeByLayerId(db)) continue;
            if (ltypeId == SymbolUtilityServices.GetLinetypeContinuousId(db)) continue;
            ltypeIds.Add(ltypeId);
        }
            

        LayerTable lt = t.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
        foreach (ObjectId ltrId in lt)
        { 
            if (ltrId.IsErased) continue;
            LayerTableRecord ltr = t.GetObject(ltrId, OpenMode.ForWrite) as LayerTableRecord;
            ltr.LinetypeObjectId = db.ContinuousLinetype;
        }
        t.Commit();
    }

    ed.WriteMessage("Checking whether {0} linetypes can be purged.\n", ltypeIds.Count);
    db.Purge(ltypeIds);
    ed.WriteMessage("{0} linetypes can be purged.\n", ltypeIds.Count);

    using (Transaction t = db.TransactionManager.StartTransaction())
    {
        foreach (ObjectId ltypeId in ltypeIds)
        {
            DBObject ltype = t.GetObject(ltypeId, OpenMode.ForWrite);
            ltype.Erase();
        }
        t.Commit();
    }
    db.ReclaimMemoryFromErasedObjects(ltypeIds);
}

 

 

Valued Mentor
fieldguy
Posts: 372
Registered: ‎03-31-2005
Message 3 of 7 (2,108 Views)

Re: Purge Linetypes

02-01-2011 06:20 PM in reply to: dan.glassman

Thank you very much.  That was educational. 

 

Below is a manual vb conversion.  It does not include the layertable section.  

 

<CommandMethod("purgelts")> _
    Public Sub purgelinetypes()
        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim db As Database = doc.Database
        Dim ltypeids As New ObjectIdCollection
        Using t As Transaction = db.TransactionManager.StartTransaction()
            Dim ltt As LinetypeTable = CType(t.GetObject(db.LinetypeTableId, OpenMode.ForRead), LinetypeTable)
            For Each ltypeid As ObjectId In ltt
                If ltypeid = SymbolUtilityServices.GetLinetypeByBlockId(db) Then
                    Continue For
                End If
                If ltypeid = SymbolUtilityServices.GetLinetypeByLayerId(db) Then
                    Continue For
                End If
                If ltypeid = SymbolUtilityServices.GetLinetypeContinuousId(db) Then
                    Continue For
                End If
                ltypeids.Add(ltypeid)
            Next
            t.Commit()
        End Using
        ed.WriteMessage("Checking whether {0} linetypes can be purged " & vbCrLf, ltypeids.Count)
        db.Purge(ltypeids)
        ed.WriteMessage("{0} linetypes can be purged " & vbCrLf, ltypeids.Count)
        Using t As Transaction = db.TransactionManager.StartTransaction
            For Each ltypeid As ObjectId In ltypeids
                Dim ltype As LinetypeTableRecord = CType(t.GetObject(ltypeid, OpenMode.ForWrite), LinetypeTableRecord)
                ltype.Erase()
            Next
            t.Commit()
        End Using
        db.ReclaimMemoryFromErasedObjects(ltypeids)
    End Sub

 

Active Contributor
dan.glassman
Posts: 43
Registered: ‎09-23-2008
Message 4 of 7 (2,105 Views)

Re: Purge Linetypes

02-01-2011 07:01 PM in reply to: fieldguy

I'm glad that helped.  Two things about my code are making me cringe, though -- there's no need to check each linetype to see if it's ByBlock, ByLayer, or Continuous -- one check at the end will do.  And the call to ReclaimMemoryFromErasedObjects -- I've removed it in this version because it isn't required to achieve the desired result and...I don't really understand it [sorry!].

 

Corrected:

 

 

<CommandMethod("purgelts")>
Public Sub purgelinetypes()
    Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
    Dim ed As Editor = doc.Editor
    Dim db As Database = doc.Database
    Dim ltypeids As New ObjectIdCollection
    Using t As Transaction = db.TransactionManager.StartTransaction()
        Dim ltt As LinetypeTable = t.GetObject(db.LinetypeTableId, OpenMode.ForRead)
        For Each ltypeid As ObjectId In ltt
            ltypeids.Add(ltypeid)
        Next
        t.Commit()
    End Using

    Dim ltypeContinuousId As ObjectId = SymbolUtilityServices.GetLinetypeContinuousId(db)
    Dim ltypeByLayerId As ObjectId = SymbolUtilityServices.GetLinetypeByLayerId(db)
    Dim ltypeByBlockId As ObjectId = SymbolUtilityServices.GetLinetypeByBlockId(db)

    If ltypeids.Contains(ltypeContinuousId) Then ltypeids.Remove(ltypeContinuousId)
    If ltypeids.Contains(ltypeByLayerId) Then ltypeids.Remove(ltypeByLayerId)
    If ltypeids.Contains(ltypeByBlockId) Then ltypeids.Remove(ltypeByBlockId)

    ed.WriteMessage("Checking whether {0} linetypes can be purged" & Environment.NewLine, ltypeids.Count)
    db.Purge(ltypeids)
    ed.WriteMessage("{0} linetypes can be purged" & Environment.NewLine, ltypeids.Count)
    Using t As Transaction = db.TransactionManager.StartTransaction
        For Each ltypeid As ObjectId In ltypeids
            Dim ltype As DBObject = t.GetObject(ltypeid, OpenMode.ForWrite)
            ltype.Erase()
        Next
        t.Commit()
    End Using        
End Sub

 

 

 

 

Valued Mentor
fieldguy
Posts: 372
Registered: ‎03-31-2005
Message 5 of 7 (2,090 Views)

Re: Purge Linetypes

02-02-2011 09:12 AM in reply to: dan.glassman

That was part of the education - the reclaim memory statement.  I found that in Keans blog.  It is good to know for future reference.  My process runs in a batch - open in the editor, modify, save and close a list of files.  That adds up to a manual "reclaim", so I am not using it either.  I have never used the "symbolutilityservices" namespace, so that is good to know as well.

 

Deleting the un-used and un-wanted linetype ids makes perfect sense, along with the db.purge to make sure the linetypes are not referenced in a dimension style or something.

New Member
craigkapitzke8875
Posts: 1
Registered: ‎09-09-2012
Message 6 of 7 (1,530 Views)

Re: Purge Linetypes

09-09-2012 04:27 PM in reply to: dan.glassman

Hey, just wondering if anyone knows what language " Public Sub purgelinetypes() " is written in. It has been years since I have done any ARX programming and need to know if it is J# or C so I can compile it. Thanks

Valued Mentor
fieldguy
Posts: 372
Registered: ‎03-31-2005
Message 7 of 7 (1,511 Views)

Re: Purge Linetypes

09-10-2012 07:53 AM in reply to: craigkapitzke8875

That is vb

 

vs_1.png

Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.