[每日一码] AcBr 类开发代码
//// ObjectARX defined commands
#include "StdAfx.h"
#include "StdArx.h"
#include "brbrep.h" // AcBrBrep
#include "dbents.h"
#include "dbregion.h" // AcDbRegion
#include "dbpl.h" // AcDbPolyline
#include "gecomp3d.h" // AcGeCompositeCurve2d
// 根据轻量多段线创建对应的AcGeCurve2d对象
BOOL PolylineToGeCurve(const AcDbPolyline *&pPline,
AcGeCurve3d *&pGeCurve)
{
int nSegs; // 多段线的段数
AcGeLineSeg3d line, *pLine; // 几何曲线的直线段部分
AcGeCircArc3d 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 AcGeLineSeg3d(line);
geCurves.append(pLine);
}
else if (pPline->segType(i) == AcDbPolyline::kArc)
{
pPline->getArcSegAt(i, arc);
pArc = new AcGeCircArc3d(arc);
geCurves.append(pArc);
}
}
// 处理闭合多段线最后一段是圆弧的情况
if (pPline->isClosed() && pPline->segType(nSegs) == AcDbPolyline::kArc)
{
pPline->getArcSegAt(nSegs, arc);
pArc = new AcGeCircArc3d(arc);
pArc->setAngles(arc.startAng(), arc.endAng() -
(arc.endAng() - arc.startAng()) / 100);
geCurves.append(pArc);
}
// 根据分段的几何曲线创建对应的复合曲线
if (geCurves.length() == 1)
{
pGeCurve = (AcGeCurve3d *)geCurves;
}
else
{
pGeCurve = new AcGeCompositeCurve3d(geCurves);
}
// 释放动态分配的内存
for (i = 0; i < geCurves.length(); i++)
{
delete geCurves<i>;
}
return TRUE;
}
// 将实体添加到图形数据库的模型空间
AcDbObjectId PostToModelSpace(AcDbEntity* pEnt)
{
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getBlockTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB采用MODEL采用SPACE, pBlockTableRecord,
AcDb::kForWrite);
AcDbObjectId entId;
pBlockTableRecord->appendAcDbEntity(entId, pEnt);
pBlockTable->close();
pBlockTableRecord->close();
pEnt->close();
return entId;
}
// 根据给定的边界对象创建面域
AcDbObjectIdArray CreateRegion(const AcDbObjectIdArray& curveIds)
{
AcDbObjectIdArray regionIds; // 生成的面域的ID数组
AcDbVoidPtrArray curves; // 指向作为面域边界的曲线的指针的数组
AcDbVoidPtrArray regions; // 指向创建的面域对象的指针的数组
AcDbEntity *pEnt; // 临时指针,用来关闭边界曲线
AcDbRegion *pRegion; // 临时对象,用来将面域添加到模型空间
// 用curveIds初始化curves
for (int i = 0; i < curveIds.length(); i++)
{
acdbOpenAcDbEntity(pEnt, curveIds.at(i), AcDb::kForRead);
if (pEnt->isKindOf(AcDbCurve::desc()))
{
curves.append(static采用cast<void*>(pEnt));
}
}
Acad::ErrorStatus es = AcDbRegion::createFromCurves(curves, regions);
if (es == Acad::eOk)
{
// 将生成的面域添加到模型空间
for (i = 0; i < regions.length(); i++)
{
// 将空指针(可指向任何类型)转化为指向面域的指针
pRegion = static采用cast<AcDbRegion*>(regions<i>);
pRegion->setDatabaseDefaults();
AcDbObjectId regionId;
regionId = PostToModelSpace(pRegion);
regionIds.append(regionId);
}
}
else // 如果创建不成功,也要删除已经生成的面域
{
for (i = 0; i < regions.length(); i++)
{
delete (AcRxObject*)regions<i>;
}
}
// 关闭作为边界的对象
for (i = 0; i < curves.length(); i++)
{
pEnt = static采用cast<AcDbEntity*>(curves<i>);
pEnt->close();
}
return regionIds;
}
// 判断点是否在指定的面域内部
bool PtInRegion(AcGePoint3d &pt, AcDbRegion *pRegion)
{
if (pRegion == NULL)
return false;
AcBrBrep brep;
if (brep.set(*pRegion) != AcBr::eOk)
return false;
AcBr::Relation relation;
AcBr::ErrorStatus es = brep.getPointRelationToBrep(pt, relation);
if (es != AcBr::eOk)
return false;
switch (relation)
{
case AcBr::kBoundary:
case AcBr::kInside:
return true;
default:
return false;
}
}
// 判断一条多段线是否在另一条多段线内部
bool PolyInRegion(AcDbPolyline *pPoly, AcDbRegion *pRegion)
{
if ((pPoly == NULL) || (pRegion == NULL))
return false;
// 创建Brep实体
AcBrBrep brep;
if (brep.set(*pRegion) != AcBr::eOk)
return false;
// 根据多段线创建对应的几何类
//AcGeCurve3d *pGeCurve = NULL;
AcGeLineSeg3d *pGeCurve = new AcGeLineSeg3d(AcGePoint3d(50, 50, 0),
AcGePoint3d(60, 60, 0));
//PolylineToGeCurve(pPoly, pGeCurve);
AcBr::Relation relation;
AcBr::ErrorStatus es = brep.getCurveRelationToBrep(*pGeCurve, relation);
delete pGeCurve; // 在函数PolylineToGeCurve中分配了内存
if (es != AcBr::eOk)
return false;
switch (relation)
{
case AcBr::kBoundary:
case AcBr::kInside:
return true;
default:
return false;
}
}
// This is command 'PTINREGION'
void ZffCHAP2PtInRegion()
{
// 创建一个圆作为拉伸的截面
AcGeVector3d vec(0, 0, 1); // 圆所在平面的法矢量
AcGePoint3d ptCenter(30, 0, 0); // 圆心位置与半径的大小有关
AcDbCircle *pCircle = new AcDbCircle(ptCenter, vec, 30);
AcDbObjectId circleId = PostToModelSpace(pCircle);
// 根据圆创建一个面域
AcDbObjectIdArray boundaryIds, regionIds;
boundaryIds.append(circleId);
regionIds = CreateRegion(boundaryIds);
// 打开面域
AcDbRegion *pRegion;
acdbOpenObject(pRegion, regionIds, AcDb::kForRead);
AcGePoint3d pt(1, 0, 0);
if (PtInRegion(pt, pRegion) == true)
{
acedAlert("True");
}
pRegion->close();
}
// This is command 'POLYCONTAIN'
void ZffCHAP2PolyContain()
{
// 提示用户选择对象
ads采用name en1, en2;
ads采用point pt;
if (acedEntSel("n选择第一条多段线:", en1, pt) != RTNORM)
return;
if (acedEntSel("n选择第二条多段线:", en2, pt) != RTNORM)
return;
// 获得选择对象的指针
AcDbObjectId polyId1, polyId2;
Acad::ErrorStatus es = acdbGetObjectId(polyId1, en1);
es = acdbGetObjectId(polyId2, en2);
AcDbPolyline *pPoly;
es = acdbOpenObject(pPoly, polyId1, AcDb::kForRead);
// 根据第二条多段线创建一个面域
AcDbObjectIdArray boundaryIds, regionIds;
boundaryIds.append(polyId2);
regionIds = CreateRegion(boundaryIds);
// 打开面域
AcDbRegion *pRegion;
acdbOpenObject(pRegion, regionIds, AcDb::kForWrite);
if (PolyInRegion(pPoly, pRegion) == true)
{
acedAlert("第一条多段线在第二条多段线内部!");
}
pPoly->close();
pRegion->erase();
pRegion->close();
} 我在CAD2008使用过程中发现BOOL PolylineToGeCurve(const AcDbPolyline *&pPline,
AcGeCurve3d *&pGeCurve)函数生成的AcGeCurve3d* 并没有被释放,导致CAD的占用内存越用越大,不知道是怎么回事。
// 释放动态分配的内存
for (i = 0; i < geCurves.length(); i++)
{
delete geCurves;
}
这一段语句实际上是不能运行的:
错误 4 error C2440: 'delete' : cannot convert from 'AcGeVoidPointerArray' to 'void *' d:\backup\documents\ymf\软件开发\nbtsurvey开发版\vc\nbtsurvey\nbtsurvey\cconversion.cpp 290
页:
[1]