原文:Creating and overriding AutoCAD dimension styles using .NET
上周末有一封电子邮件发来了一份请求::
我一直在寻找一种创建标注样式重定义的方法,但一直没有真的没有成功。我写了一个程序,在程序中我创建了几个标注样式,但是总是会丢失标注的重定义。
这似乎是一个很好的重定义话题,所以这篇文章包含一些简单的代码,创建一个样式和两个几乎相同的线性标注:都使用我们新创建的样式但第二个尺寸包含了一些尺寸样式重定义,我们通过附加扩展实体数据(xData)附加到尺寸上来实现这一功能
以下是C #代码:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
namespace DimStyleOverrideTest
{
public class Commands
{
[CommandMethod("ODS")]
public void OverrideDimensionStyle()
{
Database db =
HostApplicationServices.WorkingDatabase;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
// Open our dimension style table to add our
// new dimension style
DimStyleTable dst =
(DimStyleTable)tr.GetObject(
db.DimStyleTableId, OpenMode.ForWrite
);
// Create our new dimension style
DimStyleTableRecord dstr =
new DimStyleTableRecord();
dstr.Dimtad = 2;
dstr.Dimgap = 0.3;
dstr.Name = "MyStyle";
// Add it to the dimension style table
ObjectId dsId = dst.Add(dstr);
tr.AddNewlyCreatedDBObject(dstr, true);
// Now create two identical dimensions, one
// next to the other, using our dimension
// style
AlignedDimension ad1 =
new AlignedDimension(
Point3d.Origin,
new Point3d(5.0, 0.0, 0.0),
new Point3d(2.5, 2.0, 0.0),
"Standard dimension",
dsId
);
// The only thing we change is the text string
AlignedDimension ad2 =
new AlignedDimension(
new Point3d(5.0, 0.0, 0.0),
new Point3d(10.0, 0.0, 0.0),
new Point3d(7.5, 2.0, 0.0),
"Overridden dimension",
dsId
);
/*
Now we'll add dimension overrides for DIMTAD
and DIMGAP via XData
Dimension variable group codes are:
DIMPOST 3
DIMAPOST 4
DIMSCALE 40
DIMASZ 41
DIMEXO 42
DIMDLI 43
DIMEXE 44
DIMRND 45
DIMDLE 46
DIMTP 47
DIMTM 48
DIMTOL 71
DIMLIM 72
DIMTIH 73
DIMTOH 74
DIMSE1 75
DIMSE2 76
DIMTAD 77
DIMZIN 78
DIMAZIN 79
DIMTXT 140
DIMCEN 141
DIMTSZ 142
DIMALTF 143
DIMLFAC 144
DIMTVP 145
DIMTFAC 146
DIMGAP 147
DIMALTRND 148
DIMALT 170
DIMALTD 171
DIMTOFL 172
DIMSAH 173
DIMTIX 174
DIMSOXD 175
DIMCLRD 176
DIMCLRE 177
DIMCLRT 178
DIMADEC 179
DIMDEC 271
DIMTDEC 272
DIMALTU 273
DIMALTTD 274
DIMAUNIT 275
DIMFRAC 276
DIMLUNIT 277
DIMDSEP 278
DIMATMOVE 279
DIMJUST 280
DIMSD1 281
DIMSD2 282
DIMTOLJ 283
DIMTZIN 284
DIMALTZ 285
DIMALTTZ 286
DIMUPT 288
DIMATFIT 289
DIMTXSTY 340
DIMLDRBLK 341
DIMBLK 342
DIMBLK1 343
DIMBLK2 344
DIMLWD 371
DIMLWE 372
Variables have different types: these can be found in
the ObjectARX Reference - search for "Dimension Style
Overrides"
*/
ResultBuffer rb =
new ResultBuffer(
new TypedValue[8]{
new TypedValue(
(int)DxfCode.ExtendedDataRegAppName, "ACAD"
),
new TypedValue(
(int)DxfCode.ExtendedDataAsciiString, "DSTYLE"
),
new TypedValue(
(int)DxfCode.ExtendedDataControlString, "{"
),
new TypedValue(
(int)DxfCode.ExtendedDataInteger16, 77 // DIMTAD
),
new TypedValue(
(int)DxfCode.ExtendedDataInteger16, 4 // Below
),
new TypedValue(
(int)DxfCode.ExtendedDataInteger16, 147 // DIMGAP
),
new TypedValue(
(int)DxfCode.ExtendedDataReal, 0.5 // Larger
),
new TypedValue(
(int)DxfCode.ExtendedDataControlString, "}"
)
}
);
// Set the XData on our object
ad2.XData = rb;
rb.Dispose();
// Now let's open the current space and add our two
// dimensions
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForWrite
);
btr.AppendEntity(ad1);
btr.AppendEntity(ad2);
tr.AddNewlyCreatedDBObject(ad1, true);
tr.AddNewlyCreatedDBObject(ad2, true);
// And commit the transaction, of course
tr.Commit();
}
}
}
}
更新
OK, I missed the obvious on this one (as does happen from time-to-time, as regular readers will by now be aware). Rather than setting the overrides directly via XData, there are handy properties belonging to the dimension’s managed interface that do this for you. Very cool. So we can reduce the code to the following:
好吧,我完全没有意识到这一明显的做法(这的确也时有会发生,普通读者现在也知道了)。与其通过直接重写XDATA,其实Dimesion的接口属性中有更方便的方法来实现。实现的方法很酷。所以我们可以减少代码如下:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
namespace DimStyleOverrideTest
{
public class Commands
{
[CommandMethod("ODS")]
public void OverrideDimensionStyle()
{
Database db =
HostApplicationServices.WorkingDatabase;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
// Open our dimension style table to add our
// new dimension style
DimStyleTable dst =
(DimStyleTable)tr.GetObject(
db.DimStyleTableId, OpenMode.ForWrite
);
// Create our new dimension style
DimStyleTableRecord dstr =
new DimStyleTableRecord();
dstr.Dimtad = 2;
dstr.Dimgap = 0.3;
dstr.Name = "MyStyle";
// Add it to the dimension style table
ObjectId dsId = dst.Add(dstr);
tr.AddNewlyCreatedDBObject(dstr, true);
// Now create two identical dimensions, one
// next to the other, using our dimension
// style
AlignedDimension ad1 =
new AlignedDimension(
Point3d.Origin,
new Point3d(5.0, 0.0, 0.0),
new Point3d(2.5, 2.0, 0.0),
"Standard dimension",
dsId
);
// The only thing we change is the text string
AlignedDimension ad2 =
new AlignedDimension(
new Point3d(5.0, 0.0, 0.0),
new Point3d(10.0, 0.0, 0.0),
new Point3d(7.5, 2.0, 0.0),
"Overridden dimension",
dsId
);
// Isn't this easier?
ad2.Dimtad = 4;
ad2.Dimgap = 0.5;
// Now let's open the current space and add our two
// dimensions
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForWrite
);
btr.AppendEntity(ad1);
btr.AppendEntity(ad2);
tr.AddNewlyCreatedDBObject(ad1, true);
tr.AddNewlyCreatedDBObject(ad2, true);
// And commit the transaction, of course
tr.Commit();
}
}
}
}