objectarx 得到有宽度的多段的轮廓

时间:2024-02-01 19:03:31

使用到的命令是:_.wmfout和_.import以及PEdit
步骤:1.先通过_.wmfout和_.import得到轮廓线,得到的轮廓线是一个块。方法如下:

//ssname:选择的有宽度的多段线
static AcDbObjectId wmfoutIn(ads_name& ssname)
    {
        acedCommandS(RTSTR, L"_.wmfout", RTSTR, L"E:\\temp_1.wmf", RTENAME, ssname, RTSTR, L"", RTNONE);
        acedCommandS(RTSTR, L"_.import", RTSTR, L"E:\\temp_1.wmf", RTNONE);
        acdbEntLast(ssname);
        AcDbObjectId entId;
        acdbGetObjectId(entId, ssname);
        AcDbBlockReference* pBlk = NULL;
        AcGePoint3d ptBase;
        AcGeMatrix3d mat;
        if (acdbOpenObject(pBlk, entId, AcDb::kForWrite) == Acad::eOk)
        {
            ptBase = pBlk->position();
            mat.setToScaling(2.0, ptBase);
            pBlk->transformBy(mat);
            pBlk->close();

            return entId;
        }

        return AcDbObjectId::kNull;
    }
View Code
2.炸开这个块,得到的是2维多段线集合。AcDb2dPolyline 在炸开,得到直线集合。

 

AcDbVoidPtrArray voidArr;

                es = pBlk->explode(voidArr);

                if (es == ErrorStatus::eOk) {

                    for (int j = 0; j < voidArr.length(); j++)
                    {

                        AcDb2dPolyline *pl2d = (AcDb2dPolyline*)voidArr[j];

                        AcDbVoidPtrArray voidArr2d;

                        es = pl2d->explode(voidArr2d);

                        if (es == ErrorStatus::eOk) {
                            for (int m = 0; m < voidArr2d.length(); m++)
                            {
                                AcDbLine * line = (AcDbLine*)voidArr2d[m];

                                vecLines.push_back(line);
                            }
                        }
                        delete pl2d;
                        pl2d = NULL;
                    }
                }

3.这样得到的直线集合,发现除了能得到轮廓之后,在轮廓内部还会有重叠的直线,所以这一步就是删除轮廓内部重叠的直线。

for (int i = 0; i < (int)vecLines.size(); i++)
        {
            AcDbLine * l1 = vecLines[i];
            if (l1 == NULL) {
                continue;
            }
            int m = 0;
            for (int j = i + 1; j < (int)vecLines.size(); j++)
            {
                AcDbLine * l2 = vecLines[j];
                if (l2 == NULL || l1 == NULL) {
                    break;
                }            
                if (IsEqual(l1->startPoint(), l2->startPoint(), 1e-4) && IsEqual(l1->endPoint(), l2->endPoint(), 1e-4)) {

                    vecLines.erase(vecLines.begin() + i - m, vecLines.begin() + i + 1 - m);
                    m++;
                    vecLines.erase(vecLines.begin() + j - m, vecLines.begin() + j + 1 - m);
                    m++;
                }
            }
        }
View Code

4.到了这一步就只剩下轮廓直线集合了,这步就把这个剩余的直线转换为多段线。我使用的PEDit命令,这个命令具体用法,详见另一篇博客:

https://www.cnblogs.com/HelloQLQ/p/12381923.html

这里做的不好的是,在第4步,需要再次选择一下,我本来是直接通过:
int acedSSAdd(
    const ads_name ename,
    const ads_name sname,
    ads_name result
);
但是添加出来的result用PE命令合成多段线始终不成功,所以只能手动选择一次,得到result集合,再合成多段线了。。