使用 ReadDwgFile 获取 Database ,修改其中的DBText 与 AttributeReference 发生对齐及宽度因子不改变。

使用 ReadDwgFile 获取 Database ,修改其中的DBText 与 AttributeReference 发生对齐及宽度因子不改变。

a932994040
Participant Participant
1,314 Views
8 Replies
Message 1 of 9

使用 ReadDwgFile 获取 Database ,修改其中的DBText 与 AttributeReference 发生对齐及宽度因子不改变。

a932994040
Participant
Participant

想请教一下,我使用 ReadDwgFile 获取 Database ;

使用 Transaction 获取 Database 中的 DBText 与 AttributeReference;

对其属性 TextString 进行修改;

但只修改了文本值,对齐方式与宽度因子未随之改变;

尝试使用 AdjustAlignment,但并未解决问题。

using (var docLock = document.LockDocument())
{
using(var ndb = new Database(false, true))
{
ndb.ReadDwgFile("D:\\Projects\\Document3.dwg", FileShare.ReadWrite, true, "");

using (Transaction tr = ndb.TransactionManager.StartTransaction())
{
var bt = tr.GetObject(ndb.BlockTableId, OpenMode.ForRead) as BlockTable;
var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

foreach (ObjectId id in btr)
{
var dbo = tr.GetObject(id, OpenMode.ForWrite);

if (dbo.GetType() == typeof(DBText))
{
txt = dbo as DBText;
txt.TextString = "填充文本";
var originalDatabase = HostApplicationServices.WorkingDatabase;
HostApplicationServices.WorkingDatabase = ndb;
txt.AdjustAlignment(ndb);
HostApplicationServices.WorkingDatabase = originalDatabase;
}
}
tr.Commit();
}

ndb.SaveAs("D:\\Projects\\Document3.dwg", DwgVersion.Current);
ndb.Dispose();
}
}微信图片_20230515154643.png微信图片_20230515154726.png

I borrowed from previous posts:

https://forums.autodesk.com/t5/net/attrubute-text-alignment-problem-after-update/m-p/2624675#M17532

https://forums.autodesk.com/t5/net/wrong-justification-of-dbtext-in-block/m-p/9401872/highlight/fals...

https://forums.autodesk.com/t5/net/c-dbtext-alignment-error-when-openning-readdwgfile-method-have/m-...

use code:

var originalDatabase = HostApplicationServices.WorkingDatabase;
HostApplicationServices.WorkingDatabase = ndb;
txt.AdjustAlignment(ndb);
HostApplicationServices.WorkingDatabase = originalDatabase;

no success

Must the DWG file be opened in a viewport to take effect?

0 Likes
Accepted solutions (1)
1,315 Views
8 Replies
Replies (8)
Message 2 of 9

norman.yuan
Mentor
Mentor

Well, I would try to set WorkingDatabase BEFORE starting the Transaction:

using (ndb=new Database(false, true))
{
  ndb.ReadDwgFile(...);
  var originalDatabase=HostApplicationServices.WorkingDatabase;
  using (var tr = ndb.TransactionManager.StartTransaction()
  {
    ...
    tr.Commit();
  }
  HostApplicationServices.WorkingDatabase=originalDatabase
  ndb.SaveAs(...)
}

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 9

a932994040
Participant
Participant

I followed your method to try to set WorkingDatabase BEFORE starting the Transaction

original document:

企业微信截图_16841977255099.png

After program execution:

企业微信截图_1684197796122.png

Manual movement:

企业微信截图_1684197862947.png

 

using (var docLock = document.LockDocument())
{
	using(var ndb = new Database(false, true))
	{
		ndb.ReadDwgFile("D:\\Projects\\Document3.dwg", FileShare.ReadWrite, true, "");
		var originalDatabase = HostApplicationServices.WorkingDatabase;
		using (Transaction tr = ndb.TransactionManager.StartTransaction())
		{
			var bt = tr.GetObject(ndb.BlockTableId, OpenMode.ForRead) as BlockTable;
			var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

			foreach (ObjectId id in btr)
			{
				var dbo = tr.GetObject(id, OpenMode.ForWrite);

				if (dbo.GetType() == typeof(DBText))
				{
					txt.SetDatabaseDefaults(ndb);
					txt = dbo as DBText;
					txt.TextString = "红旗H平台";
					
					HostApplicationServices.WorkingDatabase = ndb;
					txt.AdjustAlignment(ndb);
					
				}
			}
			tr.Commit();
		}
		HostApplicationServices.WorkingDatabase = originalDatabase;

		ndb.SaveAs("D:\\Projects\\Document3.dwg", DwgVersion.Current);
		ndb.Dispose();
	}
}

 

 

 

 

0 Likes
Message 4 of 9

Miralkong
Advocate
Advocate
Accepted solution

Hi, in my test, I found that if you set the command flag to CommandFlags.Session, it works well. The sample code is as below:

[CommandMethod("test",CommandFlags.Session)]
        public void Test()
        {
            Database sourceDb = new Database(false, true);
            sourceDb.ReadDwgFile("Your dwg file path", System.IO.FileShare.ReadWrite, true, "");
            sourceDb.CloseInput(true);

            var originalDb = HostApplicationServices.WorkingDatabase;

            using (Transaction acTrans = sourceDb.TransactionManager.StartOpenCloseTransaction())
            {
                HostApplicationServices.WorkingDatabase = sourceDb;

                BlockTable acBlkTbl = acTrans.GetObject(sourceDb.BlockTableId, OpenMode.ForWrite) as BlockTable;
                BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                
                foreach (ObjectId id in acBlkTblRec)
                {
                    DBObject obj = acTrans.GetObject(id, OpenMode.ForWrite);
                    if (obj.GetType() != typeof(DBText))
                        continue;
                    DBText txt = (DBText)obj;
                    txt.TextString = "Change text from dll";
                    txt.Height = 5000;
                    txt.WidthFactor = 5;
                    txt.Justify = AttachmentPoint.MiddleCenter;
                    txt.AlignmentPoint = txt.Position;
                }

                acTrans.Commit();
            }

            HostApplicationServices.WorkingDatabase = originalDb;

            sourceDb.SaveAs("Your dwg file path", DwgVersion.Current);
            sourceDb.Dispose();
        }
Message 5 of 9

a932994040
Participant
Participant
Thanks! That was it.
0 Likes
Message 6 of 9

a932994040
Participant
Participant

Hello, I want to replicate a BlockReference and modify the TextString attribute value of AttributeReference in the replicated BlockReference。I applied the same method to AttributeReference, but the position did not refresh。Could you please guide me again? Thank you very much!

 

[CommandMethod("test", CommandFlags.Session)]
public void Test()
{
	Database sourceDb = new Database(false, true);
	sourceDb.ReadDwgFile("D:\\Projects\\Document2.dwg", System.IO.FileShare.ReadWrite, true, "");
	sourceDb.CloseInput(true);

	var originalDb = HostApplicationServices.WorkingDatabase;

	using (Transaction acTrans = sourceDb.TransactionManager.StartOpenCloseTransaction())
	{
		HostApplicationServices.WorkingDatabase = sourceDb;

		BlockReference block = null;

		BlockTable acBlkTbl = acTrans.GetObject(sourceDb.BlockTableId, OpenMode.ForWrite) as BlockTable;
		BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

		foreach (ObjectId id in acBlkTblRec)
		{
			DBObject obj = acTrans.GetObject(id, OpenMode.ForWrite);
			if (obj.GetType() != typeof(BlockReference))
				continue;
			block = (BlockReference)obj;
		}

		var point = new Point3d(block.Position.X + 260, block.Position.Y, block.Position.Z);
		var mt = Matrix3d.Displacement(point - block.Position);
		var nbr = block.GetTransformedCopy(mt) as BlockReference;
		acBlkTblRec.AppendEntity(nbr);
		acTrans.AddNewlyCreatedDBObject(nbr, true);

		foreach (ObjectId id in nbr.AttributeCollection)
		{
			var nbr_ar = acTrans.GetObject(id, OpenMode.ForWrite) as AttributeReference;

			switch (nbr_ar.Tag)
			{
				case "厂项名称":
					nbr_ar.TextString = "红旗H平台";
					break;

				case "图纸名称":
					nbr_ar.TextString = "蜡烘干室";
					break;
				case "图纸编号":
					nbr_ar.TextString = "FH866";
					break;

				case "年":
					nbr_ar.TextString = "2023";
					break;

				case "月":
					nbr_ar.TextString = "5";
					break;
			}

			nbr_ar.AdjustAlignment(sourceDb);
		}

		acTrans.Commit();
	}

	HostApplicationServices.WorkingDatabase = originalDb;

	sourceDb.SaveAs("D:\\Projects\\Document2.dwg", DwgVersion.Current);
	sourceDb.Dispose();
}

 

 

企业微信截图_1684289313190.png

 

0 Likes
Message 7 of 9

a932994040
Participant
Participant

Hello, I have reviewed the post about updating attribute references but have not found a solution. Can you help me?
0 Likes
Message 8 of 9

a932994040
Participant
Participant
I refer to other similar solutions, which are all copying the AttributeDefinition of the original BlockReference and recreating the BlockReference before adding a new AttributeDefinition;
0 Likes
Message 9 of 9

Miralkong
Advocate
Advocate

Hi. The reason why you did't get a correct result is that you should call "attsync" method after you change the contents of an attribute block. However, if you are working with a side database, you probably can't use Editor.Command("_attsync ", "_name ", "your block name"). Another way you could try is to create a new block reference other than copying one and editing its value. Another thing to say here, the method you used in your code to get the attribute block can only work on the circumstance that you only have one block in your drawing. You should use more general ways to do it. Below is a sample that works on my computer.

[CommandMethod("test", CommandFlags.Session)]
        public void Test()
        {
            Database sourceDb = new Database(false, true);
            sourceDb.ReadDwgFile(@"C:\Users\MiralKong\Desktop\Document2.dwg", System.IO.FileShare.ReadWrite, true, "");
            sourceDb.CloseInput(true);

            using (Transaction acTrans = sourceDb.TransactionManager.StartOpenCloseTransaction())
            {
                string attBlkName = "汇总封面块";

                BlockTable acBlkTbl = acTrans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                
                Point3d insertPt = new Point3d();
                foreach (ObjectId id in acBlkTblRec)
                {
                    BlockReference origin = acTrans.GetObject(id, OpenMode.ForRead) as BlockReference;
                    if(origin!=null && origin.Name == attBlkName)
                    {
                        insertPt = origin.Position;
                        break;
                    }
                }
                insertPt = new Point3d(insertPt.X + 260, insertPt.Y, insertPt.Z);                

                if (!acBlkTbl.Has(attBlkName))
                {
                    return;
                }
              
                BlockTableRecord attBlkTblRec = acTrans.GetObject(acBlkTbl[attBlkName], OpenMode.ForRead) as BlockTableRecord;

                using (BlockReference acBlkRef = new BlockReference(insertPt, attBlkTblRec.ObjectId))
                {
                    acBlkTblRec.AppendEntity(acBlkRef);
                    acTrans.AddNewlyCreatedDBObject(acBlkRef, true);

                    foreach (ObjectId id in attBlkTblRec)
                    {                       
                        DBObject dBObject = acTrans.GetObject(id, OpenMode.ForWrite);
                        AttributeDefinition attDef = dBObject as AttributeDefinition;
                        
                        if (attDef != null && !attDef.Constant)
                        {
                            using (AttributeReference attRef = new AttributeReference())
                            {
                                attRef.SetAttributeFromBlock(attDef, acBlkRef.BlockTransform);
                                switch (attDef.Tag)
                                {
                                    case "厂项名称":
                                        attDef.TextString = "红旗H平台";
                                        break;
                                    case "图纸名称":
                                        attDef.TextString = "蜡烘干室";
                                        break;
                                    case "图纸编号":
                                        attDef.TextString = "FH866";
                                        break;
                                    case "年":
                                        attDef.TextString = "2023";
                                        break;
                                    case "月":
                                        attDef.TextString = "5";
                                        break;
                                }
                                acBlkRef.AttributeCollection.AppendAttribute(attRef);
                                acTrans.AddNewlyCreatedDBObject(attRef, true);
                            }
                        }
                    }
                }
                acTrans.Commit();
            }

            sourceDb.SaveAs(@"C:\Users\MiralKong\Desktop\Document2.dwg", DwgVersion.Current);
            sourceDb.Dispose();
        }
0 Likes