1.选择实体做成块
下面代码,让用在图上选择实体,然后把实体做成一个图块,然后插入到图上。
C#代码如下:
// 把aryId中的实体,做成一个图块.
private long MakeEntitysToBlock(
AxMxDrawXLib.AxMxDrawX mxdraw,
List<Int64> aryId
)
{
// 得到当前数据库.
MxDrawDatabase curDatabase = (MxDrawDatabase)(mxdraw.GetDatabase());
// 选择实体的最外矩形外包.
double dMinX = 0, dMinY = 0, dMaxX = 0, dMaxY = 0;
bool isFirstEnt = true;
// 遍历每个实体,计算外包。
for (int l = 0; l < aryId.Count; l++)
{
// 根据id得到实体对象.
MxDrawMcDbObject pObj = curDatabase.ObjectIdToObject(aryId[l]);
if (pObj == null)
continue;
MxDrawEntity pEnt = (MxDrawEntity)pObj;
if (pEnt == null)
continue;
// 得到实体的最小外包.
MxDrawPoint pt1Ob, pt2Ob;
pEnt.GetBoundingBox(out pt1Ob, out pt2Ob);
MxDrawPoint minPt = (MxDrawPoint)pt1Ob;
MxDrawPoint maxPt = (MxDrawPoint)pt2Ob;
if (minPt != null && maxPt != null)
{
if (isFirstEnt)
{
dMinX = minPt.x;
dMinY = minPt.y;
dMaxX = maxPt.x;
dMaxY = maxPt.y;
isFirstEnt = false;
}
else
{
if (dMinX > minPt.x)
dMinX = minPt.x;
if (dMinY > minPt.y)
dMinY = minPt.y;
if (dMaxX < maxPt.x)
dMaxX = maxPt.x;
if (dMaxY < maxPt.y)
dMaxY = maxPt.y;
}
}
}
if (isFirstEnt)
{
// 没有实体
return 0;
}
// 计算外包的中心点。
MxDrawPoint pos = new MxDrawPoint();
pos.x = dMinX + (dMaxX - dMinX) / 2.0;
pos.y = dMinY + (dMaxY - dMinY) / 2.0;
// 检查新创建的块名,在当前数据库是否已经存在.
// 得到块表.
MxDrawBlockTable blkTable = curDatabase.GetBlockTable();
// 得到当前空间的块表记录。
MxDrawBlockTableRecord curSpace = curDatabase.CurrentSpace();
String sNewBlakName;
// 添加一个匿名块,
MxDrawBlockTableRecord blkNewRec = blkTable.Add("");
// 得到系统分配的块名。
sNewBlakName = blkNewRec.Name;
// 修改新增加的块表记录的插入基点,到外包的中心点。
blkNewRec.Origin = pos;
// 遍历所有实体,把实体添加块表记录中。
for (int l = 0; l < aryId.Count; l++)
{
// 复制对象,然后添加块表记录.
blkNewRec.AddCloneEntity(aryId[l]);
// 把以前实体删除 。
MxDrawMcDbObject pObj = curDatabase.ObjectIdToObject(aryId[l]);
if (pObj == null)
continue;
pObj.Erase();
}
if (blkNewRec != null)
{
// 在当前空间中,创建一个块引对象,然后引用刚才创建的块表记录。
MxDrawBlockReference blkRef = curSpace.InsertBlock(pos.x, pos.y, sNewBlakName, 1.0, 0.0);
// 为块引用对象,添加一个属性。
MxDrawAttribute attrib = blkRef.AppendAttribute();
attrib.Position = pos;
attrib.AlignmentPoint = pos;
attrib.Oblique = 0.0;
attrib.Rotation = 0.0;
attrib.Height = 2.0;
attrib.TrueColor.SetRGB(255, 0, 0);
attrib.TextString = "这是一个属性文字的测试";
attrib.Tag = "TestTag";
attrib.IsInvisible = false;
blkRef.Position = blkRef.Position;
// 返回创建 的块引用对象的id.
return blkRef.ObjectID;
}
return 0;
}
调用代码:
// 创建一个选择集对象.
MxDrawSelectionSet ss = new MxDrawSelectionSet();
// 让用户在图上选择对象.
ss.Select(MCAD_McSelect.mcSelectionSetUserSelect, null, null, null);
// 得到用户选择的对象,把对象的id放入aryID
List<Int64> aryId = new List<Int64>();
for (Int32 i = 0; i < ss.Count; i++)
{
MxDrawEntity ent = ss.Item(i);
if (ent != null)
{
aryId.Add(ent.ObjectID);
ent.Close();
}
}
// 调用函数,把选择的对象做成一个块。
MakeEntitysToBlock(axMxDrawX1,aryId);
2. 把一个DWG文件插入到当前文件
(1)调用控件的InsertBlock函数,把一个DWG文件,插入到图上,指定一个块名,放在块表记录中。InsertBlock的函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__InsertBlock@BSTR@BSTR.htm,
(2)如果给的图块名,当前图上已经有该名称的图块,可以调用Mx_InsertBlockEx 自定义函数,告诉控件是否需要重新定义图块。Mx_InsertBlockEx的详细说明: http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_InsertBlockEx@CString@CString@INT@CString@bool.htm
(3)然后调用DrawBlockReference函数绘制块引用,引用InsertBlock创建的块表记录。函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__DrawBlockReference@DOUBLE@DOUBLE@BSTR@DOUBLE@DOUBLE.htm
下面代码,演示如何插入DWG:
axMxDrawX1.InsertBlock("G:\pt1000.dwg", "MyBlkName");
axMxDrawX1.DrawBlockReference(0, 0, "MyBlkName", 1.0, 0.0);
axMxDrawX1.ZoomAll();
3. 把一个图块插入基出,修正到图块的中心点。
下面,会遍历图块中所有实体,然后求所有实体的最小外包,再计算出外包的中心点,再把块记录的Origin属性修改到中心点。sBlkName是图块名。
private bool ModifyBlockInsertPointToCenter(String sBlkName)
{
//返回控件的数据库对象
MxDrawDatabase databae = (MxDrawDatabase)axMxDrawX1.GetDatabase();
//返回数据库中的块表对象
MxDrawBlockTable blkTab = databae.GetBlockTable();
MxDrawBlockTableRecord blkRec = blkTab.GetAt(sBlkName);
if (blkRec == null)
return false;
//创建一个遍历块表中所有记录的遍历器
MxDrawBlockTableRecordIterator mBlockTableReciter = blkRec.NewIterator();
MxDrawPoint mMaxPt = new MxDrawPoint();
MxDrawPoint mMinPt = new MxDrawPoint();
MxDrawPoint mMaxPtTemp = new MxDrawPoint();
MxDrawPoint mMinPtTemp = new MxDrawPoint();
bool isFirstEnt = true;
//移动当前遍历器位置
for (; !mBlockTableReciter.Done(); mBlockTableReciter.Step(true, false))
{
//与用户交互在图面上选择一个实体
MxDrawEntity ent = mBlockTableReciter.GetEntity();
//返回实体的最小矩形框外包
ent.GetBoundingBox(out mMinPtTemp, out mMaxPtTemp);
if ((mMinPtTemp == null) || (mMaxPtTemp == null))
break;
if (isFirstEnt)
{
mMinPt.x = mMinPtTemp.x;
mMinPt.y = mMinPtTemp.y;
mMaxPt.x = mMaxPtTemp.x;
mMaxPt.y = mMaxPtTemp.y;
isFirstEnt = false;
}
else
{
mMaxPt.x = Math.Max(mMaxPt.x, mMaxPtTemp.x);
mMaxPt.y = Math.Max(mMaxPt.y, mMaxPtTemp.y);
mMinPt.x = Math.Min(mMinPt.x, mMinPtTemp.x);
mMinPt.y = Math.Min(mMinPt.y, mMinPtTemp.y);
}
}
if (isFirstEnt)
{
// 没有实体
return false;
}
MxDrawPoint mNewBasePt = new MxDrawPoint();
mNewBasePt.x = mMinPt.x + (mMaxPt.x - mMinPt.x) / 2;
mNewBasePt.y = mMinPt.y + (mMaxPt.y - mMinPt.y) / 2;
//块表记录的插入原点属性
blkRec.Origin = mNewBasePt;
//重新生成图,重新生成所有显示数据
axMxDrawX1.Regen();
return true;
}
4. 属性块
(1)下面我们演示如果在AutoCAD中做一个属性块文件,然后在控件中如何插入该属性块,并修改它的属性。
打开AutoCAD软件,画一些图形,比如我画了一个圆,然后用attdef命令,插入一个属性定义,如下图:
插入属性定义,如下图
(2)使用WBLOCK命令,把我们画的图形输入一个块文件,命令界面如下:
基点,选对圆的中心位置,它是图块的插入原点,点选择对象,选择我们刚画的圆和属性定义,目标指定我们的输出文件位置.
这样我们做好图块文件MyBlock.dwg
(3)下面代码,会插入MyBlock.dwg文件,然后绘一个属性块,然后修改图块属性文字,
c#如下:
private void InsertAttribBlock()
{
// 注释文本内容
String sNoteText = "这是属性文字";
// 注释图块名
String sNote = "NoteBlockName";
// 让用点取一个注释插入点。
MxDrawUtility mxUtility = new MxDrawUtility();
MxDrawPoint point = (MxDrawPoint)(mxUtility.GetPoint(null, "点取插入点 :"));
if (point == null)
{
MessageBox.Show("用户取消..");
return;
}
// 得到当前应用对象
MxDrawApplication app = new MxDrawApplication();
// 得到当前数据库
MxDrawDatabase curDatabase = app.WorkingDatabase();
// 得到块表对象
MxDrawBlockTable blkTable = curDatabase.GetBlockTable();
// 得到当前空间
MxDrawBlockTableRecord curSpace = curDatabase.CurrentSpace();
// 当前块表中是否已经有名为sNote的块表记录,如有返回
MxDrawBlockTableRecord blkRec = blkTable.GetAt(sNote, true);
if (blkRec == null)
{
// 没有就新插入块表记录
// sBlkFilePath是块文字路径
String sBlkFilePath = "H:\\MyBlock.dwg";
// 把dwg文件导入到当前数据库。
axMxDrawX1.InsertBlock(sBlkFilePath, sNote);
// 得到新插入的块表记录
blkRec = blkTable.GetAt(sNote, true);
}
if (blkRec != null)
{
// 在当前空间中插入一个块引用。
MxDrawBlockReference blkRef = curSpace.InsertBlock(point.x, point.y, sNote, 4.0, 0.0);
// 创建属性块的属性。
MxDrawResbuf param = new MxDrawResbuf();
blkRef.SetProp("createAttribute", param);
// 修改属性文字。
for (int j = 0; j < blkRef.AttributeCount; j++)
{
// 得到块引用中所有的属性
MxDrawAttribute attrib = blkRef.AttributeItem(j);
if (attrib.Tag == "MYATTRIB")
{
attrib.TextString = sNoteText;
}
}
// 修改了属性文字,通知块引用更新显示。
blkRef.AssertWriteEnabled();
}
}
运行效果如下图:
5.得到图上所有属性块的属性文本.
下面代码,得到图上所有图块,然后遍历每个图块,再遍历每个属性块的属性
C#代码:
private void TestGeAlltBlockAttrib()
{
// 构造一个选择集.
MxDrawSelectionSet ss = new MxDrawSelectionSet();
// 创建一个过滤选择条件.
MxDrawResbuf spFilte = new MxDrawResbuf();
// 把块引用对象,当着过滤条件.
spFilte.AddStringEx("INSERT", 5020);
// 得到图上,所有引用对象.
ss.AllSelect(spFilte);
String str = "";
// 遍历所有块引用。
for (var i = 0; i < ss.Count; i++)
{
MxDrawEntity ent = ss.Item(i);
if (ent == null)
continue;
if (ent.ObjectName == "McDbBlockReference")
{
MxDrawBlockReference blkRef = (MxDrawBlockReference)ent;
// 遍历属性块的属性。
for (var j = 0; j < blkRef.AttributeCount; j++)
{
// 得到块引用中所有的属性
MxDrawAttribute attrib = blkRef.AttributeItem(j);
str += attrib.TextString + "---";
}
}
}
MessageBox.Show(str);
}