返回介绍

块表

发布于 2023-08-09 23:10:34 字数 12035 浏览 0 评论 0 收藏 0

DWG数据库中,所有图块存放在块表中,块表类名:MxDrawBlockTable,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawBlockTable.htm

块表中每一条记录称为块表记录,类名:MxDrawBlockTableRecord,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawBlockTableRecord.htm

块表记录中存放所有实体数据。每个DWG数据库中,到少有一个名为"*Model_Space"的块表记录(模型空间),CAD图纸打开后,默认看到的对象都存放在模型空间,有一种对象是块引用MxDrawBlockReference,它的详细接口说明参考:http://www.mxdraw.com/help/IMxDrawBlockReference.htm,块引用又可以指向另一个块表记录。

调用MxDrawDatabase::GetBlockTable 得到DWG数据库中块表

var mxUtility = mxOcx.NewUtility;

// 得到当前图纸空间
var blkRec = mxOcx.GetDatabase().CurrentSpace();

// 创建一个用于遍历当前图纸空间的遍历器
var iter = blkRec.NewIterator();
if (iter == null)
    return;

// 所有实体的id数组。
var aryId =  new Array();

var iLineNum = 0;
// 循环得到所有实体

for (; !iter.Done(); iter.Step(true, false))
{
    // 得到遍历器当前的实体
    var ent = iter.GetEntity();
    if (ent == null)
        continue;

    // 得到实体的id
    aryId.push(ent.ObjectID);


    var c= aryId.length;
    console.log(c);

    if (ent.ObjectName == "McDbLine")
    {
        // 当前实体是一个直线
        var line = ent;
        iLineNum++;
    }
else if (ent.ObjectName ==  "McDbBlockReference")
    {
        // 当前实体是一个块引用
        var blkRef =ent;
        for (var j = 0; j < blkRef.AttributeCount; j++)
        {
            // 得到块引用中所有的属性
            var attrib = blkRef.AttributeItem(j);
            mxUtility.Prompt("n Tag: " + attrib.Tag + "Text:" + attrib.TextString);
        }
    }
}

var sT;
sT = "发现" + aryId.length + "个实体,其中有" + iLineNum + "个直线";
alert(sT);

E 添加块表记录

下面代码,判断块表中是否有指定名称的块表记录,如果没有就增一个块表记录。

        function AddBlockRrecord(sName,blkOriginPoint) {
    // 取当前数据库.
    var curDatabase = mxOcx.GetDatabase();
    // 得到块表
    var blkTable = curDatabase.GetBlockTable();
 
    // 判断块表是否已经有该名称的块名。
    if (blkTable.Has(sName))
    {
        var blkRec = blkTable.GetAt(sName, true);
        // 如果块被删除,就反删除。
        blkRec.SetProp("unErase", null);
        return true;
    }
    // 新增一个块表记录.
    var blkNewRec = blkTable.Add(sName);
    if (blkNewRec == null)
        return false;
    // 设置块表记录的插入基点
    blkNewRec.Origin = blkOriginPoint;
    return true;
}

调用代码:

        var  pt = mxOcx.NewPoint();
        pt.x = 100;
        pt.y = 100;
        AddBlockRrecord("MyBlkName", pt);
        alert("成功");

运行后块表中多了一个我们添加的块表记录

blk1.png

F. 选择实体做成块

下面代码,让用在图上选择实体,然后把实体做成一个图块,然后插入到图上。

js代码如下:

//实例化一个构造选择集进行过滤,该类封装了选择集及其处理函数。
var ss = mxOcx.NewSelectionSet();
//构造一个过滤链表
var spFilte = mxOcx.NewResbuf();
//用户选择对象  得到用户选取的实体
ss.Select2(8, null, null, null, spFilte);
 
var aryId = new Array();
for (var i = 0; i < ss.Count; i++)
{
    var ent = ss.Item(i);
    if (ent != null)
    {
        aryId.push(ent.ObjectID);
        ent.Close();
    }
}
//返回控件的数据库对象
var curDatabase =mxOcx.GetDatabase();
var dMinX = 0, dMinY = 0, dMaxX = 0, dMaxY = 0;
var isFirstEnt = true;
for (var l = 0; l < aryId.length; l++)
{
    var pObj = curDatabase.ObjectIdToObject(aryId[l]);
    if (pObj == null)
        continue;
    var pEnt = pObj;
    if (pEnt == null)
        continue;
    var  points = pEnt.GetBoundingBox2();
 
    var minPt = points.Item(0);
    var maxPt = points.Item(1);
 
    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;
}
var pos = mxOcx.NewPoint();
pos.x = dMinX + (dMaxX - dMinX) / 2.0;
pos.y = dMinY + (dMaxY - dMinY) / 2.0;
 
// 检查新创建的块名,在当前数据库是否已经存在.
 
var blkTable = curDatabase.GetBlockTable();
var curSpace = curDatabase.CurrentSpace();
 
var sNewBlakName;
 
var blkNewRec = blkTable.Add("");
sNewBlakName = blkNewRec.Name;
 
blkNewRec.Origin = pos;
 
for (var l = 0; l < aryId.length; l++)
{
 
    blkNewRec.AddCloneEntity(aryId[l]);
    // 把以前实体删除 。
    var pObj = curDatabase.ObjectIdToObject(aryId[l]);
    if (pObj == null)
        continue;
    pObj.Erase();
}
if (blkNewRec != null)
{
    var blkRef = curSpace.InsertBlock(pos.x,pos.y, sNewBlakName, 1.0, 0.0);
    var attrib = blkRef.AppendAttribute();
    attrib.Position = pos;
    attrib.AlignmentPoint = pos;
    attrib.Oblique = 0.0;
    attrib.Rotation = 0.0;
    attrib.Height = 2.0;
    attrib.TextString = "这是一个属性文字的测试";
    attrib.Tag = "TestTag";
    attrib.IsInvisible = false;
 
    blkRef.Position = blkRef.Position;
 
}
 
return;

G. 把一个DWG文件插入到当前文件

调用控件的InsertBlock函数,把一个DWG文件,插入到图上,指定一个块名,放在块表记录中。InsertBlock的函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__InsertBlock@BSTR@BSTR.htm,

如果给的图块名,当前图上已经有该名称的图块,可以调用Mx_InsertBlockEx 自定义函数,告诉控件是否需要重新定义图块。Mx_InsertBlockEx的详细说明: http://www.mxdraw.com/help/MxDrawXCustomFunction__Mx_InsertBlockEx@CString@CString@INT@CString@bool.htm

然后调用DrawBlockReference函数绘制块引用,引用InsertBlock创建的块表记录。函数详细说明:http://www.mxdraw.com/help/MxDrawXLib___DMxDrawX__DrawBlockReference@DOUBLE@DOUBLE@BSTR@DOUBLE@DOUBLE.htm

下面代码,演示如何插入DWG.

            mxOcx.InsertBlock("G:\pt1000.dwg", "MyBlkName");
            mxOcx.DrawBlockReference(0, 0, "MyBlkName", 1.0, 0.0);
            mxOcx.ZoomAll();

H. 把一个图块插入基出,修正到图块的中心点。

下面,会遍历图块中所有实体,然后求所有实体的最小外包,再计算出外包的中心点,再把块记录的Origin属性修改到中心点。sBlkName是图块名。

//返回控件的数据库对象
var databae = mxOcx.GetDatabase();
//返回数据库中的块表对象
var blkTab = databae.GetBlockTable();
var sBlkName = "123";
var blkRec = blkTab.GetAt(sBlkName);
if (blkRec == null)
    return false;
//创建一个遍历块表中所有记录的遍历器
var mBlockTableReciter = blkRec.NewIterator();
var mMaxPt = mxOcx.NewPoint();
var mMinPt = mxOcx.NewPoint();
var mMaxPtTemp = mxOcx.NewPoint();
var mMinPtTemp = mxOcx.NewPoint();
var isFirstEnt = true;
//移动当前遍历器位置
for (; !mBlockTableReciter.Done(); mBlockTableReciter.Step(true, false))
{
    //与用户交互在图面上选择一个实体
    var ent = mBlockTableReciter.GetEntity();
    //返回实体的最小矩形框外包

    var  points = ent.GetBoundingBox2();

    var mMinPtTemp = points.Item(0);
    var mMaxPtTemp = points.Item(1);
    
    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;
}
var mNewBasePt = mxOcx.NewPoint();
mNewBasePt.x = mMinPt.x + (mMaxPt.x - mMinPt.x) / 2;
mNewBasePt.y = mMinPt.y + (mMaxPt.y - mMinPt.y) / 2;
//块表记录的插入原点属性
blkRec.Origin = mNewBasePt;
//重新生成图,重新生成所有显示数据
mxOcx.Regen();
return true;

I. 属性块

下面我们演示如果在AutoCAD中做一个属性块文件,然后在控件中如何插入该属性块,并修改它的属性。

1. 打开AutoCAD软件,画一些图形,比如我画了一个圆,然后用attdef命令,插入一个属性定义,如下图:

attrib.png

插入属性定义,如下图

attrib2.png

2. 使用WBLOCK命令,把我们画的图形输入一个块文件,命令界面如下:

基点,选对圆的中心位置,它是图块的插入原点,点选择对象,选择我们刚画的圆和属性定义,目标指定我们的输出文件位置.

attrib3.png

这样我们做好图块文件MyBlock.dwg

3. 下面代码,会插入MyBlock.dwg文件,然后绘一个属性块,然后修改图块属性文字,

js如下:

// 注释文本内容
var sNoteText = "这是属性文字";
// 注释图块名
var sNote = "NoteBlockName";
// 让用点取一个注释插入点。

//与用户交互到在图上提取一个点
var point = mxOcx.GetPoint(false,0,0,"\n 点取插入点:");

if (point == null)
{
   alert("用户取消..");
    return;
}

var curDatabase = mxOcx.GetDatabase();
// 得到块表对象
var blkTable = curDatabase.GetBlockTable();
// 得到当前空间
var curSpace = curDatabase.CurrentSpace();
// 当前块表中是否已经有名为sNote的块表记录,如有返回
var blkRec = blkTable.GetAt(sNote, true);
if (blkRec == null)
{
    //  没有就新插入块表记录
    //  sBlkFilePath是块文字路径


    var sBlkFilePath = "d:\\MyBlock.dwg";
    // 把dwg文件导入到当前数据库。
    mxOcx.InsertBlock(sBlkFilePath, sNote);
    // 得到新插入的块表记录
    blkRec = blkTable.GetAt(sNote, true);
}
if (blkRec != null)
{
    // 在当前空间中插入一个块引用。
    var blkRef = curSpace.InsertBlock(point.x, point.y, sNote, 4.0, 0.0);
    // 创建属性块的属性。
    var param = mxOcx.NewResbuf();
    blkRef.SetProp("createAttribute", param);
    // 修改属性文字。
    for (var j = 0; j < blkRef.AttributeCount; j++)
    {
        // 得到块引用中所有的属性
        var  attrib = blkRef.AttributeItem(j);
        if (attrib.Tag == "MYATTRIB")
        {
            attrib.TextString = sNoteText;
        }
    }
    // 修改了属性文字,通知块引用更新显示。
    blkRef.AssertWriteEnabled();
}

J. 得到图上所有属性块的属性文本.

下面代码,得到图上所有图块,然后遍历每个图块,再遍历每个属性块的属性

js代码:

// 构造一个选择集.
var ss = mxOcx.NewSelectionSet();
// 创建一个过滤选择条件.
var spFilte = mxOcx.NewResbuf();
// 把块引用对象,当着过滤条件.
spFilte.AddStringEx("INSERT", 5020);
// 得到图上,所有引用对象.
ss.AllSelect(spFilte);
var  str = "";
// 遍历所有块引用。
for (var i = 0; i < ss.Count; i++)
{
    var ent = ss.Item(i);
    if (ent == null)
        continue;
    if (ent.ObjectName == "McDbBlockReference")
    {
        var blkRef = ent;
        // 遍历属性块的属性。
        for (var j = 0; j < blkRef.AttributeCount; j++)
        {
            // 得到块引用中所有的属性
            var attrib = blkRef.AttributeItem(j);
            str += attrib.TextString + "---";
        }
    }
}
alert(str);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文