AcDbHatch_填充邊界重生成 Restore hatch boundaries

參考博客:https://adndevblog.typepad.com/autocad/2013/01/restore-hatch-boundaries-if-they-have-been-lost.html

/*
* 函數介紹:獲取圖案填充邊界
* 輸入參數: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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章