- UID
- 786039
- 积分
- 27
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2019-4-11
- 最后登录
- 1970-1-1
|
发表于 2019-4-15 17:56:43
|
显示全部楼层
// 根据多段线构建二维几何曲线
static bool PolyToGeCurve(AcDbPolyline *pPline, AcGeCurve2d *&pGeCurve)
{
int nSegs; // 多段线的段数
AcGeLineSeg2d line, *pLine; // 几何曲线的直线段部分
AcGeCircArc2d arc, *pArc; // 几何曲线的圆弧部分
AcGeVoidPointerArray geCurves; // 指向组成几何曲线各分段的指针数组
nSegs = pPline->numVerts() - 1;
// 根据多段线创建对应的分段几何曲线
for (int i = 0; i < nSegs; i++)
{
if (pPline->segType(i) == AcDbPolyline::kLine)
{
pPline->getLineSegAt(i, line);
pLine = new AcGeLineSeg2d(line);
geCurves.append(pLine);
}
else if (pPline->segType(i) == AcDbPolyline::kArc)
{
pPline->getArcSegAt(i, arc);
pArc = new AcGeCircArc2d(arc);
geCurves.append(pArc);
}
}
// 处理闭合多段线最后一段是圆弧的情况
if (pPline->isClosed() && pPline->segType(nSegs) == AcDbPolyline::kArc)
{
pPline->getArcSegAt(nSegs, arc);
pArc = new AcGeCircArc2d(arc);
pArc->setAngles(arc.startAng(), arc.endAng() -
(arc.endAng() - arc.startAng()) / 100);
geCurves.append(pArc);
}
// 根据分段的几何曲线创建对应的复合曲线
if (geCurves.length() == 1)
{
pGeCurve = (AcGeCurve2d *)geCurves[0];
}
else
{
pGeCurve = new AcGeCompositeCurve2d(geCurves);
}
// 释放动态分配的内存
if (geCurves.length() > 1)
{
for (int i = 0; i < geCurves.length(); i++)
{
delete geCurves[i];
}
}
return true;
}
// 根据指定的一组点创建一个结果缓冲区链表
struct resbuf* BuildRbFromPtArray(const AcGePoint2dArray &arrPoints)
{
struct resbuf *retRb = NULL;
int count = arrPoints.length();
if (count <= 1)
{
acedAlert(TEXT("函数BuildBbFromPtArray中, 点数组包含元素个数不足!"));
return retRb;
}
// 使用第一个点来构建结果缓冲区链表的头节点
ads_point adsPt;
adsPt[X] = arrPoints[0].x;
adsPt[Y] = arrPoints[0].y;
retRb = acutBuildList(RTPOINT, adsPt, RTNONE);
struct resbuf *nextRb = retRb; // 辅助指针
for (int i = 1; i < count; i++) // 注意:不考虑第一个元素,因此i从1开始
{
adsPt[X] = arrPoints[i].x;
adsPt[Y] = arrPoints[i].y;
// 动态创建新的节点,并将其链接到原来的链表尾部
nextRb->rbnext = acutBuildList(RTPOINT, adsPt, RTNONE);
nextRb = nextRb->rbnext;
}
return retRb;
}
// 选择位于多段线内部的所有实体
static bool SelectEntInPoly(AcDbPolyline *pPline, AcDbObjectIdArray &ObjectIdArray, const char *selectMode, double approxEps)
{
// 判断selectMode的有效性
if (_tcscmp(char2wchar(selectMode), TEXT("CP")) != 0 && _tcscmp(char2wchar(selectMode), TEXT("WP")) != 0)
{
acedAlert(TEXT("函数SelectEntInPline中, 指定了无效的选择模式!"));
return false;
}
// 清除数组中所有的ObjectId
for (int i = 0; i < ObjectIdArray.length(); i++)
{
ObjectIdArray.removeAt(i);
}
//AcDbEntity *pNewPpline = AcDbEntity::cast(pPline->clone());
//ObjectIdArray.append(pNewPpline->objectId()); // 将作为边界的多段线本身的Id也加入到所选择实体的数组中
AcGeCurve2d *pGeCurve; // 多段线对应的几何曲线
Adesk::Boolean bClosed = pPline->isClosed(); // 多段线是否闭合
if (bClosed != Adesk::kTrue) // 确保多段线作为选择边界时是闭合的
{
pPline->setClosed(!bClosed);
}
// 创建对应的几何类曲线
PolyToGeCurve(pPline, pGeCurve);
// 获得几何曲线的样本点
AcGePoint2dArray SamplePtArray; // 存储曲线的样本点
AcGeDoubleArray ParamArray; // 存储样本点对应的参数值
AcGePoint2d ptStart, ptEnd; // 几何曲线的起点和终点
Adesk::Boolean bRet = pGeCurve->hasStartPoint(ptStart);
bRet = pGeCurve->hasEndPoint(ptEnd);
double valueSt = pGeCurve->paramOf(ptStart);
double valueEn = pGeCurve->paramOf(ptEnd);
AcGeInterval pInterval;
pGeCurve->getInterval(pInterval, ptStart, ptEnd);
//pGeCurve->getInterval(pInterval);
//pInterval.getBounds(ptStart.x, ptEnd.x);
//pInterval.getBounds(ptStart.y, ptEnd.y);
pInterval.getBounds(valueSt, valueEn);
pGeCurve->getSamplePoints(valueSt, valueEn, approxEps, SamplePtArray, ParamArray);
delete pGeCurve; // 在函数PolyToGeCurve中分配了内存
// 确保样本点的起点和终点不重合
AcGeTol tol;
tol.setEqualPoint(0.01);
AcGePoint2d ptFirst = SamplePtArray[0];
AcGePoint2d ptLast = SamplePtArray[SamplePtArray.length() - 1];
if (ptFirst.isEqualTo(ptLast))
{
SamplePtArray.removeLast();
}
// 根据样本点创建结果缓冲区链表
struct resbuf *rb;
rb = BuildRbFromPtArray(SamplePtArray);
//设置过滤条件
struct resbuf rbFilter;
TCHAR sbuf[50];
rbFilter.restype = 0;
_tcscpy(sbuf, TEXT("10kV线路-牧野变"));
rbFilter.resval.rstring = sbuf;
rbFilter.rbnext = NULL;
// 使用acedSSGet函数创建选择集
ads_name ssName; // 选择集名称
//int rt = acedSSGet(char2wchar(selectMode), rb, NULL, NULL, ssName);
int rt = acedSSGet(char2wchar(selectMode), rb, NULL, &rbFilter, ssName);
if (rt != RTNORM)
{
acutRelRb(rb); // 释放结果缓冲区链表
return false;
}
// 将选择集中所有的对象添加到ObjectIdArray
long length;
acedSSLength(ssName, &length);
for (int i = 0; i < length; i++)
{
// 获得指定元素的ObjectId
ads_name ent;
acedSSName(ssName, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
// 获得指向当前元素的指针
AcDbEntity *pEnt;
Acad::ErrorStatus es = acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead);
// 选择到作为边界的多段线了,直接跳过该次循环
if (es == Acad::eWasOpenForWrite)
{
continue;
}
ObjectIdArray.append(pEnt->objectId());
pEnt->close();
}
// 释放内存
acutRelRb(rb); // 释放结果缓冲区链表
acedSSFree(ssName); // 删除选择集
return true;
}
class CSegmentationByGridApp : public AcRxArxApp {
public:
CSegmentationByGridApp () : AcRxArxApp () {}
virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
// TODO: Load dependencies here
// You *must* call On_kInitAppMsg here
AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
// TODO: Add your initialization code here
return (retCode) ;
}
virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
// TODO: Add your code here
// You *must* call On_kUnloadAppMsg here
AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
// TODO: Unload dependencies here
return (retCode) ;
}
virtual void RegisterServerComponents () {
}
public:
// - GYDLSegmentationByGrid.dividedByGrid command (do not rename)
static void GYDLSegmentationByGriddividedByGrid(void)
{
// Add your code for command GYDLSegmentationByGrid.dividedByGrid here
//获取当前图层上所有实体的Id
//AcDbObjectIdArray allBorderIds = CDwgDatabaseUtil::GetAllEntityIds(TEXT("0"));
AcDbObjectIdArray allBorderIds = CDwgDatabaseUtil::GetAllEntityIds(TEXT("2020年网格边界"));
//获取当前dwg文件的图形数据库
AcDbDatabase *pSourceDb = acdbHostApplicationServices()->workingDatabase();
//创建分图的图形数据库
AcDbDatabase *pSubgraphDestDb = NULL;
//建立多段线网格边界的圈交(CP)模式选择集数组
AcDbObjectIdArray subgraphIdArray;
for (int i = 0; i < allBorderIds.length(); i++)
{
AcDbPolyline *pPolyline = NULL;
if (acdbOpenObject(pPolyline, allBorderIds[i], AcDb::kForWrite) == Acad::eOk)
{
//获取每个多段线网格边界的圈交(CP)模式选择集的Id
SelectEntInPoly(pPolyline, subgraphIdArray, "CP", 1);
//将多段线网格边界的Id加入当前选择集
subgraphIdArray.append(pPolyline->objectId());
pPolyline->close();
//使用wblock将当前图形数据库中的多段线网格边界及其选择集导出到一个新的图形数据库中
Acad::ErrorStatus es = pSourceDb->wblock(pSubgraphDestDb, subgraphIdArray, AcGePoint3d::kOrigin);
assert (es == Acad::eOk);
//将切分出来的子图存为dwg文件
CString d;
d.Format(_T("%d"),i);//整型转字符串
pSubgraphDestDb->saveAs(_T("E:/PartialGraph/" + d + ".dwg")); // 使用saveAs成员函数时,必须指定包含dwg扩展名的文件名称
pSubgraphDestDb->closeInput(true);
delete pSubgraphDestDb;
pSubgraphDestDb = NULL;
subgraphIdArray.removeAll();
//pPolyline->close();
}
}
pSourceDb = NULL;
}
} ;
现在遇到的主要问题是,在多段线里面选择集另存为dwg文件后,选择集里面是空的。我现在把代码贴上去了,麻烦诸位仁兄看一下吧,谢谢!接着我把原dwg文件传一下。 |
|