找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3581|回复: 4

[分享] Jigging an AutoCAD block with attributes using .NET

[复制链接]

已领礼包: 1268个

财富等级: 财源广进

发表于 2013-8-22 15:14:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Jigging an AutoCAD block with attributes using .NET



Thanks, once again, to Philippe Leefsma, a DevTech engineer based in Prague, for contributing the code for this post. While researching an issue he was working on Philippe stumbled across a comment on this previous post where I more-or-less said jigging attributes wasn’t possible. Ahem. Anyway, Philippe decided to – quite rightly – prove me wrong, and the result is today’s post. :-)

It turns out that the trick to jigging a block with attributes is to add the block reference to the database prior to running the jig. I’d been coming at this from another direction – working out how to call through to the right version of the ObjectARX function, the one that allows the block reference to be in-memory rather than db-resident – but Philippe’s approach means that’s no longer needed. I see this technique as potentially being useful when jigging other entities that benefit from being database resident (Solid3d objects spring to mind), so I really appreciate Philippe’s hard work on this.

Here’s the C# code which I’ve edited for posting:
  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using System.Collections.Generic;



  7. namespace BlockJig
  8. {
  9.   class CBlockJig : EntityJig
  10.   {
  11.     private Point3d _pos;
  12.     private Dictionary<string, Point3d> _attPos;
  13.     private Transaction _tr;

  14.     public CBlockJig(Transaction tr, BlockReference br)
  15.       : base(br)
  16.     {
  17.       _pos = br.Position;

  18.       // Initialize our dictionary with the tag /
  19.       // AttributeDefinition position

  20.       _attPos = new Dictionary<string, Point3d>();

  21.       _tr = tr;

  22.       BlockTableRecord btr =
  23.         (BlockTableRecord)_tr.GetObject(
  24.           br.BlockTableRecord,
  25.           OpenMode.ForRead
  26.         );

  27.       if (btr.HasAttributeDefinitions)
  28.       {
  29.         foreach (ObjectId id in btr)
  30.         {
  31.           DBObject obj =
  32.             tr.GetObject(id, OpenMode.ForRead);
  33.           AttributeDefinition ad =
  34.             obj as AttributeDefinition;

  35.           if (ad != null)
  36.           {
  37.             _attPos.Add(ad.Tag, ad.Position);
  38.           }
  39.         }
  40.       }
  41.    }

  42.     protected override bool Update()
  43.     {
  44.       BlockReference br = Entity as BlockReference;
  45.       br.Position = _pos;
  46.       if (br.AttributeCollection.Count != 0)
  47.       {
  48.         foreach (ObjectId id in br.AttributeCollection)
  49.         {
  50.           DBObject obj =
  51.             _tr.GetObject(id, OpenMode.ForRead);
  52.           AttributeReference ar =
  53.             obj as AttributeReference;

  54.           // Apply block transform to att def position

  55.           if (ar != null)
  56.           {
  57.             ar.UpgradeOpen();
  58.             ar.Position =
  59.               _attPos[ar.Tag].TransformBy(br.BlockTransform);
  60.           }
  61.         }
  62.       }
  63.       return true;
  64.     }


  65.     protected override SamplerStatus Sampler(JigPrompts prompts)
  66.     {
  67.       JigPromptPointOptions opts =
  68.         new JigPromptPointOptions("\nSelect insertion point:");
  69.       opts.BasePoint = new Point3d(0, 0, 0);
  70.       opts.UserInputControls =
  71.         UserInputControls.NoZeroResponseAccepted;
  72.       PromptPointResult ppr = prompts.AcquirePoint(opts);

  73.       if (_pos == ppr.Value)
  74.       {
  75.         return SamplerStatus.NoChange;
  76.       }
  77.       _pos = ppr.Value;
  78.       return SamplerStatus.OK;
  79.     }

  80.     public PromptStatus Run()
  81.     {
  82.       Document doc =
  83.         Application.DocumentManager.MdiActiveDocument;
  84.       Editor ed = doc.Editor;
  85.       PromptResult promptResult = ed.Drag(this);
  86.       return promptResult.Status;
  87.     }
  88.   }

  89.   public class Commands
  90.   {
  91.     [CommandMethod("BJ")]
  92.     static public void BlockJig()
  93.     {
  94.       Document doc =
  95.         Application.DocumentManager.MdiActiveDocument;
  96.       Database db = doc.Database;
  97.       Editor ed = doc.Editor;
  98.       PromptStringOptions pso =
  99.         new PromptStringOptions("\nEnter block name: ");
  100.       PromptResult pr = ed.GetString(pso);

  101.       if (pr.Status != PromptStatus.OK)
  102.         return;

  103.       Transaction tr =
  104.         doc.TransactionManager.StartTransaction();
  105.       using (tr)
  106.       {
  107.         BlockTable bt =
  108.           (BlockTable)tr.GetObject(
  109.             db.BlockTableId,
  110.             OpenMode.ForRead
  111.           );
  112.         BlockTableRecord space =
  113.           (BlockTableRecord)tr.GetObject(
  114.             db.CurrentSpaceId,
  115.             OpenMode.ForRead
  116.           );

  117.         if (!bt.Has(pr.StringResult))
  118.         {
  119.           ed.WriteMessage(
  120.             "\nBlock \"" + pr.StringResult + "\" not found.");
  121.           return;
  122.         }

  123.         space.UpgradeOpen();

  124.         BlockTableRecord btr =
  125.           (BlockTableRecord)tr.GetObject(
  126.             bt[pr.StringResult],
  127.             OpenMode.ForRead);

  128.         // Block needs to be inserted to current space before
  129.         // being able to append attribute to it

  130.         BlockReference br =
  131.           new BlockReference(new Point3d(), btr.ObjectId);
  132.         space.AppendEntity(br);
  133.         tr.AddNewlyCreatedDBObject(br, true);

  134.         if (btr.HasAttributeDefinitions)
  135.         {
  136.           foreach (ObjectId id in btr)
  137.           {
  138.             DBObject obj =
  139.               tr.GetObject(id, OpenMode.ForRead);
  140.             AttributeDefinition ad =
  141.               obj as AttributeDefinition;

  142.             if (ad != null && !ad.Constant)
  143.             {

  144.               AttributeReference ar =
  145.                 new AttributeReference();
  146.               ar.SetAttributeFromBlock(ad, br.BlockTransform);
  147.               ar.Position =
  148.                 ad.Position.TransformBy(br.BlockTransform);
  149.               ar.TextString = ad.TextString;
  150.               br.AttributeCollection.AppendAttribute(ar);
  151.               tr.AddNewlyCreatedDBObject(ar, true);
  152.             }
  153.           }
  154.         }

  155.         // Run the jig

  156.         CBlockJig myJig = new CBlockJig(tr, br);

  157.         if (myJig.Run() != PromptStatus.OK)
  158.           return;

  159.         // Commit changes if user accepted, otherwise discard

  160.         tr.Commit();
  161.       }
  162.     }
  163.   }
  164. }

When you run the BJ command (short for BlockJig) and specify the name of a block in the current drawing which contains attributes, you’ll now see the attributes with their default values shown as part of the block being jigged. Implementing the code to allow editing of those attributes after insertion is left as an exercise for the reader.

Update:

This code didn't work for a few situations, such as when using justification (attributes would end up at the origin after being dragged) or with MText attributes (which would start at the origin until the mouse was moved).

A big thanks to Roland Feletic from PAUSER ZT-GMBH for helping identify and diagnose the various cases.

Here's the updated C# code:

  1. using Autodesk.AutoCAD.Runtime;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using System.Collections.Generic;

  7. namespace BlockJigApplication
  8. {
  9.   class AttInfo
  10.   {
  11.     private Point3d _pos;
  12.     private Point3d _aln;
  13.     private bool _aligned;

  14.     public AttInfo(Point3d pos, Point3d aln, bool aligned)
  15.     {
  16.       _pos = pos;
  17.       _aln = aln;
  18.       _aligned = aligned;
  19.     }

  20.     public Point3d Position
  21.     {
  22.       set { _pos = value; }
  23.       get { return _pos; }
  24.     }

  25.     public Point3d Alignment
  26.     {
  27.       set { _aln = value; }
  28.       get { return _aln; }
  29.     }

  30.     public bool IsAligned
  31.     {
  32.       set { _aligned = value; }
  33.       get { return _aligned; }
  34.     }
  35.   }

  36.   class BlockJig : EntityJig
  37.   {
  38.     private Point3d _pos;
  39.     private Dictionary<ObjectId, AttInfo> _attInfo;
  40.     private Transaction _tr;

  41.     public BlockJig(
  42.       Transaction tr,
  43.       BlockReference br,
  44.       Dictionary<ObjectId, AttInfo> attInfo
  45.     ) : base(br)
  46.     {
  47.       _pos = br.Position;
  48.       _attInfo = attInfo;
  49.       _tr = tr;
  50.     }

  51.     protected override bool Update()
  52.     {
  53.       BlockReference br = Entity as BlockReference;
  54.       br.Position = _pos;

  55.       if (br.AttributeCollection.Count != 0)
  56.       {
  57.         foreach (ObjectId id in br.AttributeCollection)
  58.         {
  59.           DBObject obj =
  60.             _tr.GetObject(id, OpenMode.ForRead);
  61.           AttributeReference ar =
  62.             obj as AttributeReference;

  63.           // Apply block transform to att def position

  64.           if (ar != null)
  65.           {
  66.             ar.UpgradeOpen();
  67.             AttInfo ai = _attInfo[ar.ObjectId];
  68.             ar.Position =
  69.               ai.Position.TransformBy(br.BlockTransform);
  70.             if (ai.IsAligned)
  71.             {
  72.               ar.AlignmentPoint =
  73.                 ai.Alignment.TransformBy(br.BlockTransform);
  74.             }
  75.             if (ar.IsMTextAttribute)
  76.             {
  77.               ar.UpdateMTextAttribute();
  78.             }
  79.           }
  80.         }
  81.       }
  82.       return true;
  83.     }

  84.     protected override SamplerStatus Sampler(JigPrompts prompts)
  85.     {
  86.       JigPromptPointOptions opts =
  87.         new JigPromptPointOptions("\nSelect insertion point:");
  88.       opts.BasePoint = new Point3d(0, 0, 0);
  89.       opts.UserInputControls =
  90.         UserInputControls.NoZeroResponseAccepted;
  91.       PromptPointResult ppr = prompts.AcquirePoint(opts);

  92.       if (_pos == ppr.Value)
  93.       {
  94.         return SamplerStatus.NoChange;
  95.       }
  96.       _pos = ppr.Value;
  97.       return SamplerStatus.OK;
  98.     }

  99.     public PromptStatus Run()
  100.     {
  101.       Document doc =
  102.         Application.DocumentManager.MdiActiveDocument;
  103.       Editor ed = doc.Editor;
  104.       PromptResult promptResult = ed.Drag(this);
  105.       return promptResult.Status;
  106.     }
  107.   }

  108.   public class Commands
  109.   {
  110.     [CommandMethod("BJ")]
  111.     static public void BlockJigCmd()
  112.     {
  113.       Document doc =
  114.         Application.DocumentManager.MdiActiveDocument;
  115.       Database db = doc.Database;
  116.       Editor ed = doc.Editor;
  117.       PromptStringOptions pso =
  118.         new PromptStringOptions("\nEnter block name: ");
  119.       PromptResult pr = ed.GetString(pso);
  120.       if (pr.Status != PromptStatus.OK)
  121.         return;
  122.       Transaction tr =
  123.         doc.TransactionManager.StartTransaction();
  124.       using (tr)
  125.       {
  126.         BlockTable bt =
  127.           (BlockTable)tr.GetObject(
  128.             db.BlockTableId,
  129.             OpenMode.ForRead
  130.           );

  131.         if (!bt.Has(pr.StringResult))
  132.         {
  133.           ed.WriteMessage(
  134.             "\nBlock \"" + pr.StringResult + "\" not found.");
  135.           return;
  136.         }

  137.         BlockTableRecord space =
  138.           (BlockTableRecord)tr.GetObject(
  139.             db.CurrentSpaceId,
  140.             OpenMode.ForWrite
  141.           );

  142.         BlockTableRecord btr =
  143.           (BlockTableRecord)tr.GetObject(
  144.             bt[pr.StringResult],
  145.             OpenMode.ForRead);

  146.         // Block needs to be inserted to current space before
  147.         // being able to append attribute to it

  148.         BlockReference br =
  149.           new BlockReference(new Point3d(), btr.ObjectId);
  150.         space.AppendEntity(br);
  151.         tr.AddNewlyCreatedDBObject(br, true);
  152.         Dictionary<ObjectId, AttInfo> attInfo =
  153.           new Dictionary<ObjectId,AttInfo>();

  154.         if (btr.HasAttributeDefinitions)
  155.         {
  156.           foreach (ObjectId id in btr)
  157.           {
  158.             DBObject obj =
  159.               tr.GetObject(id, OpenMode.ForRead);
  160.             AttributeDefinition ad =
  161.               obj as AttributeDefinition;
  162.             if (ad != null && !ad.Constant)
  163.             {
  164.               AttributeReference ar =
  165.                 new AttributeReference();
  166.               ar.SetAttributeFromBlock(ad, br.BlockTransform);
  167.               ar.Position =
  168.                 ad.Position.TransformBy(br.BlockTransform);
  169.               if (ad.Justify != AttachmentPoint.BaseLeft)
  170.               {
  171.                 ar.AlignmentPoint =
  172.                   ad.AlignmentPoint.TransformBy(br.BlockTransform);
  173.               }
  174.               if (ar.IsMTextAttribute)
  175.               {
  176.                 ar.UpdateMTextAttribute();
  177.               }
  178.               ar.TextString = ad.TextString;
  179.               ObjectId arId =
  180.                 br.AttributeCollection.AppendAttribute(ar);
  181.               tr.AddNewlyCreatedDBObject(ar, true);

  182.               // Initialize our dictionary with the ObjectId of
  183.               // the attribute reference + attribute definition info

  184.               attInfo.Add(
  185.                 arId,
  186.                 new AttInfo(
  187.                   ad.Position,
  188.                   ad.AlignmentPoint,
  189.                   ad.Justify != AttachmentPoint.BaseLeft
  190.                 )
  191.               );
  192.             }
  193.           }
  194.         }

  195.         // Run the jig

  196.         BlockJig myJig = new BlockJig(tr, br, attInfo);

  197.         if (myJig.Run() != PromptStatus.OK)
  198.           return;

  199.         // Commit changes if user accepted, otherwise discard

  200.         tr.Commit();
  201.       }
  202.     }
  203.   }
  204. }

A few comments on this code:
&#8226;It's been refactored to make a single pass through the block definition to both create the block reference and collect the attribute information to store in our dictionary.
&#8226;The attribute information is now held in a class, which allows us to store more than just the position in our dictionary (without using multiple dictionaries), I went to the effort of exposing public properties for the various private members, as this is generally a good technique to use (if a little redundant, here).
&#8226;The dictionary now stores this attribute information against an ObjectId rather than the tag string. Roland made the excellent point that blocks can contain attributes with duplicate tags, so this is much safe. We also had to use the ObjectId of the AttributeReference, as later on inside the jig's Update() function we no longer have access to the AttributeDefinition.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-8-22 15:21:17 | 显示全部楼层
  1. using System.Collections.Generic;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application;

  7. namespace AcadNetAddinWizard_Namespace
  8. {
  9.     public class BlockAttributeJig : EntityJig
  10.     {
  11.         #region Fields

  12.         private int mCurJigFactorNumber = 1;
  13.         private double mAngleOffset = 0.0;
  14.         private Point3d mPosition = new Point3d(0,0,0); // Factor #1
  15.         private double mRotation = 0.0;                 // Factor #2
  16.         private double mScaleFactor = 1.0;              // Factor #3
  17.         private Dictionary<AttributeReference, AttributeDefinition> mRef2DefMap;

  18.         #endregion

  19.         #region Constructors

  20.         public BlockAttributeJig(BlockReference ent, Dictionary<AttributeReference, AttributeDefinition> dict)
  21.             : base(ent)
  22.         {
  23.             mAngleOffset = ent.Rotation;
  24.             mRef2DefMap = dict;
  25.         }

  26.         #endregion

  27.         #region Properties

  28.         protected static Matrix3d UCS
  29.         {
  30.             get
  31.             {
  32.                 return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
  33.             }
  34.         }

  35.         protected new BlockReference Entity
  36.         {
  37.             get
  38.             {
  39.                 return (BlockReference)base.Entity;
  40.             }
  41.         }

  42.         #endregion

  43.         #region Overrides

  44.         protected override bool Update()
  45.         {
  46.             switch (mCurJigFactorNumber)
  47.             {
  48.                 case 1:
  49.                     Entity.Position = mPosition.TransformBy(UCS);
  50.                     break;
  51.                 case 2:
  52.                     Entity.Rotation = mRotation + mAngleOffset; ;
  53.                     break;
  54.                 case 3:
  55.                     Entity.ScaleFactors = new Scale3d(mScaleFactor);
  56.                     break;
  57.                 default:
  58.                     break;
  59.             }

  60.             foreach (KeyValuePair<AttributeReference, AttributeDefinition> ar2ad in mRef2DefMap)
  61.             {
  62.                 string value = ar2ad.Key.TextString;
  63.                 ar2ad.Key.SetAttributeFromBlock(ar2ad.Value, Entity.BlockTransform);
  64.                 ar2ad.Key.TextString = value;
  65.                 ar2ad.Key.XData = ar2ad.Value.XData;
  66.                 ar2ad.Key.AdjustAlignment(Entity.Database);
  67.             }

  68.             return true;
  69.         }

  70.         protected override SamplerStatus Sampler(JigPrompts prompts)
  71.         {
  72.             switch (mCurJigFactorNumber)
  73.             {
  74.                 case 1:
  75.                     JigPromptPointOptions prOptions1 = new JigPromptPointOptions("\nBlock insertion point:");
  76.                     PromptPointResult prResult1 = prompts.AcquirePoint(prOptions1);
  77.                     if (prResult1.Status == PromptStatus.Cancel)
  78.                         return SamplerStatus.Cancel;

  79.                     Point3d tempPt = prResult1.Value.TransformBy(UCS.Inverse());
  80.                     if (tempPt.IsEqualTo(mPosition))
  81.                     {
  82.                         return SamplerStatus.NoChange;
  83.                     }
  84.                     else
  85.                     {
  86.                         mPosition = tempPt;
  87.                         return SamplerStatus.OK;
  88.                     }
  89.                 case 2:
  90.                     JigPromptAngleOptions prOptions2 = new JigPromptAngleOptions("\nBlock rotation angle:");
  91.                     prOptions2.BasePoint = mPosition.TransformBy(UCS);
  92.                     prOptions2.UseBasePoint = true;
  93.                     PromptDoubleResult prResult2 = prompts.AcquireAngle(prOptions2);
  94.                     if (prResult2.Status == PromptStatus.Cancel)
  95.                         return SamplerStatus.Cancel;

  96.                     if (prResult2.Value.Equals(mRotation))
  97.                     {
  98.                         return SamplerStatus.NoChange;
  99.                     }
  100.                     else
  101.                     {
  102.                         mRotation = prResult2.Value;
  103.                         return SamplerStatus.OK;
  104.                     }
  105.                 case 3:
  106.                     JigPromptDistanceOptions prOptions3 = new JigPromptDistanceOptions("\nBlock scale factor:");
  107.                     prOptions3.BasePoint = mPosition.TransformBy(UCS);
  108.                     prOptions3.UseBasePoint = true;
  109.                     PromptDoubleResult prResult3 = prompts.AcquireDistance(prOptions3);
  110.                     if (prResult3.Status == PromptStatus.Cancel)
  111.                         return SamplerStatus.Cancel;

  112.                     if (prResult3.Value.Equals(mScaleFactor))
  113.                     {
  114.                         return SamplerStatus.NoChange;
  115.                     }
  116.                     else
  117.                     {
  118.                         mScaleFactor = prResult3.Value;
  119.                         return SamplerStatus.OK;
  120.                     }
  121.                 default:
  122.                     break;
  123.             }

  124.             return SamplerStatus.OK;
  125.         }

  126.         #endregion

  127.         #region Method to Call

  128.         public static bool Jig(BlockReference ent, Dictionary<AttributeReference, AttributeDefinition> dict)
  129.         {
  130.             try
  131.             {
  132.                 Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
  133.                 BlockAttributeJig jigger = new BlockAttributeJig(ent, dict);
  134.                 PromptResult pr;
  135.                 do
  136.                 {
  137.                     pr = ed.Drag(jigger);
  138.                 } while (pr.Status != PromptStatus.Cancel && pr.Status != PromptStatus.Error && jigger.mCurJigFactorNumber++ <= 3);

  139.                 return pr.Status == PromptStatus.OK;
  140.             }
  141.             catch
  142.             {
  143.                 return false;
  144.             }
  145.         }

  146.         public static string CollectAttributeText(AttributeDefinition attDef)
  147.         {
  148.             string ret = string.Empty;

  149.             PromptStringOptions prStrOpt = new PromptStringOptions("");
  150.             prStrOpt.AllowSpaces = true;
  151.             prStrOpt.DefaultValue = attDef.TextString;
  152.             prStrOpt.UseDefaultValue = true;
  153.             prStrOpt.Message = attDef.Prompt;
  154.             PromptResult pr = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.GetString(prStrOpt);
  155.             if (pr.Status == PromptStatus.OK)
  156.             {
  157.                 ret = pr.StringResult;
  158.             }

  159.             return ret;
  160.         }

  161.         #endregion

  162.         #region Test Command

  163.         [CommandMethod("BlockAttributeJig")]
  164.         public static void BlockAttributeJig_Method()
  165.         {
  166.             Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
  167.             Database db = HostApplicationServices.WorkingDatabase;
  168.             try
  169.             {
  170.                 PromptResult pr = ed.GetString("\nBlock name:");
  171.                 if (pr.Status == PromptStatus.OK)
  172.                 {
  173.                     using (Transaction tr = db.TransactionManager.StartTransaction())
  174.                     {
  175.                         BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  176.                         BlockTableRecord btr = tr.GetObject(bt[pr.StringResult], OpenMode.ForRead) as BlockTableRecord;
  177.                         if (btr != null)
  178.                         {
  179.                             BlockReference ent = new BlockReference(new Point3d(0, 0, 0), btr.ObjectId);
  180.                             ent.TransformBy(UCS);
  181.                             BlockTableRecord modelspace = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  182.                             modelspace.AppendEntity(ent);
  183.                             tr.AddNewlyCreatedDBObject(ent, true);

  184.                             if (btr.Annotative == AnnotativeStates.True)
  185.                             {
  186.                                 ObjectContextManager ocm = db.ObjectContextManager;
  187.                                 ObjectContextCollection occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
  188.                                 ent.AddContext(occ.CurrentContext);
  189.                             }

  190.                             Dictionary<AttributeReference, AttributeDefinition> dict = new Dictionary<AttributeReference, AttributeDefinition>();
  191.                             if (btr.HasAttributeDefinitions)
  192.                             {
  193.                                 RXClass rxClass = RXClass.GetClass(typeof(AttributeDefinition));
  194.                                 foreach (ObjectId id in btr)
  195.                                 {
  196.                                     if (id.ObjectClass == rxClass)
  197.                                     {
  198.                                         DBObject obj = tr.GetObject(id, OpenMode.ForRead);

  199.                                         AttributeDefinition ad = obj as AttributeDefinition;
  200.                                         AttributeReference ar = new AttributeReference();
  201.                                         ar.SetAttributeFromBlock(ad, ent.BlockTransform);
  202.                                         ar.TextString = CollectAttributeText(ad);

  203.                                         ent.AttributeCollection.AppendAttribute(ar);
  204.                                         tr.AddNewlyCreatedDBObject(ar, true);

  205.                                         dict.Add(ar, ad);
  206.                                     }
  207.                                 }
  208.                             }

  209.                             if (BlockAttributeJig.Jig(ent, dict))
  210.                             {
  211.                                 tr.Commit();
  212.                             }
  213.                             else
  214.                             {
  215.                                 ent.Dispose();
  216.                                 foreach (KeyValuePair<AttributeReference, AttributeDefinition> entry in dict)
  217.                                 {
  218.                                     ent.Dispose();
  219.                                 }
  220.                                 tr.Abort();
  221.                             }
  222.                         }
  223.                     }
  224.                 }
  225.             }
  226.             catch (Exception ex)
  227.             {
  228.                 ed.WriteMessage(ex.Message);
  229.             }
  230.         }

  231.         #endregion

  232.     }
  233. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1268个

财富等级: 财源广进

 楼主| 发表于 2013-8-22 15:22:24 | 显示全部楼层
   
  1. private static void ApplyAttibutes(Database db, Transaction tr, BlockReference bref, List<string> listTags, List<string> listValues)
  2.         {
  3.             BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead);

  4.             foreach (ObjectId attId in btr)
  5.             {
  6.                 Entity ent = (Entity)tr.GetObject(attId, OpenMode.ForRead);
  7.                 if (ent is AttributeDefinition)
  8.                 {
  9.                     AttributeDefinition attDef = (AttributeDefinition)ent;
  10.                     AttributeReference attRef = new AttributeReference();

  11.                     attRef.SetAttributeFromBlock(attDef, bref.BlockTransform);
  12.                     bref.AttributeCollection.AppendAttribute(attRef);
  13.                     tr.AddNewlyCreatedDBObject(attRef, true);
  14.                     if (listTags.Contains(attDef.Tag))
  15.                     {
  16.                         int found = listTags.BinarySearch(attDef.Tag);
  17.                         if (found >= 0)
  18.                         {
  19.                             attRef.TextString = listValues[found];
  20.                             attRef.AdjustAlignment(db);
  21.                         }
  22.                     }

  23.                 }
  24.             }
  25.         }

  26.         [CommandMethod("iab")]
  27.         public static void testAttributedBlockInsert()
  28.         {
  29.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  30.             Database db = doc.Database;
  31.             Editor ed = doc.Editor;
  32.             // change block name to your suit
  33.             string blockName = "UserName";
  34.             Matrix3d ucs = ed.CurrentUserCoordinateSystem;
  35.             //get current UCS matrix
  36.             try
  37.             {
  38.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  39.                 {
  40.                     // to force update drawing screen
  41.                     doc.TransactionManager.EnableGraphicsFlush(true);
  42.                     BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);

  43.                     // if the block table doesn't already exists, exit
  44.                     if (!bt.Has(blockName))
  45.                     {
  46.                         Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Block " + blockName + " does not exist.");
  47.                         return;
  48.                     }

  49.                     // insert the block in the current space
  50.                     PromptPointResult ppr = ed.GetPoint("\nSpecify insertion point: ");
  51.                     if (ppr.Status != PromptStatus.OK)
  52.                     {
  53.                         return;
  54.                     }

  55.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  56.                     ObjectContextCollection occ = db.ObjectContextManager.GetContextCollection("ACDB_ANNOTATIONSCALES");

  57.                     Point3d pt = ppr.Value;
  58.                     BlockReference bref = new BlockReference(pt, bt[blockName]);
  59.                     bref.TransformBy(ucs);
  60.                     bref.AddContext(occ.CurrentContext);

  61.                     //add blockreference to current space
  62.                     btr.AppendEntity(bref);
  63.                     tr.AddNewlyCreatedDBObject(bref, true);
  64.                     // set attributes to desired values
  65.                     ApplyAttibutes(db, tr, bref, new List<string>(new string[] {
  66.                                         "TAG1",
  67.                                         "TAG2",
  68.                                         "TAG3",
  69.                                         "TAG4"
  70.                                 }), new List<string>(new string[] {
  71.                                         "Value #1",
  72.                                         "Value #2",
  73.                                         "Value #3",
  74.                                         "Value #4"
  75.                                 }));


  76.                     bref.RecordGraphicsModified(true);
  77.                     // to force updating a block reference
  78.                     tr.TransactionManager.QueueForGraphicsFlush();
  79.                     tr.Commit();
  80.                 }
  81.             }
  82.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  83.             {
  84.                 Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message);
  85.             }
  86.             finally
  87.             {
  88.                 // Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Pokey")
  89.             }
  90.         }

评分

参与人数 1D豆 +5 收起 理由
ScmTools + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1632个

财富等级: 堆金积玉

发表于 2013-8-22 20:06:37 | 显示全部楼层
好贴必须支持
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2014-4-3 09:37:27 | 显示全部楼层
英文的就是好,顶你!
{:soso_e134:}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-21 17:33 , Processed in 0.207548 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表