AcDbHatch_填充边界重生成 Restore hatch boundaries
参考博客:Restore hatch boundaries if they have been lost - AutoCAD DevBlog
/*
* 函数介绍:获取图案填充边界
* 输入参数:AcDbObjectId hatchId 填充区域Id
* 输出参数:AcDbVoidPtrArray & entitySet 边界实体指针
* 返回值 : bool true获取边界成功
*/
bool RestoreHatchBoundary(AcDbObjectId hatchId, AcDbVoidPtrArray &entitySet)
{
AcDbHatch*pHatch = NULL;
acdbOpenObject(pHatch, hatchId, AcDb::kForRead);
if (pHatch == NULL)
return false;
// For each loop, draw the boundary.
int nLoops = pHatch->numLoops();
for (int i = 0; i < nLoops; i++)
{
long loopType;
if (pHatch->loopTypeAt(i) & AcDbHatch::kPolyline)
{
AcGePoint2dArray vertices;
AcGeDoubleArray bulges;
pHatch->getLoopAt(i, loopType, vertices, bulges);
int nVertices = vertices.length();
AcDbPolyline *pPoly = new AcDbPolyline(nVertices);
for (int vx = 0; vx < nVertices; vx++)
{
double bulge = bulges.length() < nVertices ? 0.0 : bulges[vx];
pPoly->addVertexAt(vx, vertices[vx], bulge);
}
pPoly->setClosed(1);
entitySet.append(pPoly);
}
else
{
AcGePoint2dArray vertices;
AcGeDoubleArray bulges;
AcGeVoidPointerArray edgePtrs;
AcGeIntArray edgeTypes;
pHatch->getLoopAt(i, loopType, edgePtrs, edgeTypes);
for (int j = 0; j < edgePtrs.length(); j++)
{
switch (edgeTypes[j]) {
case AcDbHatch::kLine:
{
AcGeLineSeg3d *pGeLine3d = (AcGeLineSeg3d*)edgePtrs[j];
AcGePoint3d geP1, geP2;
geP1 = pGeLine3d->startPoint();
geP2 = pGeLine3d->endPoint();
AcDbLine *pLine = new AcDbLine(geP1, geP2);
entitySet.append(pLine);
}
break;
case AcDbHatch::kCirArc:
{
AcGePoint3d geCenter;
double dRadius, dStartAng, dEndAng;
AcGeCircArc3d *pGeArc = (AcGeCircArc3d*)edgePtrs[j];
geCenter = pGeArc->center();
dRadius = pGeArc->radius();
dStartAng = pGeArc->startAng();
dEndAng = pGeArc->endAng();
double dAngDiff;
dAngDiff = fabs(dEndAng - dStartAng - atan(double(1)) * 8);
if (dAngDiff > 1e-5) // It's an ARC.
{
AcDbArc *pArc = new AcDbArc(geCenter, dRadius, dStartAng, dEndAng);
entitySet.append(pArc);
}
else // It's a circle.
{
AcGeVector3d geNorm = pGeArc->normal();
AcDbCircle *pCir = new AcDbCircle(geCenter, geNorm, dRadius);
entitySet.append(pCir);
}
}
break;
case AcDbHatch::kEllArc:
{
AcGePoint3d geCenter;
AcGeVector3d geNorm, dMajorAxis, dMinorAxis;
double dMajorRadius, dMinorRadius;
double dStartAng, dEndAng;
AcGeEllipArc3d *pGeEllip = (AcGeEllipArc3d*)edgePtrs[j];
geCenter = pGeEllip->center();
dStartAng = pGeEllip->startAng();
dEndAng = pGeEllip->endAng();
geNorm = pGeEllip->normal();
dMajorAxis = pGeEllip->majorAxis();
dMinorAxis = pGeEllip->minorAxis();
dMajorRadius = pGeEllip->majorRadius();
dMinorRadius = pGeEllip->minorRadius();
AcDbEllipse *pEllip = new AcDbEllipse();
// Note: radiusRatio = dMinorRadius/dMajorRadius (must be within [0, 1])
pEllip->set(geCenter, geNorm, dMajorAxis*dMajorRadius, dMinorRadius / dMajorRadius);
pEllip->setStartParam(dStartAng);
pEllip->setEndParam(dEndAng);
if (pEllip->isNull() == Adesk::kTrue)
{
acutPrintf(_T("\nFailed to create an ellipse."));
break;
}
else
{
entitySet.append(pEllip);
}
}
break;
case AcDbHatch::kSpline:
{
Adesk::Boolean bIsFixSpline;
AcGePoint3dArray fitPoints;
AcGeTol fitTol;
Adesk::Boolean bTangentsExist;
AcGeVector3d startTangent, endTangent;
int deg;
AcGeNurbCurve3d *pGeSpline = (AcGeNurbCurve3d *)edgePtrs[j];
assert(pGeSpline);
deg = pGeSpline->degree();
bIsFixSpline = pGeSpline->getFitData(fitPoints,
fitTol,
bTangentsExist,
startTangent,
endTangent);
if (bIsFixSpline == Adesk::kTrue)
{
AcDbSpline *pSpline = new AcDbSpline();
pSpline->setFitData(fitPoints,
deg,
fitTol.equalVector(),
startTangent,
endTangent);
if (pSpline->isNull() == Adesk::kTrue)
{
acutPrintf(_T("\nFailed to create a spline."));
break;
}
else
{
entitySet.append(pSpline);
}
}
else
{
Adesk::Boolean rational, closed, periodic;
AcGePoint3dArray gePoints;
AcGeDoubleArray geWeights;
AcGePoint3d gePoint;
AcGeKnotVector geKnots;
AcGeDoubleArray dKnots;
rational = pGeSpline->isRational();
closed = pGeSpline->isClosed();
periodic = Adesk::kFalse;
for (int k = 0; k < pGeSpline->numControlPoints(); k++)
{
gePoints.append(pGeSpline->controlPointAt(k));
}
for (int k = 0; k < pGeSpline->numWeights(); k++)
{
geWeights.append(pGeSpline->weightAt(k));
}
geKnots = pGeSpline->knots();
for (int k = 0; k < geKnots.length(); k++)
{
dKnots.append(geKnots[k]);
}
AcDbSpline *pSpline = new AcDbSpline(deg,
rational,
closed,
periodic,
gePoints,
dKnots,
geWeights);
if (pSpline->isNull() == Adesk::kTrue)
{
acutPrintf(_T("\nFailed to create a spline."));
break;
}
else
{
entitySet.append(pSpline);
}
}
}
break;
default:
break;
}
}
}
}
pHatch->close();
return true;
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?