double GetHatchArea(AcDbHatch *pHatch)
{
double area = 0;
int nLoop = pHatch->numLoops();
Adesk::Int32 loopType;
for (int i = 0; i < nLoop; i++) {
double looparea = 0;
if ((loopType = pHatch->loopTypeAt(i)) & AcDbHatch::kPolyline) {
AcGePoint2dArray vertices;
AcGeDoubleArray bulges;
if (pHatch->getLoopAt(i, loopType, vertices, bulges) == Acad::eOk) {
AcDbPolyline *pPoly = new AcDbPolyline(vertices.length());
for (int j = 0; j < vertices.length(); j++) {
pPoly->addVertexAt(j, vertices[j], (bulges.length() < vertices.length()) ? 0.0 : bulges[j]);
}
pPoly->setClosed(!(loopType & AcDbHatch::kNotClosed));
pPoly->getArea(looparea);
if (loopType & AcDbHatch::kExternal) area += fabs(looparea); else area -= fabs(looparea);
delete pPoly;
}
}
else {
AcGeVoidPointerArray edgePtrs;
AcGeIntArray edgeTypes;
pHatch->getLoopAt(i, loopType, edgePtrs, edgeTypes);
AcGeCompositeCurve2d compCurve(edgePtrs);
AcGeInterval interval; compCurve.getInterval(interval);
double pmin, pmax; interval.getBounds(pmin, pmax);
if (fabs(pmax - pmin) > 1e-6) {
if (compCurve.area(interval.lowerBound(), interval.upperBound(), looparea)) {
if (loopType & AcDbHatch::kExternal) area += fabs(looparea); else area -= fabs(looparea);
}
else {
AcGePoint2dArray pts; AcGeDoubleArray pars;
AcGePoint2d pmin, pmax;
AcGeBoundBlock2d blk2d = compCurve.boundBlock(interval);
blk2d.getMinMaxPoints(pmin, pmax);
double diag = pmin.distanceTo(pmax);
compCurve.getSamplePoints(interval.lowerBound(), interval.upperBound(), 1e-6 * max(1.0, diag), pts, pars);
int np = pts.length();
for (int i = 0; i < np; i++) {
looparea += 0.5 * pts[i][X] * (pts[(i + 1) % np][Y] - pts[(i + np - 1) % np][Y]);
}
if (loopType & AcDbHatch::kExternal) area += fabs(looparea); else area -= fabs(looparea);
}
}
}
}
return fabs(area);
}