.NET

Reply
Distinguished Contributor
Dale.Bartlett
Posts: 173
Registered: ‎01-06-2003
Message 1 of 3 (175 Views)

VISRETAIN and Purge

175 Views, 2 Replies
03-17-2013 05:15 AM

I have a PurgeAll tool which appears to work well, however when used in batch mode the xref layer settings are lost. VISRETAIN remains correctly set. If I run the identical purge code on the current file (ie not using db.ReadDwgFile) then the layers are unaffected. I have tried save/restore LayerState before and after, but again the batch process mangles it, whereas on the current file it all behaves perfectly. This post seems to be closest to a similar problem: http://forums.autodesk.com/t5/NET/VISRETAIN-not-work-with-ReadDwgFile/m-p/3122828/highlight/true#M24... I have included trimmed code below. Many thanks for any thoughts. Dale

 

<code>

PROCESS:

purgeAllFiles>purgeAll>purgeDictionaries+purgeSymbolTables

 

CODE:

public static void purgeAllFiles(string pstrSourceFolderName, string pstrTargetFolderName, string pstrTargetFileNameSuffix)
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            string pathName = pstrSourceFolderName;

            string[] fileNames = FolderTools.getFilesInFolder(pstrSourceFolderName, "*.dwg", lsoFolderSearchOption);

            foreach (string lstrFileName in fileNames)
            {
                if (lstrFileName.EndsWith(".dwg", StringComparison.CurrentCultureIgnoreCase))
                {
                    string lstrFileNameOutput = FolderTools.getTargetFileNameFull(pstrTargetFolderName, lstrFileName, pstrTargetFileNameSuffix);

                    Database db = new Database(false, true);
                    try
                    {
                        db.ReadDwgFile(lstrFileName, FileOpenMode.OpenForReadAndWriteNoShare, true, "");
                        db.RetainOriginalThumbnailBitmap = true;

                        string lstrMessage = string.Empty;
                        using (Transaction tr = db.TransactionManager.StartTransaction())
                        {
                            // save Layer State "ATK_PurgeAll"
                            string lstrLayerStateName = "ATK_PurgeAll";
                            LayerStateTools.saveLayerStateAllProps(db, tr, lstrLayerStateName);

                            // this is recursive, no need for extra process
                           purgeAll(db, tr, true);

                            // restore Layer State "ATK_PurgeAll"
                            LayerStateTools.setLayerStateAllProps(db, tr, lstrLayerStateName);

                            tr.Commit();
                        }
                        db.SaveAs(lstrFileNameOutput, true, DwgVersion.Current, db.SecurityParameters);
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("\nProblem");
                    }
                }
            }
            ed.WriteMessage("\nSuccess");
        }

public static bool purgeAll(Database pdb, Transaction ptr, bool pblnSilent)
        {
            // tables
            ObjectIdCollection tableIds = new ObjectIdCollection();
            tableIds.Add(pdb.BlockTableId);
            tableIds.Add(pdb.DimStyleTableId);
            tableIds.Add(pdb.LayerTableId);
            tableIds.Add(pdb.LinetypeTableId);
            tableIds.Add(pdb.RegAppTableId);
            tableIds.Add(pdb.TextStyleTableId);
            tableIds.Add(pdb.UcsTableId);
            tableIds.Add(pdb.ViewportTableId);
            tableIds.Add(pdb.ViewTableId);

            // dictionaries
            ObjectIdCollection dictIds = new ObjectIdCollection();
            dictIds.Add(pdb.MaterialDictionaryId);
            dictIds.Add(pdb.MLStyleDictionaryId);
            dictIds.Add(pdb.MLeaderStyleDictionaryId);
            dictIds.Add(pdb.PlotStyleNameDictionaryId);
            dictIds.Add(pdb.TableStyleDictionaryId);
            dictIds.Add(pdb.VisualStyleDictionaryId);

            // recursive
            while (purgeSymbolTables(pdb, ptr, tableIds, pblnSilent) || purgeDictionaries(pdb, ptr, dictIds, pblnSilent))
                continue;
            return true;
        }

 

public static bool purgeSymbolTables(Database pdb, Transaction ptr, ObjectIdCollection pTableIds, bool pblnSilent)
        {
            bool itemsPurged = false;
            Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;

            ObjectIdCollection purgeableIds = new ObjectIdCollection();

            foreach (ObjectId id in pTableIds)
            {
                SymbolTable table = ptr.GetObject(id, OpenMode.ForRead, false) as SymbolTable;
                foreach (ObjectId recordId in table)
                    purgeableIds.Add(recordId);
            }

            pdb.Purge(purgeableIds);

            if (purgeableIds.Count == 0)
                return false;
            itemsPurged = true;

            foreach (ObjectId id in purgeableIds)
            {
                try
                {
                    SymbolTableRecord record = ptr.GetObject(id, OpenMode.ForWrite) as SymbolTableRecord;
                    string recordName = record.Name;
                    record.Erase();
                    if (!pblnSilent)
                    {
                        if (!recordName.Contains("|"))
                        {
                            ed.WriteMessage("\nPurging " + record.GetType().Name + " " + recordName);
                        }
                    }
                }
                catch (Autodesk.AutoCAD.Runtime.Exception e)
                {
                    if ((e.ErrorStatus == ErrorStatus.CannotBeErasedByCaller) || (e.ErrorStatus == (ErrorStatus)20072))
                        itemsPurged = false;
                    else
                        throw e;
                }
            }
            return itemsPurged;
        }


        public static bool purgeDictionaries(Database pdb, Transaction ptr, ObjectIdCollection pDictIds, bool pblnSilent)
        {
            bool itemsPurged = false;
            Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;

            ObjectIdCollection purgeableIds = new ObjectIdCollection();

            foreach (ObjectId id in pDictIds)
            {
                DBDictionary dict = ptr.GetObject(id, OpenMode.ForRead, false) as DBDictionary;
                foreach (DBDictionaryEntry de in dict)
                {
                    purgeableIds.Add(de.m_value);
                }
            }

            pdb.Purge(purgeableIds);

            if (purgeableIds.Count == 0)
                return false;
            itemsPurged = true;

            DBDictionary nod = ptr.GetObject(pdb.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
            foreach (ObjectId id in purgeableIds)
            {
                try
                {
                    DBObject obj = ptr.GetObject(id, OpenMode.ForWrite) as DBObject;
                    obj.Erase();
                    if (!pblnSilent)
                    {
                        foreach (ObjectId dictId in pDictIds)
                        {
                            DBDictionary dict = ptr.GetObject(dictId, OpenMode.ForRead, false) as DBDictionary;
                            string dictName = nod.NameAt(dictId);
                            if (dict.Contains(id))
                            {
                                ed.WriteMessage("\nPurging " + dict.NameAt(id) + " from " + dictName);
                                break;
                            }
                        }
                    }
                }
                catch (Autodesk.AutoCAD.Runtime.Exception e)
                {
                    if ((e.ErrorStatus == ErrorStatus.CannotBeErasedByCaller) || (e.ErrorStatus == (ErrorStatus)20072))
                        itemsPurged = false;
                    else
                        throw e;
                }
            }
            return itemsPurged;
        }

<code>

Valued Mentor
jeff
Posts: 338
Registered: ‎05-12-2009
Message 2 of 3 (150 Views)

Re: VISRETAIN and Purge

03-17-2013 09:56 PM in reply to: Dale.Bartlett

Just guessing but,

does calling CloseInput(True) after ReadDwgFile make a difference?

You can also find your answers @ TheSwamp
Distinguished Contributor
Dale.Bartlett
Posts: 173
Registered: ‎01-06-2003
Message 3 of 3 (148 Views)

Re: VISRETAIN and Purge

03-17-2013 10:05 PM in reply to: jeff

In a moment of insight after a sleepless night, it came to me: Resolve the Xrefs before processing

<code>

db.ReadDwgFile(lstrFileName, FileOpenMode.OpenForReadAndWriteNoShare, true, "");
db.RetainOriginalThumbnailBitmap = true;
db.ResolveXrefs(true, false);

<code>

Hope this is helpful for another poor soul.

Dale

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.