Modify all dynamic blocks in a DWG file with C#

Modify all dynamic blocks in a DWG file with C#

javierTZL36
Explorer Explorer
1,076 Views
1 Reply
Message 1 of 2

Modify all dynamic blocks in a DWG file with C#

javierTZL36
Explorer
Explorer

Hello!

I am new to the AutoCAD API. I hope you can help me.

My goal is to modify the distance of all the dynamic blocks of an AutoCAD plan.

 

On a first try, I am modifying all the dynamic blocks using the following code. This approach works fine and I can see how the dynamic blocks change in AutoCAD.

 

[CommandMethod("test1")]

static public void Test1()

{

var dimensions = new Dictionary<string, double> { { "LMB", 750 }, { "H", 400 }, { "S", 44 }, { "Z", 6 }, { "X", 30 }, { "Y", 120 } };

Document doc = Application.DocumentManager.MdiActiveDocument;

Database db = doc.Database;

Transaction tr = db.TransactionManager.StartTransaction();

Editor editor = doc.Editor;

 

using (tr)

{

var result = editor.SelectAll();

SelectionSet ss = result.Value;

ObjectId[] ids = ss.GetObjectIds();

 

var blockReferenceList = new List();

foreach (var id in ids)

{

var br = tr.GetObject(id, OpenMode.ForRead) as BlockReference;

if (br != null && br.IsDynamicBlock)

{

blockReferenceList.Add(br);

}

}

foreach (var br in blockReferenceList)

{

DynamicBlockReferencePropertyCollection pc = br.DynamicBlockReferencePropertyCollection;

foreach (DynamicBlockReferenceProperty prop in pc)

{

if (prop.UnitsType == DynamicBlockReferencePropertyUnitsType.Distance)

{

var dimension = dimensions.SingleOrDefault(x => x.Key == prop.PropertyName);

if (dimension.Key != null)

{

prop.Value = dimension.Value;

}

}

}

}

tr.Commit();

}

}

 

In a second attempt, what I need is to modify all the dynamic blocks by loading a DWG file into memory, modifying it and then saving the changes to disk. I am using the following code but it is not working. Can you help me with this, please?

 

[CommandMethod("test2")]

static public void Test2()

{

var dimensions = new Dictionary<string, double> { { "LMB", 750 }, { "H", 400 }, { "S", 44 }, { "Z", 6 }, { "X", 30 }, { "Y", 120 } };

const string file = @"C:\CAD\temp.dwg";

using (var db = new Database(false, true))

{

db.ReadDwgFile(file, FileShare.Read, false, "");

db.CloseInput(true);

using (var tr = db.TransactionManager.StartTransaction())

{

var wdb = HostApplicationServices.WorkingDatabase;

HostApplicationServices.WorkingDatabase = db;

///

BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

var blockReferenceList = new List();

foreach (var id in bt)

{

BlockReference br = tr.GetObject(id, OpenMode.ForRead) as BlockReference;

if (br != null && br.IsDynamicBlock)

{

blockReferenceList.Add(br);

}

}

 

foreach (var br in blockReferenceList)

{

DynamicBlockReferencePropertyCollection pc = br.DynamicBlockReferencePropertyCollection;

foreach (DynamicBlockReferenceProperty prop in pc)

{

if (prop.UnitsType == DynamicBlockReferencePropertyUnitsType.Distance)

{

var dimension = dimensions.SingleOrDefault(x => x.Key == prop.PropertyName);

if (dimension.Key != null)

{

prop.Value = dimension.Value;

}

}

}

}

 

///

tr.Commit();

HostApplicationServices.WorkingDatabase = wdb;

}

db.SaveAs(file, DwgVersion.Current);

}

}

}

 

Note: Something to note is that the line highlighted in red always returns null.

 

Thanks!

0 Likes
1,077 Views
1 Reply
Reply (1)
Message 2 of 2

_gile
Consultant
Consultant

Hi,

The BlockTable does not contain BlockReferences, it contains BlockTableRecords (i.e. model space, paper spaces, and block definitions).

You can get the BlockReferences referencing the block definitions with the BlockTableRecord.GetBlockReferenceIds method.

Another way would be iterating through model and paer spaces to get the inserted block references as the Editor.SelectAll does.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes