Deleted objects in closed files persistence

Deleted objects in closed files persistence

Anonymous
Not applicable
4,014 Views
27 Replies
Message 1 of 28

Deleted objects in closed files persistence

Anonymous
Not applicable

Hello,

 

I'm using C# to read block references from a folder of drawings and I'm running into an issue. If some objects are deleted in a drawing and then saved and closed, it appears they are still in the drawing when using the Database.ReadDwgFile method. 

I've tried Auditing and Purging these deleted entities using the code below, however the collection returned from the Database.Purge() method is always 0.

 

If I open the drawing and then audit/purge, the entities are properly erased. However this would significantly slow down the data gathering, as Autocad would have to open and load the file into the editor as opposed to just working with the Database. 


I'm not concerned with purging the entities themselves, I just want to NOT read them into a collection, and the "OpenErased" flag is always set to false during my gathering. Is there another way to determine if an object exists in the database but not the drawing?

 

//purge unreferenced entities
            ObjectIdCollection purgedIds = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, false) as BlockTableRecord;
                    if (btr.XrefStatus == XrefStatus.NotAnXref)
                    {
                        foreach (ObjectId oid in btr)
                        {
                            purgedIds.Add(oid);
                            
                        }
                    }
                }
                tr.Commit();
            }

            db.Purge(purgedIds);

            foreach (ObjectId oid in purgedIds)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)tr.GetObject(oid, OpenMode.ForWrite, false);
                    try
                    {
                        ent.Erase();
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        log.Debug(ex);
                    }
                    tr.Commit();
                }
            }
            
            try
            {
                bool fixErrors = true;
                bool echo = true;
                
                db.Audit(fixErrors, echo);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                log.Debug(ex);
            }
0 Likes
Accepted solutions (1)
4,015 Views
27 Replies
Replies (27)
Message 2 of 28

norman.yuan
Mentor
Mentor

Since you are using AutoCAD .NET API, your post would get more attentions and responses if you post in .NET forum here.

 

Anyway, could you upload a DWG file with erased entities still in it to prove your case?

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 28

Anonymous
Not applicable

See attached.

0 Likes
Message 4 of 28

Anonymous
Not applicable

Is there a way to move the post over there or would I just have to make a new thread? I'm kind of new to the forums here.

0 Likes
Message 5 of 28

norman.yuan
Mentor
Mentor

Well, I ran some code against the drawing (as side database) and could not find any erased entity. So, I also did some test: open the drawing as side database, erase something in it (in modelspace). Save and close it; the open is as side database again and scan the modelspace, no erased entity found.

 

Here is the code:

 

using System.Linq;
using System.IO;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(ErasedEntitiesInDwg.MyCommands))]

namespace ErasedEntitiesInDwg
{
    public class MyCommands 
    {
        private const string FILE_NAME = 
            @"C:\Temp\E001977-03-116 SHT 2.dwg";

        [CommandMethod("ErasedInDB")]
        public static void FindErasedInSideDatabase()
        {
            var dwg = CadApp.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;

            try
            {
                if (File.Exists(FILE_NAME))
                {
                    FindEraseEntitiesInSideDB(FILE_NAME, out int totalCount, out int erasedCount);
                    var msg = $"Total entity count ModelSpace: {totalCount}\n" +
                        $"Erased entity count: {erasedCount}";
                    CadApp.ShowAlertDialog(msg);
                }
                else
                {
                    ed.WriteMessage("\nCannot fine file: {0}", FILE_NAME);
                    ed.WriteMessage("\n*Cancel*");
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: {0}", ex.Message);
                ed.WriteMessage("\n*Cancel*");
            }
            finally
            {
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
            }
        }

        private static void FindEraseEntitiesInSideDB(string fileName, out int entityCount, out int erasedCount)
        {
            entityCount = 0;
            erasedCount = 0;

            using (var db = new Database(false, true))
            {
                db.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                using (var tran = db.TransactionManager.StartTransaction())
                {
                    var model = (BlockTableRecord)tran.GetObject(
                        SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
                    var ids = model.Cast<ObjectId>();
                    entityCount = ids.Count();
                    foreach (ObjectId id in model)
                    {
                        if (id.IsErased) erasedCount++;
                    }
                    tran.Commit();
                }
            }
        }

        [CommandMethod("ErasingInDB")]
        public static void ErasingInSideDatabase()
        {
            var dwg = CadApp.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;

            try
            {
                if (File.Exists(FILE_NAME))
                {
                    int count = DoEraseInSideDB(FILE_NAME);
                    var msg = $"Erased entity count: {count}";
                    CadApp.ShowAlertDialog(msg);
                }
                else
                {
                    ed.WriteMessage("\nCannot fine file: {0}", FILE_NAME);
                    ed.WriteMessage("\n*Cancel*");
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: {0}", ex.Message);
                ed.WriteMessage("\n*Cancel*");
            }
            finally
            {
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
            }
        }

        private static int DoEraseInSideDB(string fileName)
        {
            int count = 0;

            using (var db = new Database(false, true))
            {
                db.ReadDwgFile(fileName, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
                using (var tran = db.TransactionManager.StartTransaction())
                {
                    var model = (BlockTableRecord)tran.GetObject(
                        SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
                    var ids = model.Cast<ObjectId>();
                    
                    foreach (ObjectId id in model)
                    {
                        //Erase all entities on layer "Text"
                        var ent = (Entity)tran.GetObject(id, OpenMode.ForRead);
                        if (ent.Layer.ToUpper()=="TEXT")
                        {
                            ent.UpgradeOpen();
                            ent.Erase();
                            count++;
                        }
                    }
                    tran.Commit();
                }

                if (count>0)
                {
                    db.SaveAs(fileName,true, DwgVersion.Current, null);
                }
            }

            return count;
        }
    }
}

 

That is, with this code loaded,

1. I ran command "ErasedInDb" first to prove that is no erased entity in modelspace (322 entities);

2. I ran command "ErasingInDb", which erases 84 entities on layer "Text";

3. I ran command "ErasedInDb" again, no erased entity found (238 entities found, because 84 were erased).

 

Since you did not post all code that may related to your issue/question, I suspect that you are doing something wrong. For example, after erasing, the entities are only flagged as "Erased" until the drawing is saved. Did you do something after erasing but before saving?

 

BTW, if you want to move the thread to .NET forum, you click "Options-Report" to ask moderator to do it.

Norman Yuan

Drive CAD With Code

EESignature

Message 6 of 28

Anonymous
Not applicable

Whoops, added the wrong file.

0 Likes
Message 7 of 28

Anonymous
Not applicable

Okay here is a full dump of code I'm running right now to test this:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;

namespace ClassLibrary2
{
    public class Material
    {
        public String BlockName { get; set; }
        public String BlockID { get; set; }
        public String Function { get; set; }
        public String Tag { get; set; }
        public String Type { get; set; }
        public String Size { get; set; }
        public String DrawingNumber { get; set; }

        /// <summary>
        /// The Sync Change type, the default value is 'Unspecified'
        /// </summary>
        public ChangeTypeCode ChangeType { get; set; }
    }
    public enum ChangeTypeCode
    {
        Unspecified = 0,
        Same = 1,
        Updated = 2,
        Deleted = 3,
        New = 4,
        UpdatedFromEDM = 5
    }
    public class Class1
    {
        [CommandMethod("TestDB")]
        public static void CollectMaterials()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            string dwg = "C:\\E001977 EDM Testing\\4. Drafting\\P&ID\\E001977-03-116 SHT 1.DWG";
            using (Database db = new Database(false, false))
            {
                db.ReadDwgFile(dwg, FileShare.ReadWrite, false, "");
                List<Material> dwgComponents = CollectMaterials(db, ed, dwg);
                foreach (Material material in dwgComponents)
                {
                    ed.WriteMessage("\nHandle: {0} Block Name: {1} Tag: {2}", material.BlockID, material.BlockName, material.Tag);
                }
            }
        }
        public static List<Material> CollectMaterials(Database db, Editor ed, string filename)
        {
            List<Material> dwgComponents = new List<Material>();

            //purge unreferenced entities
            ObjectIdCollection purgedIds = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, true) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, true) as BlockTableRecord;
                    if (btr.XrefStatus == XrefStatus.NotAnXref)
                    {
                        foreach (ObjectId oid in btr)
                        {
                            purgedIds.Add(oid);

                        }
                    }
                }
                tr.Commit();
            }

            db.Purge(purgedIds);

            foreach (ObjectId oid in purgedIds)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)tr.GetObject(oid, OpenMode.ForWrite, true);
                    try
                    {
                        ent.Erase();
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        ed.WriteMessage(ex.Message);
                    }
                    tr.Commit();
                }
            }

            try
            {
                bool fixErrors = true;
                bool echo = true;

                db.Audit(fixErrors, echo);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage(ex.Message);
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary gd = (DBDictionary)tr.GetObject(db.GroupDictionaryId, OpenMode.ForRead, false);
                foreach (DBDictionaryEntry gdentry in gd)
                {

                    ObjectId groupid = gdentry.Value;
                    Group dictionarygroup = (Group)tr.GetObject(groupid, OpenMode.ForRead, false);
                    ResultBuffer rb = dictionarygroup.GetXDataForApplication("CFD1");
                    if (rb != null)
                    {
                        //group entity
                        //need to find tag and shortdesc
                        Material comp = new Material();
                        bool exclude = false;
                        string tag = "";
                        string shortdesc = "";
                        string blockname = "";
                        string blockid = dictionarygroup.Handle.ToString();

                        foreach (ObjectId entityid in dictionarygroup.GetAllEntityIds())
                        {
                            Entity ent = (Entity)tr.GetObject(entityid, OpenMode.ForRead, false);

                            if ((ent as BlockReference != null))
                            {
                                BlockReference bref = ent as BlockReference;
                                if (bref.Name == "LABEL_EQUIP" || bref.Name == "TAG_1_I")
                                {
                                    foreach (ObjectId attid in bref.AttributeCollection)
                                    {
                                        AttributeReference attref = (AttributeReference)tr.GetObject(attid, OpenMode.ForRead, false);
                                        switch (attref.Tag)
                                        {
                                            case "TAG":
                                                {
                                                    tag = attref.TextString;
                                                    if (tag.ToUpper().Contains("%%U"))
                                                    {
                                                        tag = tag.ToUpper().Replace("%%U", "");
                                                    }
                                                    break;
                                                }

                                            case "SHORTDESC":
                                                shortdesc = attref.TextString;
                                                break;
                                        }
                                    }
                                }
                            }

                            if ((shortdesc.ToUpper().Contains("BOTTLE") || shortdesc.ToUpper().Contains("SCRUBBER")))
                                exclude = true;
                            if (shortdesc.ToUpper().Contains("CYLINDER"))
                                exclude = true;
                            if (shortdesc.ToUpper().Contains("COMPRESSOR FRAME"))
                                exclude = true;
                            if (shortdesc.ToUpper().Contains("JUNCTION BOX"))
                                exclude = true;
                        }

                        if (!exclude)
                        {
                            comp.Tag = tag;
                            comp.BlockID = blockid;
                            comp.DrawingNumber = filename;
                            comp.BlockName = blockname;
                            if (!string.IsNullOrEmpty(tag))
                                dwgComponents.Add(comp);
                        }

                    }
                }

                tr.Commit();
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, false) as BlockTableRecord;
                    if (btr.XrefStatus == XrefStatus.NotAnXref)
                    {
                        foreach (ObjectId oid in btr)
                        {
                            bool exclude = false;

                            Entity ent = (Entity)tr.GetObject(oid, OpenMode.ForRead, false);
                            ResultBuffer rb = ent.GetXDataForApplication("CFD1");
                            if (rb != null)
                            {
                                TypedValue[] tv = rb.AsArray();
                                string cadworxComponentType = tv[8].Value.ToString();
                                switch (cadworxComponentType)
                                {

                                    case "301":
                                        exclude = true;
                                        break;
                                    case "306":
                                        exclude = true;
                                        break;
                                    case "307":
                                        exclude = true;
                                        break;
                                    case "308":
                                        exclude = true;
                                        break;
                                    case "341":
                                        exclude = true;
                                        break;

                                }
                                if ((ent as BlockReference != null) && !exclude)
                                {
                                    BlockReference bref = ent as BlockReference;
                                    string brefName = null;
                                    if (bref.IsDynamicBlock)
                                    {
                                        BlockTableRecord dynBtr = (BlockTableRecord)tr.GetObject(bref.DynamicBlockTableRecord, OpenMode.ForRead, false);
                                        brefName = dynBtr.Name;

                                    }
                                    else
                                    {
                                        brefName = bref.Name;
                                    }
                                    if (brefName.ToUpper().Contains("DYN_CO_") || brefName.ToUpper().Contains("DYN_LO_") || brefName.ToUpper().Contains("DYN_SH_") || brefName.ToUpper().Contains("DYN_JB") || brefName.ToUpper().Contains("DYN_PI_") || brefName.ToUpper().Contains("NOZZLE_"))
                                    {
                                        // hmi/plc/safety component, do not include
                                        exclude = true;
                                    }

                                    if (!exclude)
                                    {
                                        Material comp = new Material();

                                        string size = null;
                                        string function = null;
                                        string tag = null;
                                        string type = null;
                                        string blockid = bref.Handle.ToString();
                                        foreach (ObjectId attid in bref.AttributeCollection)
                                        {
                                            AttributeReference attref = (AttributeReference)tr.GetObject(attid, OpenMode.ForRead, false);
                                            switch (attref.Tag)
                                            {
                                                case "SIZE":
                                                    size = attref.TextString;
                                                    break;
                                                case "TAG":
                                                    {
                                                        tag = attref.TextString;
                                                        if (tag.ToUpper().Contains("%%U"))
                                                        {
                                                            tag = tag.ToUpper().Replace("%%U", "");
                                                        }
                                                        break;
                                                    }

                                                case "TYPE":
                                                    type = attref.TextString;
                                                    break;
                                                case "FUNCTION":
                                                    function = attref.TextString;
                                                    break;
                                            }
                                        }

                                        if (size == "")
                                            size = null;
                                        comp.Size = size;

                                        if (function == "")
                                            function = null;
                                        comp.Function = function;

                                        comp.Tag = tag;

                                        if (type == "")
                                            type = null;
                                        comp.Type = type;
                                        comp.BlockID = blockid;
                                        comp.DrawingNumber = filename;
                                        comp.BlockName = brefName;
                                        if (!string.IsNullOrEmpty(tag))
                                            dwgComponents.Add(comp);
                                    }
                                }
                            }

                        }
                    }
                }
                tr.Commit();
            }
            return dwgComponents;
        }
    }
    
}

And here is the result of me running the command:

 

Command: TESTDB



Auditing Header


Auditing Tables


Auditing Entities Pass 1

Pass 1 6800    objects audited
Auditing Entities Pass 2

Pass 2 6800    objects audited
Auditing Blocks

 101     Blocks audited



Auditing AcDsRecords


Total errors found 0 fixed 0

Erased 0 objects


Handle: 1265C Block Name:  Tag: F-1101K
Handle: 1265F Block Name:  Tag: SL-1101
Handle: 1466F Block Name: FLEX_HOSE Tag: SP-1608
Handle: 14735 Block Name: Y_STRAINER Tag: SCN1
Handle: 1266F Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 12677 Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 1268D Block Name: DYN_VAL_BALL Tag: BSN2,PL
Handle: 12696 Block Name: DYN_VAL_BALL Tag: BSN2,PL
Handle: 126D6 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 1271A Block Name: DYN_DI_LOCAL Tag: 1101K1
Handle: 12726 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 127A7 Block Name: DYN_DI_LOCAL Tag: SRV
Handle: 127C3 Block Name: DYN_DI_LOCAL Tag: SRV
Handle: 1281A Block Name: BLEED_WITH_VALVE Tag: BR-1101K1
Handle: 12820 Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K1
Handle: 12828 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 12832 Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12879 Block Name: FLEX_HOSE_FLG Tag: NX-1101N1
Handle: 128CF Block Name: DYN_VAL_CHECK_SW_L Tag: CCS2
Handle: 128E2 Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12926 Block Name: BLEED_WITH_VALVE Tag: BR-1101K3
Handle: 1292C Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K3
Handle: 12934 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 1293E Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12968 Block Name: BLEED_WITH_VALVE Tag: BR-1101K2
Handle: 1296E Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 12978 Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 129A1 Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K2
Handle: 129EA Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12A51 Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 12A8B Block Name: FLEX_HOSE Tag: SP-1506
Handle: 12A91 Block Name: DYN_VAL_CHECK Tag: CST4
Handle: 12AFD Block Name: FLEX_HOSE_FLG Tag: NX-1101M1
Handle: 12B1A Block Name: DYN_VAL_GATE Tag: NSM2
Handle: 12B43 Block Name: DYN_VAL_GATE Tag: NSM2
Handle: 12BAE Block Name: DYN_VAL_BALL Tag: BC12,PL
Handle: 12C2D Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 12C4B Block Name: Dyn_Val_Ctrl_Ball_F Tag: PCV-1503

And here is a screenshot of the drawing, opened, with only two "tagged" components in the drawing:

 

image.png

 

I don't understand where all those other entities that are being reported are coming from. 

0 Likes
Message 8 of 28

ActivistInvestor
Mentor
Mentor

Your drawing contains numerous blocks containing insertions of other blocks, and complicating that, in some of those blocks, the entities are in groups.

 

What you're trying to do requires multiple calls to Purge(), each time erasing the objects that it returns. For example let's suppose there are two blocks in your drawing, named 'A' and 'B'. Block 'A' contains an insertion of block 'B'. But, there are no insertions of either A or B in model or paper space. If you pass the ObjectIds of the BlockTableRecords for both of those blocks to Purge(), it will only return the ObjectId of block 'A', because there's an insertion of block 'B' within block 'A'. So, after you erase block A, and then call Purge() again, passing it the same ObjectIds, it will then return the ObjectId of the BlockTableRecord for block 'B', because you already erased block 'A', which contained the only insertion of block B.

 

IOW, what you're trying to do requires numerous calls to Purge(), and what your code appears to be trying to do, is to re-invent the Database.WBlock() method.

 

If you want to get rid of everything for which no objects in model or paper space have a dependence on, you can use Database.WBlock() to do the equivalent of the WBLOCK * command (e.g., WBLOCK the entire database to a new DWG file). Then you would just replace the source drawing file with the file created by saving the Database returned by Wblock().


@Anonymous wrote:

Okay here is a full dump of code I'm running right now to test this:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;

namespace ClassLibrary2
{
    public class Material
    {
        public String BlockName { get; set; }
        public String BlockID { get; set; }
        public String Function { get; set; }
        public String Tag { get; set; }
        public String Type { get; set; }
        public String Size { get; set; }
        public String DrawingNumber { get; set; }

        /// <summary>
        /// The Sync Change type, the default value is 'Unspecified'
        /// </summary>
        public ChangeTypeCode ChangeType { get; set; }
    }
    public enum ChangeTypeCode
    {
        Unspecified = 0,
        Same = 1,
        Updated = 2,
        Deleted = 3,
        New = 4,
        UpdatedFromEDM = 5
    }
    public class Class1
    {
        [CommandMethod("TestDB")]
        public static void CollectMaterials()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            string dwg = "C:\\E001977 EDM Testing\\4. Drafting\\P&ID\\E001977-03-116 SHT 1.DWG";
            using (Database db = new Database(false, false))
            {
                db.ReadDwgFile(dwg, FileShare.ReadWrite, false, "");
                List<Material> dwgComponents = CollectMaterials(db, ed, dwg);
                foreach (Material material in dwgComponents)
                {
                    ed.WriteMessage("\nHandle: {0} Block Name: {1} Tag: {2}", material.BlockID, material.BlockName, material.Tag);
                }
            }
        }
        public static List<Material> CollectMaterials(Database db, Editor ed, string filename)
        {
            List<Material> dwgComponents = new List<Material>();

            //purge unreferenced entities
            ObjectIdCollection purgedIds = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, true) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, true) as BlockTableRecord;
                    if (btr.XrefStatus == XrefStatus.NotAnXref)
                    {
                        foreach (ObjectId oid in btr)
                        {
                            purgedIds.Add(oid);

                        }
                    }
                }
                tr.Commit();
            }

            db.Purge(purgedIds);

            foreach (ObjectId oid in purgedIds)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)tr.GetObject(oid, OpenMode.ForWrite, true);
                    try
                    {
                        ent.Erase();
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        ed.WriteMessage(ex.Message);
                    }
                    tr.Commit();
                }
            }

            try
            {
                bool fixErrors = true;
                bool echo = true;

                db.Audit(fixErrors, echo);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage(ex.Message);
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary gd = (DBDictionary)tr.GetObject(db.GroupDictionaryId, OpenMode.ForRead, false);
                foreach (DBDictionaryEntry gdentry in gd)
                {

                    ObjectId groupid = gdentry.Value;
                    Group dictionarygroup = (Group)tr.GetObject(groupid, OpenMode.ForRead, false);
                    ResultBuffer rb = dictionarygroup.GetXDataForApplication("CFD1");
                    if (rb != null)
                    {
                        //group entity
                        //need to find tag and shortdesc
                        Material comp = new Material();
                        bool exclude = false;
                        string tag = "";
                        string shortdesc = "";
                        string blockname = "";
                        string blockid = dictionarygroup.Handle.ToString();

                        foreach (ObjectId entityid in dictionarygroup.GetAllEntityIds())
                        {
                            Entity ent = (Entity)tr.GetObject(entityid, OpenMode.ForRead, false);

                            if ((ent as BlockReference != null))
                            {
                                BlockReference bref = ent as BlockReference;
                                if (bref.Name == "LABEL_EQUIP" || bref.Name == "TAG_1_I")
                                {
                                    foreach (ObjectId attid in bref.AttributeCollection)
                                    {
                                        AttributeReference attref = (AttributeReference)tr.GetObject(attid, OpenMode.ForRead, false);
                                        switch (attref.Tag)
                                        {
                                            case "TAG":
                                                {
                                                    tag = attref.TextString;
                                                    if (tag.ToUpper().Contains("%%U"))
                                                    {
                                                        tag = tag.ToUpper().Replace("%%U", "");
                                                    }
                                                    break;
                                                }

                                            case "SHORTDESC":
                                                shortdesc = attref.TextString;
                                                break;
                                        }
                                    }
                                }
                            }

                            if ((shortdesc.ToUpper().Contains("BOTTLE") || shortdesc.ToUpper().Contains("SCRUBBER")))
                                exclude = true;
                            if (shortdesc.ToUpper().Contains("CYLINDER"))
                                exclude = true;
                            if (shortdesc.ToUpper().Contains("COMPRESSOR FRAME"))
                                exclude = true;
                            if (shortdesc.ToUpper().Contains("JUNCTION BOX"))
                                exclude = true;
                        }

                        if (!exclude)
                        {
                            comp.Tag = tag;
                            comp.BlockID = blockid;
                            comp.DrawingNumber = filename;
                            comp.BlockName = blockname;
                            if (!string.IsNullOrEmpty(tag))
                                dwgComponents.Add(comp);
                        }

                    }
                }

                tr.Commit();
            }

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, false) as BlockTableRecord;
                    if (btr.XrefStatus == XrefStatus.NotAnXref)
                    {
                        foreach (ObjectId oid in btr)
                        {
                            bool exclude = false;

                            Entity ent = (Entity)tr.GetObject(oid, OpenMode.ForRead, false);
                            ResultBuffer rb = ent.GetXDataForApplication("CFD1");
                            if (rb != null)
                            {
                                TypedValue[] tv = rb.AsArray();
                                string cadworxComponentType = tv[8].Value.ToString();
                                switch (cadworxComponentType)
                                {

                                    case "301":
                                        exclude = true;
                                        break;
                                    case "306":
                                        exclude = true;
                                        break;
                                    case "307":
                                        exclude = true;
                                        break;
                                    case "308":
                                        exclude = true;
                                        break;
                                    case "341":
                                        exclude = true;
                                        break;

                                }
                                if ((ent as BlockReference != null) && !exclude)
                                {
                                    BlockReference bref = ent as BlockReference;
                                    string brefName = null;
                                    if (bref.IsDynamicBlock)
                                    {
                                        BlockTableRecord dynBtr = (BlockTableRecord)tr.GetObject(bref.DynamicBlockTableRecord, OpenMode.ForRead, false);
                                        brefName = dynBtr.Name;

                                    }
                                    else
                                    {
                                        brefName = bref.Name;
                                    }
                                    if (brefName.ToUpper().Contains("DYN_CO_") || brefName.ToUpper().Contains("DYN_LO_") || brefName.ToUpper().Contains("DYN_SH_") || brefName.ToUpper().Contains("DYN_JB") || brefName.ToUpper().Contains("DYN_PI_") || brefName.ToUpper().Contains("NOZZLE_"))
                                    {
                                        // hmi/plc/safety component, do not include
                                        exclude = true;
                                    }

                                    if (!exclude)
                                    {
                                        Material comp = new Material();

                                        string size = null;
                                        string function = null;
                                        string tag = null;
                                        string type = null;
                                        string blockid = bref.Handle.ToString();
                                        foreach (ObjectId attid in bref.AttributeCollection)
                                        {
                                            AttributeReference attref = (AttributeReference)tr.GetObject(attid, OpenMode.ForRead, false);
                                            switch (attref.Tag)
                                            {
                                                case "SIZE":
                                                    size = attref.TextString;
                                                    break;
                                                case "TAG":
                                                    {
                                                        tag = attref.TextString;
                                                        if (tag.ToUpper().Contains("%%U"))
                                                        {
                                                            tag = tag.ToUpper().Replace("%%U", "");
                                                        }
                                                        break;
                                                    }

                                                case "TYPE":
                                                    type = attref.TextString;
                                                    break;
                                                case "FUNCTION":
                                                    function = attref.TextString;
                                                    break;
                                            }
                                        }

                                        if (size == "")
                                            size = null;
                                        comp.Size = size;

                                        if (function == "")
                                            function = null;
                                        comp.Function = function;

                                        comp.Tag = tag;

                                        if (type == "")
                                            type = null;
                                        comp.Type = type;
                                        comp.BlockID = blockid;
                                        comp.DrawingNumber = filename;
                                        comp.BlockName = brefName;
                                        if (!string.IsNullOrEmpty(tag))
                                            dwgComponents.Add(comp);
                                    }
                                }
                            }

                        }
                    }
                }
                tr.Commit();
            }
            return dwgComponents;
        }
    }
    
}

And here is the result of me running the command:

 

Command: TESTDB



Auditing Header


Auditing Tables


Auditing Entities Pass 1

Pass 1 6800    objects audited
Auditing Entities Pass 2

Pass 2 6800    objects audited
Auditing Blocks

 101     Blocks audited



Auditing AcDsRecords


Total errors found 0 fixed 0

Erased 0 objects


Handle: 1265C Block Name:  Tag: F-1101K
Handle: 1265F Block Name:  Tag: SL-1101
Handle: 1466F Block Name: FLEX_HOSE Tag: SP-1608
Handle: 14735 Block Name: Y_STRAINER Tag: SCN1
Handle: 1266F Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 12677 Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 1268D Block Name: DYN_VAL_BALL Tag: BSN2,PL
Handle: 12696 Block Name: DYN_VAL_BALL Tag: BSN2,PL
Handle: 126D6 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 1271A Block Name: DYN_DI_LOCAL Tag: 1101K1
Handle: 12726 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 127A7 Block Name: DYN_DI_LOCAL Tag: SRV
Handle: 127C3 Block Name: DYN_DI_LOCAL Tag: SRV
Handle: 1281A Block Name: BLEED_WITH_VALVE Tag: BR-1101K1
Handle: 12820 Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K1
Handle: 12828 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 12832 Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12879 Block Name: FLEX_HOSE_FLG Tag: NX-1101N1
Handle: 128CF Block Name: DYN_VAL_CHECK_SW_L Tag: CCS2
Handle: 128E2 Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12926 Block Name: BLEED_WITH_VALVE Tag: BR-1101K3
Handle: 1292C Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K3
Handle: 12934 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 1293E Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12968 Block Name: BLEED_WITH_VALVE Tag: BR-1101K2
Handle: 1296E Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2
Handle: 12978 Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 129A1 Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K2
Handle: 129EA Block Name: DYN_VAL_BALL_F Tag: BC12,PL
Handle: 12A51 Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 12A8B Block Name: FLEX_HOSE Tag: SP-1506
Handle: 12A91 Block Name: DYN_VAL_CHECK Tag: CST4
Handle: 12AFD Block Name: FLEX_HOSE_FLG Tag: NX-1101M1
Handle: 12B1A Block Name: DYN_VAL_GATE Tag: NSM2
Handle: 12B43 Block Name: DYN_VAL_GATE Tag: NSM2
Handle: 12BAE Block Name: DYN_VAL_BALL Tag: BC12,PL
Handle: 12C2D Block Name: DYN_DI_LOCAL Tag: F1101K
Handle: 12C4B Block Name: Dyn_Val_Ctrl_Ball_F Tag: PCV-1503

And here is a screenshot of the drawing, opened, with only two "tagged" components in the drawing:

 

image.png

 

I don't understand where all those other entities that are being reported are coming from. 


 

0 Likes
Message 9 of 28

Anonymous
Not applicable

ActivistInvestor,

 

I understand what you're saying, but how does that explain entity handles and the filled out attribute data. Are you suggesting the data exists in the block definitions? I'm not trying to clear the block table record of block definition, I'm trying to read entities that are actually in the drawing, not erased, without having to open the file in the AutoCAD application.

0 Likes
Message 10 of 28

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

ActivistInvestor,

 

I understand what you're saying, but how does that explain entity handles and the filled out attribute data. Are you suggesting the data exists in the block definitions? I'm not trying to clear the block table record of block definition, I'm trying to read entities that are actually in the drawing, not erased, without having to open the file in the AutoCAD application.


I didn't look closely at your code, but now that I did, I see that it is trying to purge entities within BlockTableRecords:

  

 

            ObjectIdCollection purgedIds = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, true) as BlockTable;
                foreach (ObjectId btrid in bt)
                {
                    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, true) as BlockTableRecord;
                    if (btr.XrefStatus == XrefStatus.NotAnXref)
                    {
                        foreach (ObjectId oid in btr)
                        {
                            purgedIds.Add(oid);

                        }
                    }
                }
                tr.Commit();
            }

            db.Purge(purgedIds);

 

You can't purge entities, you can only purge Blocks, Layers, and other objects represented by SymbolTableRecords.

 

If you're using handles to access objects, then they could be erased. Erased objects in a database do not get removed from it until the next time you open the database in the editor (and in fact, may not even be removed then, depending on the value of ISAVEPERCENT).

 

If you're accessing a Database via ReadDwgFile(), then previously-erased entities may still be in the drawing, but you shouldn't see them if you access entities by iterating over BlockTableRecords and open them using GetObject().

 

If you're using handles to access objects, then the objects could be erased. You can't force AutoCAD to remove the erased objects without doing a WBLOCK * or setting ISAVEPERCENT to 0 and opening and saving the file in the drawing editor.

 

In short, if you are using handles to access objects, and you find that they are erased, then they're erased, and you shouldn't try to do anything with them.

 

 

 

 

0 Likes
Message 11 of 28

Anonymous
Not applicable

@ActivistInvestor wrote:
In short, if you are using handles to access objects, and you find that they are erased, then they're erased, and you shouldn't try to do anything with them.

  


Yes, exactly. So look past the purge in the code. When I gather entities, I have set the openErased flag to false. So how am I getting entities that are erased?

0 Likes
Message 12 of 28

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

@ActivistInvestor wrote:
In short, if you are using handles to access objects, and you find that they are erased, then they're erased, and you shouldn't try to do anything with them.

  


Yes, exactly. So look past the purge in the code. When I gather entities, I have set the openErased flag to false. So how am I getting entities that are erased?


Your code calls GetObject() in several places, and I'm not sure which one you're referring to when you say you're getting erased entities.

 

Please point out the line of code where the erased entities are coming from, as I don't have time to repro this here.

 

 

 

0 Likes
Message 13 of 28

Anonymous
Not applicable

@ActivistInvestor wrote:

@Anonymous wrote:

@ActivistInvestor wrote:
In short, if you are using handles to access objects, and you find that they are erased, then they're erased, and you shouldn't try to do anything with them.

  


Yes, exactly. So look past the purge in the code. When I gather entities, I have set the openErased flag to false. So how am I getting entities that are erased?


Sorry, I don't follow. If you pass false for openErased, there should be an exception if the entity whose ObjectId you're trying to open is erased.

 

Is that what's happening? If so, that's what supposed to happen.

 

As far as where erased objects are coming from, they are objects that were erased (or whose owner was erased) in a previous (or the current) editing session.

 

Erased objects are erased objects. You are supposed to treat them as such. 

 

To get rid of them, open the file in AutoCAD, set ISAVEPERCENT to 0, and save the file.

 

 


No. There is no exception. The entities in the dump above are not being reported as erased, even though they are erased. That is the whole problem and why I was trying to purge and audit. Run the code.

0 Likes
Message 14 of 28

ActivistInvestor
Mentor
Mentor

See my reply above, I'm not sure what line of code is producing the erased objects.

0 Likes
Message 15 of 28

Anonymous
Not applicable

@ActivistInvestor wrote:

See my reply above, I'm not sure what line of code is producing the erased objects.


The entities in the drawing were erased in a previous session.

0 Likes
Message 16 of 28

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

No. There is no exception. The entities in the dump above are not being reported as erased, even though they are erased. That is the whole problem and why I was trying to purge and audit. Run the code.


The dump doesn't indicate if the entities that the objects are derived from are erased, because you're not checking to see if they are.

 

The reason you're getting erased entities is because your code is erasing them. The code that gathers all entities in all blocks, and passes their ObjectIds to Purge() then erases all of the ObjectIds that Purge() did not remove. Purge is probably not removing the ObjectIds of entities because you're not supposed to be passing the ObjectIds of entities to Purge() in the first place.

 

So, Purge() doesn't throw an exception and just ignores the ObjectIds of the entities, and returns them in its result, and then the you erase them all.

 

That's why you have erased objects.

 

Phffffffffffffff

 

0 Likes
Message 17 of 28

Anonymous
Not applicable

@ActivistInvestor wrote:

@Anonymous wrote:

No. There is no exception. The entities in the dump above are not being reported as erased, even though they are erased. That is the whole problem and why I was trying to purge and audit. Run the code.


The dump doesn't indicate if the entities that the objects are derived from are erased, because you're not checking to see if they are.

 

The reason you're getting erased entities is because your code is erasing them. The code that gathers all entities in all blocks, and passes their ObjectIds to Purge() then erases all of the ObjectIds that Purge() did not remove. Purge is probably not removing the ObjectIds of entities because you're not supposed to be passing the ObjectIds of entities to Purge() in the first place.

 

So, Purge() doesn't throw an exception and just ignores the ObjectIds of the entities, and returns them in its result, and then the you erase them all.

 

That's why you have erased objects.

 

Phffffffffffffff

 


If you would read my original post, the purge collects 0 entities. There are no entities in that collection. I added that part of the code in an attempt to purge the erased entities, but there are none. The code erases nothing from the drawing, if you actually run it on the drawing I attached.

0 Likes
Message 18 of 28

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

If you would read my original post, the purge collects 0 entities. There are no entities in that collection. I added that part of the code in an attempt to purge the erased entities, but there are none. The code erases nothing from the drawing, if you actually run it on the drawing I attached.


I ran the modified copy of your code shown below, and it's telling me that the some of the groups in that DWG are not accessible.

 

According to the ObjectARX documentation for Group.IsNotAccessible:

 

This method returns true if the group is marked as inaccessible, otherwise returns false. Currently, only groups in Xrefs are marked as inaccessible

 

Here is the output:

 

Command: TESTDB
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 6800    objects audited
Auditing Entities Pass 2
Pass 2 6800    objects audited
Auditing Blocks

 101     Blocks audited

Auditing AcDsRecords
Total errors found 0 fixed 0

Erased 0 objects


Group *A1 IsNotAccessible = true
Group *A10 IsNotAccessible = true
Group *A11 IsNotAccessible = true
Group *A12 IsNotAccessible = true
Group *A13 IsNotAccessible = true
Group *A14 IsNotAccessible = true
Group *A15 IsNotAccessible = true
Group *A16 IsNotAccessible = true
Group *A17 IsNotAccessible = true
Group *A18 IsNotAccessible = true
Group *A19 IsNotAccessible = true
Group *A2 IsNotAccessible = true
Group *A20 IsNotAccessible = true
Group *A21 IsNotAccessible = true
Group *A22 IsNotAccessible = true
Group *A23 IsNotAccessible = true
Group *A3 IsNotAccessible = true
Group *A4 IsNotAccessible = true
Group *A5 IsNotAccessible = true
Group *A6 IsNotAccessible = true
Group *A7 IsNotAccessible = true
Group *A8 IsNotAccessible = true
Group *A9 IsNotAccessible = true
Handle: 1466F Block Name: FLEX_HOSE Tag: SP-1608 IsErased = True IsEffectivelyErased = True
Handle: 14735 Block Name: Y_STRAINER Tag: SCN1 IsErased = True IsEffectivelyErased = True
Handle: 1266F Block Name: DYN_DI_LOCAL Tag: F1101K IsErased = True IsEffectivelyErased = True
Handle: 12677 Block Name: DYN_DI_LOCAL Tag: F1101K IsErased = True IsEffectivelyErased = True
Handle: 1268D Block Name: DYN_VAL_BALL Tag: BSN2,PL IsErased = True IsEffectivelyErased = True
Handle: 12696 Block Name: DYN_VAL_BALL Tag: BSN2,PL IsErased = True IsEffectivelyErased = True
Handle: 126D6 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 1271A Block Name: DYN_DI_LOCAL Tag: 1101K1 IsErased = True IsEffectivelyErased = True
Handle: 12726 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 127A7 Block Name: DYN_DI_LOCAL Tag: SRV IsErased = True IsEffectivelyErased = True
Handle: 127C3 Block Name: DYN_DI_LOCAL Tag: SRV IsErased = True IsEffectivelyErased = True
Handle: 1281A Block Name: BLEED_WITH_VALVE Tag: BR-1101K1 IsErased = True IsEffectivelyErased = True
Handle: 12820 Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K1 IsErased = True IsEffectivelyErased = True
Handle: 12828 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 12832 Block Name: DYN_VAL_BALL_F Tag: BC12,PL IsErased = True IsEffectivelyErased = True
Handle: 12879 Block Name: FLEX_HOSE_FLG Tag: NX-1101N1 IsErased = True IsEffectivelyErased = True
Handle: 128CF Block Name: DYN_VAL_CHECK_SW_L Tag: CCS2 IsErased = True IsEffectivelyErased = True
Handle: 128E2 Block Name: DYN_VAL_BALL_F Tag: BC12,PL IsErased = True IsEffectivelyErased = True
Handle: 12926 Block Name: BLEED_WITH_VALVE Tag: BR-1101K3 IsErased = True IsEffectivelyErased = True
Handle: 1292C Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K3 IsErased = True IsEffectivelyErased = True
Handle: 12934 Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 1293E Block Name: DYN_VAL_BALL_F Tag: BC12,PL IsErased = True IsEffectivelyErased = True
Handle: 12968 Block Name: BLEED_WITH_VALVE Tag: BR-1101K2 IsErased = True IsEffectivelyErased = True
Handle: 1296E Block Name: DYN_VAL_NEEDLE_BLEED Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 12978 Block Name: DYN_VAL_BALL_F Tag: BC12,PL IsErased = True IsEffectivelyErased = True
Handle: 129A1 Block Name: DYN_VAL_RELIEF_F Tag: PSV-1101K2 IsErased = True IsEffectivelyErased = True
Handle: 129EA Block Name: DYN_VAL_BALL_F Tag: BC12,PL IsErased = True IsEffectivelyErased = True
Handle: 12A51 Block Name: DYN_DI_LOCAL Tag: F1101K IsErased = True IsEffectivelyErased = True
Handle: 12A8B Block Name: FLEX_HOSE Tag: SP-1506 IsErased = True IsEffectivelyErased = True
Handle: 12A91 Block Name: DYN_VAL_CHECK Tag: CST4 IsErased = True IsEffectivelyErased = True
Handle: 12AFD Block Name: FLEX_HOSE_FLG Tag: NX-1101M1 IsErased = True IsEffectivelyErased = True
Handle: 12B1A Block Name: DYN_VAL_GATE Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 12B43 Block Name: DYN_VAL_GATE Tag: NSM2 IsErased = True IsEffectivelyErased = True
Handle: 12BAE Block Name: DYN_VAL_BALL Tag: BC12,PL IsErased = True IsEffectivelyErased = True
Handle: 12C2D Block Name: DYN_DI_LOCAL Tag: F1101K IsErased = True IsEffectivelyErased = True
Handle: 12C4B Block Name: Dyn_Val_Ctrl_Ball_F Tag: PCV-1503 IsErased = True IsEffectivelyErased = True

 

 

Here's the modified code:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;

namespace ClassLibrary2
{
   public class Material
   {
      public String BlockName
      {
         get; set;
      }
      public String BlockID
      {
         get; set;
      }
      public String Function
      {
         get; set;
      }
      public String Tag
      {
         get; set;
      }
      public String Type
      {
         get; set;
      }
      public String Size
      {
         get; set;
      }
      public String DrawingNumber
      {
         get; set;
      }

      public ObjectId Id
      {
         get;
         set;
      }
      /// <summary>
      /// The Sync Change type, the default value is 'Unspecified'
      /// </summary>
      public ChangeTypeCode ChangeType
      {
         get; set;
      }
   }
   public enum ChangeTypeCode
   {
      Unspecified = 0,
      Same = 1,
      Updated = 2,
      Deleted = 3,
      New = 4,
      UpdatedFromEDM = 5
   }
   public class Class1
   {
      [CommandMethod("TestDB")]
      public static void CollectMaterials()
      {
         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
         string dwg = "D:\\Inbox\\E001977-03-116 SHT 1.DWG";
         using(Database db = new Database(false, false))
         {
            db.ReadDwgFile(dwg, FileShare.ReadWrite, false, "");
            List<Material> dwgComponents = CollectMaterials(db, ed, dwg);
            foreach(Material mat in dwgComponents)
            {
               ed.WriteMessage("\nHandle: {0} Block Name: {1} Tag: {2} IsErased = {3} IsEffectivelyErased = {4}",
                  mat.BlockID, mat.BlockName, mat.Tag, mat.Id.IsErased, mat.Id.IsEffectivelyErased);            }
         }
      }
      public static List<Material> CollectMaterials(Database db, Editor ed, string filename)
      {
         List<Material> dwgComponents = new List<Material>();

         //purge unreferenced entities
         //ObjectIdCollection purgedIds = new ObjectIdCollection();
         //using(Transaction tr = db.TransactionManager.StartTransaction())
         //{
         // BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, true) as BlockTable;
         // foreach(ObjectId btrid in bt)
         // {
         //    BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, true) as BlockTableRecord;
         //    if(btr.XrefStatus == XrefStatus.NotAnXref)
         //    {
         //       foreach(ObjectId oid in btr)
         //       {
         //          purgedIds.Add(oid);

         //       }
         //    }
         // }
         // tr.Commit();
         //}

         //db.Purge(purgedIds);

         //foreach(ObjectId oid in purgedIds)
         //{
         // using(Transaction tr = db.TransactionManager.StartTransaction())
         // {
         //    Entity ent = (Entity) tr.GetObject(oid, OpenMode.ForWrite, true);
         //    try
         //    {
         //       ent.Erase();
         //    }
         //    catch(Autodesk.AutoCAD.Runtime.Exception ex)
         //    {
         //       ed.WriteMessage(ex.Message);
         //    }
         //    tr.Commit();
         // }
         //}
         try
         {
            bool fixErrors = true;
            bool echo = true;

            db.Audit(fixErrors, echo);
         }
         catch(Autodesk.AutoCAD.Runtime.Exception ex)
         {
            ed.WriteMessage(ex.Message);
         }

         using(Transaction tr = db.TransactionManager.StartTransaction())
         {
            DBDictionary gd = (DBDictionary) tr.GetObject(db.GroupDictionaryId, OpenMode.ForRead, false);
            foreach(DBDictionaryEntry gdentry in gd)
            {

               ObjectId groupid = gdentry.Value;
               Group dictionarygroup = (Group) tr.GetObject(groupid, OpenMode.ForRead, false);
               if(dictionarygroup.IsNotAccessible)
               {
                  ed.WriteMessage("\nGroup {0} IsNotAccessible = true", dictionarygroup.Name);
                  continue;
               }               ResultBuffer rb = dictionarygroup.GetXDataForApplication("CFD1");
               if(rb != null)
               {
                  //group entity
                  //need to find tag and shortdesc
                  Material comp = new Material();
                  bool exclude = false;
                  string tag = "";
                  string shortdesc = "";
                  string blockname = "";
                  string blockid = dictionarygroup.Handle.ToString();

                  foreach(ObjectId entityid in dictionarygroup.GetAllEntityIds())
                  {
                     if(entityid.IsEffectivelyErased)
                        ed.WriteMessage("\n{0}({1}) is effectively erased", 
                           entityid.Handle.ToString(), entityid.ObjectClass.Name);
                     else if(entityid.IsErased)
                        ed.WriteMessage("\n{0}({1}) is erased", 
                           entityid.Handle.ToString(), entityid.ObjectClass.Name);                     Entity ent = (Entity) tr.GetObject(entityid, OpenMode.ForRead, false);

                     if((ent as BlockReference != null))
                     {
                        BlockReference bref = ent as BlockReference;
                        if(bref.Name == "LABEL_EQUIP" || bref.Name == "TAG_1_I")
                        {
                           foreach(ObjectId attid in bref.AttributeCollection)
                           {
                              AttributeReference attref = (AttributeReference) tr.GetObject(attid, OpenMode.ForRead, false);
                              switch(attref.Tag)
                              {
                                 case "TAG":
                                    {
                                       tag = attref.TextString;
                                       if(tag.ToUpper().Contains("%%U"))
                                       {
                                          tag = tag.ToUpper().Replace("%%U", "");
                                       }
                                       break;
                                    }

                                 case "SHORTDESC":
                                    shortdesc = attref.TextString;
                                    break;
                              }
                           }
                        }
                     }

                     if((shortdesc.ToUpper().Contains("BOTTLE") || shortdesc.ToUpper().Contains("SCRUBBER")))
                        exclude = true;
                     if(shortdesc.ToUpper().Contains("CYLINDER"))
                        exclude = true;
                     if(shortdesc.ToUpper().Contains("COMPRESSOR FRAME"))
                        exclude = true;
                     if(shortdesc.ToUpper().Contains("JUNCTION BOX"))
                        exclude = true;
                  }

                  if(!exclude)
                  {
                     comp.Tag = tag;
                     comp.BlockID = blockid;
                     comp.DrawingNumber = filename;
                     comp.BlockName = blockname;
                     comp.Id = dictionarygroup.Id;                     if(!string.IsNullOrEmpty(tag))
                        dwgComponents.Add(comp);
                  }

               }
            }

            tr.Commit();
         }

         using(Transaction tr = db.TransactionManager.StartTransaction())
         {
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
            foreach(ObjectId btrid in bt)
            {
               BlockTableRecord btr = tr.GetObject(btrid, OpenMode.ForRead, false) as BlockTableRecord;
               if(btr.XrefStatus == XrefStatus.NotAnXref)
               {
                  foreach(ObjectId oid in btr)
                  {
                     bool exclude = false;

                     Entity ent = (Entity) tr.GetObject(oid, OpenMode.ForRead, false);
                     ResultBuffer rb = ent.GetXDataForApplication("CFD1");
                     if(rb != null)
                     {
                        TypedValue[] tv = rb.AsArray();
                        string cadworxComponentType = tv[8].Value.ToString();
                        switch(cadworxComponentType)
                        {

                           case "301":
                              exclude = true;
                              break;
                           case "306":
                              exclude = true;
                              break;
                           case "307":
                              exclude = true;
                              break;
                           case "308":
                              exclude = true;
                              break;
                           case "341":
                              exclude = true;
                              break;

                        }
                        if((ent as BlockReference != null) && !exclude)
                        {
                           BlockReference bref = ent as BlockReference;
                           string brefName = null;
                           if(bref.IsDynamicBlock)
                           {
                              BlockTableRecord dynBtr = (BlockTableRecord) 
                                 tr.GetObject(bref.DynamicBlockTableRecord, OpenMode.ForRead, false);
                              brefName = dynBtr.Name;

                           }
                           else
                           {
                              brefName = bref.Name;
                           }
                           if(brefName.ToUpper().Contains("DYN_CO_") || brefName.ToUpper().Contains("DYN_LO_") 
                              || brefName.ToUpper().Contains("DYN_SH_") || brefName.ToUpper().Contains("DYN_JB") 
                              || brefName.ToUpper().Contains("DYN_PI_") || brefName.ToUpper().Contains("NOZZLE_"))
                           {
                              // hmi/plc/safety component, do not include
                              exclude = true;
                           }

                           if(!exclude)
                           {
                              Material comp = new Material();

                              string size = null;
                              string function = null;
                              string tag = null;
                              string type = null;
                              string blockid = bref.Handle.ToString();
                              foreach(ObjectId attid in bref.AttributeCollection)
                              {
                                 AttributeReference attref = (AttributeReference) tr.GetObject(attid, OpenMode.ForRead, false);
                                 switch(attref.Tag)
                                 {
                                    case "SIZE":
                                       size = attref.TextString;
                                       break;
                                    case "TAG":
                                       {
                                          tag = attref.TextString;
                                          if(tag.ToUpper().Contains("%%U"))
                                          {
                                             tag = tag.ToUpper().Replace("%%U", "");
                                          }
                                          break;
                                       }

                                    case "TYPE":
                                       type = attref.TextString;
                                       break;
                                    case "FUNCTION":
                                       function = attref.TextString;
                                       break;
                                 }
                              }

                              if(size == "")
                                 size = null;
                              comp.Size = size;

                              if(function == "")
                                 function = null;
                              comp.Function = function;

                              comp.Tag = tag;

                              if(type == "")
                                 type = null;
                              comp.Type = type;
                              comp.BlockID = blockid;
                              comp.DrawingNumber = filename;
                              comp.BlockName = brefName;
                              if(!string.IsNullOrEmpty(tag))
                                 dwgComponents.Add(comp);
                           }
                        }
                     }

                  }
               }
            }
            tr.Commit();
         }
         return dwgComponents;
      }
   }

}

 

 

0 Likes
Message 19 of 28

Anonymous
Not applicable
@ActivistInvestor wrote:

I ran the modified copy of your code shown below, and it's telling me that the some of the groups in that DWG are not accessible.

 

According to the ObjectARX documentation for Group.IsNotAccessible:

 

This method returns true if the group is marked as inaccessible, otherwise returns false. Currently, only groups in Xrefs are marked as inaccessible


 

This is interesting. So the individual entities listed in the group dictionary are being opened, even though the flag "openErased" is set to false, yet you are able to see the individual entity is erased when you open the object in the transaction. 

 

Thank you for your help. At least now I can individually check.. although it seems bizarre to me that the "openErased" flag is being ignored.

 

0 Likes
Message 20 of 28

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

This is interesting. So the individual entities listed in the group dictionary are being opened, even though the flag "openErased" is set to false, yet you are able to see the individual entity is erased when you open the object in the transaction.  


There are no entities that are erased.

 

I see nothing in your original code that verified that any objects you opened via GetObject() were erased.

 

The only thing my modified version of your code shows is that the groups have their IsNotAccessible property set to true..

 

The changes I made to your code that suggest that there are erased objects is flawed. It was accessing ObjectIds outside of the transaction. Within the transaction, nothing is being reported as being erased.

 

What was it that initially led you to believe that there were erased objects being returned by GetObject() ?

 

 

0 Likes