C# Bulk layer creation crashing AutoCAD

C# Bulk layer creation crashing AutoCAD

Anonymous
Not applicable
1,394 Views
6 Replies
Message 1 of 7

C# Bulk layer creation crashing AutoCAD

Anonymous
Not applicable

Hello Guys,

 

 This is what I am trying to do,

 

- Access a remote dwg and get the lsit of layers

- Check if the layers exists in the current drawing 

- Create the layers (bulk)

 

I am able to first two points, last point is there AutoCAD crahsing. 

I have a collection of layertablerecord. Which says the count is 4 when do a foreach on that to read the layer names it is crashing autocad.

 

List<LayerTableRecord> layers = new List<LayerTableRecord>();
                    layers = Helper.CADHelper.GetLayerfromDWG(GV.dwgTemplatePath, layernames);
public static void AddLayersToCurrentDrawing(List<LayerTableRecord> layerList)
        {
            if (layerList == null)
                throw new ArgumentNullException("layerList");

            if (layerList.Count == 0)
                throw new ArgumentOutOfRangeException("layerList");

            var curDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            if (curDoc == null)
                throw new ArgumentNullException("MdiActiveDocument");

            var curDb = curDoc.Database;

            try
            {
                using (var trans = curDb.TransactionManager.StartOpenCloseTransaction())
                {
                    var layerTable = (LayerTable)trans.GetObject(curDb.LayerTableId, OpenMode.ForWrite);
                    foreach (var layer in layerList)
                    {
                        if (layerTable.Has(layer.Name))
                            continue;

                        layerTable.Add(layer);
                        trans.AddNewlyCreatedDBObject(layer, true);
                    }

                    trans.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                System.Diagnostics.Debug.Write(ex.ToString());
                curDoc.Editor.WriteMessage(ex.ToString());
            }
            catch (SystemException ex)
            {
                curDoc.Editor.WriteMessage(ex.ToString());
            }
        }

it is crashing at the highlighted line. When creating layer. 

 

Please advise.

0 Likes
Accepted solutions (1)
1,395 Views
6 Replies
Replies (6)
Message 2 of 7

kerry_w_brown
Advisor
Advisor

 

Raghulan,

Your description is contradictory.

The preamble says it crashes on the foreach ;

The footnote says it crashes on the highlighted line ( before the foreach).

 

Also : What is the error message ??

 

Regards,

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 3 of 7

Anonymous
Not applicable

It crashes in the red highlight if i try to create the layer.

If i try to do just a foreach to print the selected layernames, this also crashes.

 

foreach (var layer in layerList)
{
     MessabeBox.Show(layer.Name);
}
0 Likes
Message 4 of 7

nagamalliv
Enthusiast
Enthusiast

Hi Raghu,

 

Please try with below mentioned function.

public static void CreateLayer(this Database db, string sLayerName, Transaction tr, int color = 7)
{
var acLyrTbl = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;

if (!acLyrTbl.Has(sLayerName))
{
var acLyrTblRec = new LayerTableRecord();
acLyrTblRec.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, (short)color);
acLyrTblRec.Name = sLayerName;
acLyrTbl.UpgradeOpen();
acLyrTbl.Add(acLyrTblRec);
tr.AddNewlyCreatedDBObject(acLyrTblRec, true);
}
}

Message 5 of 7

norman.yuan
Mentor
Mentor
Accepted solution

So, you get a list of LayerTableRecords from a drawing, then bring these DBobjects out of the Transaction where the LayerTableRecords were created. Then you do to another drawing (current MdiActiveDocument in AutoCAD) and try to add the LayerTableRecord (from other drawing database) into LayerTable in a completely different Transaction!

 

In general, a database-residing object, such as LayerTableRecord, should be only used within a Transaction scope (unless your code creates it and has not added it into the Database). Also, a DBObject in one Database cannot be used in other database (you can use DeepCloneObjects()/WBlock()/WBlockCloneObjects()...to bring objects between databases).

 

In your case, if you need to compare layers in different drawings, you need to first get a list of layer information from other drawing, as you did in first step. But instead of LayerTableRecord, you may create a class that hold necessary layer information (name, color, linetype..., and store the information of the layers in a list of the class.

 

Then, in your current drawing, loop through the list of your class, comparing layer name to see if the layer with the same name exists or not (or, if exists, compare if the layer properties, color, linetype..., are the same or not. Then add new layer (i.e. create a new LayerTableRecord) or update the existing layertablerecord.

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 6 of 7

kerry_w_brown
Advisor
Advisor

 

Personally, I'd look at something like giles' sample:

 

sourceDb.WblockCloneObjects(idCol, targetTableId, idMap, DuplicateRecordCloning.Ignore, false);

 

https://www.theswamp.org/index.php?topic=42539.msg477455#msg477455


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 7 of 7

Anonymous
Not applicable
Thanks Mate, I understand what you saying, ill try it and let you know.
0 Likes